diff options
281 files changed, 10002 insertions, 1579 deletions
diff --git a/.gitignore b/.gitignore index b93fb7eff942..946c7ec5c922 100644 --- a/.gitignore +++ b/.gitignore | |||
@@ -25,6 +25,7 @@ | |||
25 | *.elf | 25 | *.elf |
26 | *.bin | 26 | *.bin |
27 | *.gz | 27 | *.gz |
28 | *.bz2 | ||
28 | *.lzma | 29 | *.lzma |
29 | *.patch | 30 | *.patch |
30 | *.gcno | 31 | *.gcno |
diff --git a/Documentation/fb/framebuffer.txt b/Documentation/fb/framebuffer.txt index b3e3a0356839..fe79e3c8847d 100644 --- a/Documentation/fb/framebuffer.txt +++ b/Documentation/fb/framebuffer.txt | |||
@@ -312,10 +312,8 @@ and to the following documentation: | |||
312 | 8. Mailing list | 312 | 8. Mailing list |
313 | --------------- | 313 | --------------- |
314 | 314 | ||
315 | There are several frame buffer device related mailing lists at SourceForge: | 315 | There is a frame buffer device related mailing list at kernel.org: |
316 | - linux-fbdev-announce@lists.sourceforge.net, for announcements, | 316 | linux-fbdev@vger.kernel.org. |
317 | - linux-fbdev-user@lists.sourceforge.net, for generic user support, | ||
318 | - linux-fbdev-devel@lists.sourceforge.net, for project developers. | ||
319 | 317 | ||
320 | Point your web browser to http://sourceforge.net/projects/linux-fbdev/ for | 318 | Point your web browser to http://sourceforge.net/projects/linux-fbdev/ for |
321 | subscription information and archive browsing. | 319 | subscription information and archive browsing. |
diff --git a/Documentation/filesystems/caching/fscache.txt b/Documentation/filesystems/caching/fscache.txt index 9e94b9491d89..a91e2e2095b0 100644 --- a/Documentation/filesystems/caching/fscache.txt +++ b/Documentation/filesystems/caching/fscache.txt | |||
@@ -235,6 +235,7 @@ proc files. | |||
235 | neg=N Number of negative lookups made | 235 | neg=N Number of negative lookups made |
236 | pos=N Number of positive lookups made | 236 | pos=N Number of positive lookups made |
237 | crt=N Number of objects created by lookup | 237 | crt=N Number of objects created by lookup |
238 | tmo=N Number of lookups timed out and requeued | ||
238 | Updates n=N Number of update cookie requests seen | 239 | Updates n=N Number of update cookie requests seen |
239 | nul=N Number of upd reqs given a NULL parent | 240 | nul=N Number of upd reqs given a NULL parent |
240 | run=N Number of upd reqs granted CPU time | 241 | run=N Number of upd reqs granted CPU time |
@@ -250,8 +251,10 @@ proc files. | |||
250 | ok=N Number of successful alloc reqs | 251 | ok=N Number of successful alloc reqs |
251 | wt=N Number of alloc reqs that waited on lookup completion | 252 | wt=N Number of alloc reqs that waited on lookup completion |
252 | nbf=N Number of alloc reqs rejected -ENOBUFS | 253 | nbf=N Number of alloc reqs rejected -ENOBUFS |
254 | int=N Number of alloc reqs aborted -ERESTARTSYS | ||
253 | ops=N Number of alloc reqs submitted | 255 | ops=N Number of alloc reqs submitted |
254 | owt=N Number of alloc reqs waited for CPU time | 256 | owt=N Number of alloc reqs waited for CPU time |
257 | abt=N Number of alloc reqs aborted due to object death | ||
255 | Retrvls n=N Number of retrieval (read) requests seen | 258 | Retrvls n=N Number of retrieval (read) requests seen |
256 | ok=N Number of successful retr reqs | 259 | ok=N Number of successful retr reqs |
257 | wt=N Number of retr reqs that waited on lookup completion | 260 | wt=N Number of retr reqs that waited on lookup completion |
@@ -261,6 +264,7 @@ proc files. | |||
261 | oom=N Number of retr reqs failed -ENOMEM | 264 | oom=N Number of retr reqs failed -ENOMEM |
262 | ops=N Number of retr reqs submitted | 265 | ops=N Number of retr reqs submitted |
263 | owt=N Number of retr reqs waited for CPU time | 266 | owt=N Number of retr reqs waited for CPU time |
267 | abt=N Number of retr reqs aborted due to object death | ||
264 | Stores n=N Number of storage (write) requests seen | 268 | Stores n=N Number of storage (write) requests seen |
265 | ok=N Number of successful store reqs | 269 | ok=N Number of successful store reqs |
266 | agn=N Number of store reqs on a page already pending storage | 270 | agn=N Number of store reqs on a page already pending storage |
@@ -268,12 +272,37 @@ proc files. | |||
268 | oom=N Number of store reqs failed -ENOMEM | 272 | oom=N Number of store reqs failed -ENOMEM |
269 | ops=N Number of store reqs submitted | 273 | ops=N Number of store reqs submitted |
270 | run=N Number of store reqs granted CPU time | 274 | run=N Number of store reqs granted CPU time |
275 | pgs=N Number of pages given store req processing time | ||
276 | rxd=N Number of store reqs deleted from tracking tree | ||
277 | olm=N Number of store reqs over store limit | ||
278 | VmScan nos=N Number of release reqs against pages with no pending store | ||
279 | gon=N Number of release reqs against pages stored by time lock granted | ||
280 | bsy=N Number of release reqs ignored due to in-progress store | ||
281 | can=N Number of page stores cancelled due to release req | ||
271 | Ops pend=N Number of times async ops added to pending queues | 282 | Ops pend=N Number of times async ops added to pending queues |
272 | run=N Number of times async ops given CPU time | 283 | run=N Number of times async ops given CPU time |
273 | enq=N Number of times async ops queued for processing | 284 | enq=N Number of times async ops queued for processing |
285 | can=N Number of async ops cancelled | ||
286 | rej=N Number of async ops rejected due to object lookup/create failure | ||
274 | dfr=N Number of async ops queued for deferred release | 287 | dfr=N Number of async ops queued for deferred release |
275 | rel=N Number of async ops released | 288 | rel=N Number of async ops released |
276 | gc=N Number of deferred-release async ops garbage collected | 289 | gc=N Number of deferred-release async ops garbage collected |
290 | CacheOp alo=N Number of in-progress alloc_object() cache ops | ||
291 | luo=N Number of in-progress lookup_object() cache ops | ||
292 | luc=N Number of in-progress lookup_complete() cache ops | ||
293 | gro=N Number of in-progress grab_object() cache ops | ||
294 | upo=N Number of in-progress update_object() cache ops | ||
295 | dro=N Number of in-progress drop_object() cache ops | ||
296 | pto=N Number of in-progress put_object() cache ops | ||
297 | syn=N Number of in-progress sync_cache() cache ops | ||
298 | atc=N Number of in-progress attr_changed() cache ops | ||
299 | rap=N Number of in-progress read_or_alloc_page() cache ops | ||
300 | ras=N Number of in-progress read_or_alloc_pages() cache ops | ||
301 | alp=N Number of in-progress allocate_page() cache ops | ||
302 | als=N Number of in-progress allocate_pages() cache ops | ||
303 | wrp=N Number of in-progress write_page() cache ops | ||
304 | ucp=N Number of in-progress uncache_page() cache ops | ||
305 | dsp=N Number of in-progress dissociate_pages() cache ops | ||
277 | 306 | ||
278 | 307 | ||
279 | (*) /proc/fs/fscache/histogram | 308 | (*) /proc/fs/fscache/histogram |
@@ -299,6 +328,87 @@ proc files. | |||
299 | jiffy range covered, and the SECS field the equivalent number of seconds. | 328 | jiffy range covered, and the SECS field the equivalent number of seconds. |
300 | 329 | ||
301 | 330 | ||
331 | =========== | ||
332 | OBJECT LIST | ||
333 | =========== | ||
334 | |||
335 | If CONFIG_FSCACHE_OBJECT_LIST is enabled, the FS-Cache facility will maintain a | ||
336 | list of all the objects currently allocated and allow them to be viewed | ||
337 | through: | ||
338 | |||
339 | /proc/fs/fscache/objects | ||
340 | |||
341 | This will look something like: | ||
342 | |||
343 | [root@andromeda ~]# head /proc/fs/fscache/objects | ||
344 | OBJECT PARENT STAT CHLDN OPS OOP IPR EX READS EM EV F S | NETFS_COOKIE_DEF TY FL NETFS_DATA OBJECT_KEY, AUX_DATA | ||
345 | ======== ======== ==== ===== === === === == ===== == == = = | ================ == == ================ ================ | ||
346 | 17e4b 2 ACTV 0 0 0 0 0 0 7b 4 0 8 | NFS.fh DT 0 ffff88001dd82820 010006017edcf8bbc93b43298fdfbe71e50b57b13a172c0117f38472, e567634700000000000000000000000063f2404a000000000000000000000000c9030000000000000000000063f2404a | ||
347 | 1693a 2 ACTV 0 0 0 0 0 0 7b 4 0 8 | NFS.fh DT 0 ffff88002db23380 010006017edcf8bbc93b43298fdfbe71e50b57b1e0162c01a2df0ea6, 420ebc4a000000000000000000000000420ebc4a0000000000000000000000000e1801000000000000000000420ebc4a | ||
348 | |||
349 | where the first set of columns before the '|' describe the object: | ||
350 | |||
351 | COLUMN DESCRIPTION | ||
352 | ======= =============================================================== | ||
353 | OBJECT Object debugging ID (appears as OBJ%x in some debug messages) | ||
354 | PARENT Debugging ID of parent object | ||
355 | STAT Object state | ||
356 | CHLDN Number of child objects of this object | ||
357 | OPS Number of outstanding operations on this object | ||
358 | OOP Number of outstanding child object management operations | ||
359 | IPR | ||
360 | EX Number of outstanding exclusive operations | ||
361 | READS Number of outstanding read operations | ||
362 | EM Object's event mask | ||
363 | EV Events raised on this object | ||
364 | F Object flags | ||
365 | S Object slow-work work item flags | ||
366 | |||
367 | and the second set of columns describe the object's cookie, if present: | ||
368 | |||
369 | COLUMN DESCRIPTION | ||
370 | =============== ======================================================= | ||
371 | NETFS_COOKIE_DEF Name of netfs cookie definition | ||
372 | TY Cookie type (IX - index, DT - data, hex - special) | ||
373 | FL Cookie flags | ||
374 | NETFS_DATA Netfs private data stored in the cookie | ||
375 | OBJECT_KEY Object key } 1 column, with separating comma | ||
376 | AUX_DATA Object aux data } presence may be configured | ||
377 | |||
378 | The data shown may be filtered by attaching the a key to an appropriate keyring | ||
379 | before viewing the file. Something like: | ||
380 | |||
381 | keyctl add user fscache:objlist <restrictions> @s | ||
382 | |||
383 | where <restrictions> are a selection of the following letters: | ||
384 | |||
385 | K Show hexdump of object key (don't show if not given) | ||
386 | A Show hexdump of object aux data (don't show if not given) | ||
387 | |||
388 | and the following paired letters: | ||
389 | |||
390 | C Show objects that have a cookie | ||
391 | c Show objects that don't have a cookie | ||
392 | B Show objects that are busy | ||
393 | b Show objects that aren't busy | ||
394 | W Show objects that have pending writes | ||
395 | w Show objects that don't have pending writes | ||
396 | R Show objects that have outstanding reads | ||
397 | r Show objects that don't have outstanding reads | ||
398 | S Show objects that have slow work queued | ||
399 | s Show objects that don't have slow work queued | ||
400 | |||
401 | If neither side of a letter pair is given, then both are implied. For example: | ||
402 | |||
403 | keyctl add user fscache:objlist KB @s | ||
404 | |||
405 | shows objects that are busy, and lists their object keys, but does not dump | ||
406 | their auxiliary data. It also implies "CcWwRrSs", but as 'B' is given, 'b' is | ||
407 | not implied. | ||
408 | |||
409 | By default all objects and all fields will be shown. | ||
410 | |||
411 | |||
302 | ========= | 412 | ========= |
303 | DEBUGGING | 413 | DEBUGGING |
304 | ========= | 414 | ========= |
diff --git a/Documentation/filesystems/caching/netfs-api.txt b/Documentation/filesystems/caching/netfs-api.txt index 2666b1ed5e9e..1902c57b72ef 100644 --- a/Documentation/filesystems/caching/netfs-api.txt +++ b/Documentation/filesystems/caching/netfs-api.txt | |||
@@ -641,7 +641,7 @@ data file must be retired (see the relinquish cookie function below). | |||
641 | 641 | ||
642 | Furthermore, note that this does not cancel the asynchronous read or write | 642 | Furthermore, note that this does not cancel the asynchronous read or write |
643 | operation started by the read/alloc and write functions, so the page | 643 | operation started by the read/alloc and write functions, so the page |
644 | invalidation and release functions must use: | 644 | invalidation functions must use: |
645 | 645 | ||
646 | bool fscache_check_page_write(struct fscache_cookie *cookie, | 646 | bool fscache_check_page_write(struct fscache_cookie *cookie, |
647 | struct page *page); | 647 | struct page *page); |
@@ -654,6 +654,25 @@ to see if a page is being written to the cache, and: | |||
654 | to wait for it to finish if it is. | 654 | to wait for it to finish if it is. |
655 | 655 | ||
656 | 656 | ||
657 | When releasepage() is being implemented, a special FS-Cache function exists to | ||
658 | manage the heuristics of coping with vmscan trying to eject pages, which may | ||
659 | conflict with the cache trying to write pages to the cache (which may itself | ||
660 | need to allocate memory): | ||
661 | |||
662 | bool fscache_maybe_release_page(struct fscache_cookie *cookie, | ||
663 | struct page *page, | ||
664 | gfp_t gfp); | ||
665 | |||
666 | This takes the netfs cookie, and the page and gfp arguments as supplied to | ||
667 | releasepage(). It will return false if the page cannot be released yet for | ||
668 | some reason and if it returns true, the page has been uncached and can now be | ||
669 | released. | ||
670 | |||
671 | To make a page available for release, this function may wait for an outstanding | ||
672 | storage request to complete, or it may attempt to cancel the storage request - | ||
673 | in which case the page will not be stored in the cache this time. | ||
674 | |||
675 | |||
657 | ========================== | 676 | ========================== |
658 | INDEX AND DATA FILE UPDATE | 677 | INDEX AND DATA FILE UPDATE |
659 | ========================== | 678 | ========================== |
diff --git a/Documentation/slow-work.txt b/Documentation/slow-work.txt index ebc50f808ea4..52bc31433723 100644 --- a/Documentation/slow-work.txt +++ b/Documentation/slow-work.txt | |||
@@ -41,6 +41,13 @@ expand files, provided the time taken to do so isn't too long. | |||
41 | Operations of both types may sleep during execution, thus tying up the thread | 41 | Operations of both types may sleep during execution, thus tying up the thread |
42 | loaned to it. | 42 | loaned to it. |
43 | 43 | ||
44 | A further class of work item is available, based on the slow work item class: | ||
45 | |||
46 | (*) Delayed slow work items. | ||
47 | |||
48 | These are slow work items that have a timer to defer queueing of the item for | ||
49 | a while. | ||
50 | |||
44 | 51 | ||
45 | THREAD-TO-CLASS ALLOCATION | 52 | THREAD-TO-CLASS ALLOCATION |
46 | -------------------------- | 53 | -------------------------- |
@@ -64,9 +71,11 @@ USING SLOW WORK ITEMS | |||
64 | Firstly, a module or subsystem wanting to make use of slow work items must | 71 | Firstly, a module or subsystem wanting to make use of slow work items must |
65 | register its interest: | 72 | register its interest: |
66 | 73 | ||
67 | int ret = slow_work_register_user(); | 74 | int ret = slow_work_register_user(struct module *module); |
68 | 75 | ||
69 | This will return 0 if successful, or a -ve error upon failure. | 76 | This will return 0 if successful, or a -ve error upon failure. The module |
77 | pointer should be the module interested in using this facility (almost | ||
78 | certainly THIS_MODULE). | ||
70 | 79 | ||
71 | 80 | ||
72 | Slow work items may then be set up by: | 81 | Slow work items may then be set up by: |
@@ -93,6 +102,10 @@ Slow work items may then be set up by: | |||
93 | 102 | ||
94 | or: | 103 | or: |
95 | 104 | ||
105 | delayed_slow_work_init(&myitem, &myitem_ops); | ||
106 | |||
107 | or: | ||
108 | |||
96 | vslow_work_init(&myitem, &myitem_ops); | 109 | vslow_work_init(&myitem, &myitem_ops); |
97 | 110 | ||
98 | depending on its class. | 111 | depending on its class. |
@@ -102,15 +115,92 @@ A suitably set up work item can then be enqueued for processing: | |||
102 | int ret = slow_work_enqueue(&myitem); | 115 | int ret = slow_work_enqueue(&myitem); |
103 | 116 | ||
104 | This will return a -ve error if the thread pool is unable to gain a reference | 117 | This will return a -ve error if the thread pool is unable to gain a reference |
105 | on the item, 0 otherwise. | 118 | on the item, 0 otherwise, or (for delayed work): |
119 | |||
120 | int ret = delayed_slow_work_enqueue(&myitem, my_jiffy_delay); | ||
106 | 121 | ||
107 | 122 | ||
108 | The items are reference counted, so there ought to be no need for a flush | 123 | The items are reference counted, so there ought to be no need for a flush |
109 | operation. When all a module's slow work items have been processed, and the | 124 | operation. But as the reference counting is optional, means to cancel |
125 | existing work items are also included: | ||
126 | |||
127 | cancel_slow_work(&myitem); | ||
128 | cancel_delayed_slow_work(&myitem); | ||
129 | |||
130 | can be used to cancel pending work. The above cancel function waits for | ||
131 | existing work to have been executed (or prevent execution of them, depending | ||
132 | on timing). | ||
133 | |||
134 | |||
135 | When all a module's slow work items have been processed, and the | ||
110 | module has no further interest in the facility, it should unregister its | 136 | module has no further interest in the facility, it should unregister its |
111 | interest: | 137 | interest: |
112 | 138 | ||
113 | slow_work_unregister_user(); | 139 | slow_work_unregister_user(struct module *module); |
140 | |||
141 | The module pointer is used to wait for all outstanding work items for that | ||
142 | module before completing the unregistration. This prevents the put_ref() code | ||
143 | from being taken away before it completes. module should almost certainly be | ||
144 | THIS_MODULE. | ||
145 | |||
146 | |||
147 | ================ | ||
148 | HELPER FUNCTIONS | ||
149 | ================ | ||
150 | |||
151 | The slow-work facility provides a function by which it can be determined | ||
152 | whether or not an item is queued for later execution: | ||
153 | |||
154 | bool queued = slow_work_is_queued(struct slow_work *work); | ||
155 | |||
156 | If it returns false, then the item is not on the queue (it may be executing | ||
157 | with a requeue pending). This can be used to work out whether an item on which | ||
158 | another depends is on the queue, thus allowing a dependent item to be queued | ||
159 | after it. | ||
160 | |||
161 | If the above shows an item on which another depends not to be queued, then the | ||
162 | owner of the dependent item might need to wait. However, to avoid locking up | ||
163 | the threads unnecessarily be sleeping in them, it can make sense under some | ||
164 | circumstances to return the work item to the queue, thus deferring it until | ||
165 | some other items have had a chance to make use of the yielded thread. | ||
166 | |||
167 | To yield a thread and defer an item, the work function should simply enqueue | ||
168 | the work item again and return. However, this doesn't work if there's nothing | ||
169 | actually on the queue, as the thread just vacated will jump straight back into | ||
170 | the item's work function, thus busy waiting on a CPU. | ||
171 | |||
172 | Instead, the item should use the thread to wait for the dependency to go away, | ||
173 | but rather than using schedule() or schedule_timeout() to sleep, it should use | ||
174 | the following function: | ||
175 | |||
176 | bool requeue = slow_work_sleep_till_thread_needed( | ||
177 | struct slow_work *work, | ||
178 | signed long *_timeout); | ||
179 | |||
180 | This will add a second wait and then sleep, such that it will be woken up if | ||
181 | either something appears on the queue that could usefully make use of the | ||
182 | thread - and behind which this item can be queued, or if the event the caller | ||
183 | set up to wait for happens. True will be returned if something else appeared | ||
184 | on the queue and this work function should perhaps return, of false if | ||
185 | something else woke it up. The timeout is as for schedule_timeout(). | ||
186 | |||
187 | For example: | ||
188 | |||
189 | wq = bit_waitqueue(&my_flags, MY_BIT); | ||
190 | init_wait(&wait); | ||
191 | requeue = false; | ||
192 | do { | ||
193 | prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE); | ||
194 | if (!test_bit(MY_BIT, &my_flags)) | ||
195 | break; | ||
196 | requeue = slow_work_sleep_till_thread_needed(&my_work, | ||
197 | &timeout); | ||
198 | } while (timeout > 0 && !requeue); | ||
199 | finish_wait(wq, &wait); | ||
200 | if (!test_bit(MY_BIT, &my_flags) | ||
201 | goto do_my_thing; | ||
202 | if (requeue) | ||
203 | return; // to slow_work | ||
114 | 204 | ||
115 | 205 | ||
116 | =============== | 206 | =============== |
@@ -118,7 +208,8 @@ ITEM OPERATIONS | |||
118 | =============== | 208 | =============== |
119 | 209 | ||
120 | Each work item requires a table of operations of type struct slow_work_ops. | 210 | Each work item requires a table of operations of type struct slow_work_ops. |
121 | All members are required: | 211 | Only ->execute() is required; the getting and putting of a reference and the |
212 | describing of an item are all optional. | ||
122 | 213 | ||
123 | (*) Get a reference on an item: | 214 | (*) Get a reference on an item: |
124 | 215 | ||
@@ -148,6 +239,16 @@ All members are required: | |||
148 | This should perform the work required of the item. It may sleep, it may | 239 | This should perform the work required of the item. It may sleep, it may |
149 | perform disk I/O and it may wait for locks. | 240 | perform disk I/O and it may wait for locks. |
150 | 241 | ||
242 | (*) View an item through /proc: | ||
243 | |||
244 | void (*desc)(struct slow_work *work, struct seq_file *m); | ||
245 | |||
246 | If supplied, this should print to 'm' a small string describing the work | ||
247 | the item is to do. This should be no more than about 40 characters, and | ||
248 | shouldn't include a newline character. | ||
249 | |||
250 | See the 'Viewing executing and queued items' section below. | ||
251 | |||
151 | 252 | ||
152 | ================== | 253 | ================== |
153 | POOL CONFIGURATION | 254 | POOL CONFIGURATION |
@@ -172,3 +273,50 @@ The slow-work thread pool has a number of configurables: | |||
172 | is bounded to between 1 and one fewer than the number of active threads. | 273 | is bounded to between 1 and one fewer than the number of active threads. |
173 | This ensures there is always at least one thread that can process very | 274 | This ensures there is always at least one thread that can process very |
174 | slow work items, and always at least one thread that won't. | 275 | slow work items, and always at least one thread that won't. |
276 | |||
277 | |||
278 | ================================== | ||
279 | VIEWING EXECUTING AND QUEUED ITEMS | ||
280 | ================================== | ||
281 | |||
282 | If CONFIG_SLOW_WORK_PROC is enabled, a proc file is made available: | ||
283 | |||
284 | /proc/slow_work_rq | ||
285 | |||
286 | through which the list of work items being executed and the queues of items to | ||
287 | be executed may be viewed. The owner of a work item is given the chance to | ||
288 | add some information of its own. | ||
289 | |||
290 | The contents look something like the following: | ||
291 | |||
292 | THR PID ITEM ADDR FL MARK DESC | ||
293 | === ===== ================ == ===== ========== | ||
294 | 0 3005 ffff880023f52348 a 952ms FSC: OBJ17d3: LOOK | ||
295 | 1 3006 ffff880024e33668 2 160ms FSC: OBJ17e5 OP60d3b: Write1/Store fl=2 | ||
296 | 2 3165 ffff8800296dd180 a 424ms FSC: OBJ17e4: LOOK | ||
297 | 3 4089 ffff8800262c8d78 a 212ms FSC: OBJ17ea: CRTN | ||
298 | 4 4090 ffff88002792bed8 2 388ms FSC: OBJ17e8 OP60d36: Write1/Store fl=2 | ||
299 | 5 4092 ffff88002a0ef308 2 388ms FSC: OBJ17e7 OP60d2e: Write1/Store fl=2 | ||
300 | 6 4094 ffff88002abaf4b8 2 132ms FSC: OBJ17e2 OP60d4e: Write1/Store fl=2 | ||
301 | 7 4095 ffff88002bb188e0 a 388ms FSC: OBJ17e9: CRTN | ||
302 | vsq - ffff880023d99668 1 308ms FSC: OBJ17e0 OP60f91: Write1/EnQ fl=2 | ||
303 | vsq - ffff8800295d1740 1 212ms FSC: OBJ16be OP4d4b6: Write1/EnQ fl=2 | ||
304 | vsq - ffff880025ba3308 1 160ms FSC: OBJ179a OP58dec: Write1/EnQ fl=2 | ||
305 | vsq - ffff880024ec83e0 1 160ms FSC: OBJ17ae OP599f2: Write1/EnQ fl=2 | ||
306 | vsq - ffff880026618e00 1 160ms FSC: OBJ17e6 OP60d33: Write1/EnQ fl=2 | ||
307 | vsq - ffff880025a2a4b8 1 132ms FSC: OBJ16a2 OP4d583: Write1/EnQ fl=2 | ||
308 | vsq - ffff880023cbe6d8 9 212ms FSC: OBJ17eb: LOOK | ||
309 | vsq - ffff880024d37590 9 212ms FSC: OBJ17ec: LOOK | ||
310 | vsq - ffff880027746cb0 9 212ms FSC: OBJ17ed: LOOK | ||
311 | vsq - ffff880024d37ae8 9 212ms FSC: OBJ17ee: LOOK | ||
312 | vsq - ffff880024d37cb0 9 212ms FSC: OBJ17ef: LOOK | ||
313 | vsq - ffff880025036550 9 212ms FSC: OBJ17f0: LOOK | ||
314 | vsq - ffff8800250368e0 9 212ms FSC: OBJ17f1: LOOK | ||
315 | vsq - ffff880025036aa8 9 212ms FSC: OBJ17f2: LOOK | ||
316 | |||
317 | In the 'THR' column, executing items show the thread they're occupying and | ||
318 | queued threads indicate which queue they're on. 'PID' shows the process ID of | ||
319 | a slow-work thread that's executing something. 'FL' shows the work item flags. | ||
320 | 'MARK' indicates how long since an item was queued or began executing. Lastly, | ||
321 | the 'DESC' column permits the owner of an item to give some information. | ||
322 | |||
diff --git a/MAINTAINERS b/MAINTAINERS index d13e2e33d40e..ad59f178586f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -512,10 +512,32 @@ W: http://www.arm.linux.org.uk/ | |||
512 | S: Maintained | 512 | S: Maintained |
513 | F: arch/arm/ | 513 | F: arch/arm/ |
514 | 514 | ||
515 | ARM PRIMECELL AACI PL041 DRIVER | ||
516 | M: Russell King <linux@arm.linux.org.uk> | ||
517 | S: Maintained | ||
518 | F: sound/arm/aaci.* | ||
519 | |||
520 | ARM PRIMECELL CLCD PL110 DRIVER | ||
521 | M: Russell King <linux@arm.linux.org.uk> | ||
522 | S: Maintained | ||
523 | F: drivers/video/amba-clcd.* | ||
524 | |||
525 | ARM PRIMECELL KMI PL050 DRIVER | ||
526 | M: Russell King <linux@arm.linux.org.uk> | ||
527 | S: Maintained | ||
528 | F: drivers/input/serio/ambakmi.* | ||
529 | F: include/linux/amba/kmi.h | ||
530 | |||
515 | ARM PRIMECELL MMCI PL180/1 DRIVER | 531 | ARM PRIMECELL MMCI PL180/1 DRIVER |
516 | S: Orphan | 532 | S: Orphan |
517 | F: drivers/mmc/host/mmci.* | 533 | F: drivers/mmc/host/mmci.* |
518 | 534 | ||
535 | ARM PRIMECELL BUS SUPPORT | ||
536 | M: Russell King <linux@arm.linux.org.uk> | ||
537 | S: Maintained | ||
538 | F: drivers/amba/ | ||
539 | F: include/linux/amba/bus.h | ||
540 | |||
519 | ARM/ADI ROADRUNNER MACHINE SUPPORT | 541 | ARM/ADI ROADRUNNER MACHINE SUPPORT |
520 | M: Lennert Buytenhek <kernel@wantstofly.org> | 542 | M: Lennert Buytenhek <kernel@wantstofly.org> |
521 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 543 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
@@ -765,6 +787,14 @@ ARM/NEC MOBILEPRO 900/c MACHINE SUPPORT | |||
765 | M: Michael Petchkovsky <mkpetch@internode.on.net> | 787 | M: Michael Petchkovsky <mkpetch@internode.on.net> |
766 | S: Maintained | 788 | S: Maintained |
767 | 789 | ||
790 | ARM/NOMADIK ARCHITECTURE | ||
791 | M: Alessandro Rubini <rubini@unipv.it> | ||
792 | M: STEricsson <STEricsson_nomadik_linux@list.st.com> | ||
793 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||
794 | S: Maintained | ||
795 | F: arch/arm/mach-nomadik/ | ||
796 | F: arch/arm/plat-nomadik/ | ||
797 | |||
768 | ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT | 798 | ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT |
769 | M: Nelson Castillo <arhuaco@freaks-unidos.net> | 799 | M: Nelson Castillo <arhuaco@freaks-unidos.net> |
770 | L: openmoko-kernel@lists.openmoko.org (subscribers-only) | 800 | L: openmoko-kernel@lists.openmoko.org (subscribers-only) |
@@ -909,6 +939,12 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | |||
909 | W: http://www.mcuos.com | 939 | W: http://www.mcuos.com |
910 | S: Maintained | 940 | S: Maintained |
911 | 941 | ||
942 | ARM/U8500 ARM ARCHITECTURE | ||
943 | M: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> | ||
944 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||
945 | S: Maintained | ||
946 | F: arch/arm/mach-ux500/ | ||
947 | |||
912 | ARM/VFP SUPPORT | 948 | ARM/VFP SUPPORT |
913 | M: Russell King <linux@arm.linux.org.uk> | 949 | M: Russell King <linux@arm.linux.org.uk> |
914 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 950 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
@@ -1043,7 +1079,7 @@ F: drivers/serial/atmel_serial.c | |||
1043 | 1079 | ||
1044 | ATMEL LCDFB DRIVER | 1080 | ATMEL LCDFB DRIVER |
1045 | M: Nicolas Ferre <nicolas.ferre@atmel.com> | 1081 | M: Nicolas Ferre <nicolas.ferre@atmel.com> |
1046 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 1082 | L: linux-fbdev@vger.kernel.org |
1047 | S: Maintained | 1083 | S: Maintained |
1048 | F: drivers/video/atmel_lcdfb.c | 1084 | F: drivers/video/atmel_lcdfb.c |
1049 | F: include/video/atmel_lcdc.h | 1085 | F: include/video/atmel_lcdc.h |
@@ -2129,7 +2165,7 @@ F: drivers/net/wan/dlci.c | |||
2129 | F: drivers/net/wan/sdla.c | 2165 | F: drivers/net/wan/sdla.c |
2130 | 2166 | ||
2131 | FRAMEBUFFER LAYER | 2167 | FRAMEBUFFER LAYER |
2132 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 2168 | L: linux-fbdev@vger.kernel.org |
2133 | W: http://linux-fbdev.sourceforge.net/ | 2169 | W: http://linux-fbdev.sourceforge.net/ |
2134 | S: Orphan | 2170 | S: Orphan |
2135 | F: Documentation/fb/ | 2171 | F: Documentation/fb/ |
@@ -2152,7 +2188,7 @@ F: drivers/i2c/busses/i2c-cpm.c | |||
2152 | 2188 | ||
2153 | FREESCALE IMX / MXC FRAMEBUFFER DRIVER | 2189 | FREESCALE IMX / MXC FRAMEBUFFER DRIVER |
2154 | M: Sascha Hauer <kernel@pengutronix.de> | 2190 | M: Sascha Hauer <kernel@pengutronix.de> |
2155 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 2191 | L: linux-fbdev@vger.kernel.org |
2156 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 2192 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
2157 | S: Maintained | 2193 | S: Maintained |
2158 | F: arch/arm/plat-mxc/include/mach/imxfb.h | 2194 | F: arch/arm/plat-mxc/include/mach/imxfb.h |
@@ -2328,6 +2364,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | |||
2328 | S: Maintained | 2364 | S: Maintained |
2329 | F: drivers/media/video/gspca/finepix.c | 2365 | F: drivers/media/video/gspca/finepix.c |
2330 | 2366 | ||
2367 | GSPCA GL860 SUBDRIVER | ||
2368 | M: Olivier Lorin <o.lorin@laposte.net> | ||
2369 | L: linux-media@vger.kernel.org | ||
2370 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | ||
2371 | S: Maintained | ||
2372 | F: drivers/media/video/gspca/gl860/ | ||
2373 | |||
2331 | GSPCA M5602 SUBDRIVER | 2374 | GSPCA M5602 SUBDRIVER |
2332 | M: Erik Andren <erik.andren@gmail.com> | 2375 | M: Erik Andren <erik.andren@gmail.com> |
2333 | L: linux-media@vger.kernel.org | 2376 | L: linux-media@vger.kernel.org |
@@ -2549,8 +2592,7 @@ S: Maintained | |||
2549 | F: Documentation/i2c/ | 2592 | F: Documentation/i2c/ |
2550 | F: drivers/i2c/ | 2593 | F: drivers/i2c/ |
2551 | F: include/linux/i2c.h | 2594 | F: include/linux/i2c.h |
2552 | F: include/linux/i2c-dev.h | 2595 | F: include/linux/i2c-*.h |
2553 | F: include/linux/i2c-id.h | ||
2554 | 2596 | ||
2555 | I2C-TINY-USB DRIVER | 2597 | I2C-TINY-USB DRIVER |
2556 | M: Till Harbaum <till@harbaum.org> | 2598 | M: Till Harbaum <till@harbaum.org> |
@@ -2651,7 +2693,7 @@ S: Supported | |||
2651 | F: security/integrity/ima/ | 2693 | F: security/integrity/ima/ |
2652 | 2694 | ||
2653 | IMS TWINTURBO FRAMEBUFFER DRIVER | 2695 | IMS TWINTURBO FRAMEBUFFER DRIVER |
2654 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 2696 | L: linux-fbdev@vger.kernel.org |
2655 | S: Orphan | 2697 | S: Orphan |
2656 | F: drivers/video/imsttfb.c | 2698 | F: drivers/video/imsttfb.c |
2657 | 2699 | ||
@@ -2686,14 +2728,14 @@ F: drivers/input/ | |||
2686 | 2728 | ||
2687 | INTEL FRAMEBUFFER DRIVER (excluding 810 and 815) | 2729 | INTEL FRAMEBUFFER DRIVER (excluding 810 and 815) |
2688 | M: Sylvain Meyer <sylvain.meyer@worldonline.fr> | 2730 | M: Sylvain Meyer <sylvain.meyer@worldonline.fr> |
2689 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 2731 | L: linux-fbdev@vger.kernel.org |
2690 | S: Maintained | 2732 | S: Maintained |
2691 | F: Documentation/fb/intelfb.txt | 2733 | F: Documentation/fb/intelfb.txt |
2692 | F: drivers/video/intelfb/ | 2734 | F: drivers/video/intelfb/ |
2693 | 2735 | ||
2694 | INTEL 810/815 FRAMEBUFFER DRIVER | 2736 | INTEL 810/815 FRAMEBUFFER DRIVER |
2695 | M: Antonino Daplas <adaplas@gmail.com> | 2737 | M: Antonino Daplas <adaplas@gmail.com> |
2696 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 2738 | L: linux-fbdev@vger.kernel.org |
2697 | S: Maintained | 2739 | S: Maintained |
2698 | F: drivers/video/i810/ | 2740 | F: drivers/video/i810/ |
2699 | 2741 | ||
@@ -3407,7 +3449,7 @@ S: Supported | |||
3407 | 3449 | ||
3408 | MATROX FRAMEBUFFER DRIVER | 3450 | MATROX FRAMEBUFFER DRIVER |
3409 | M: Petr Vandrovec <vandrove@vc.cvut.cz> | 3451 | M: Petr Vandrovec <vandrove@vc.cvut.cz> |
3410 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 3452 | L: linux-fbdev@vger.kernel.org |
3411 | S: Maintained | 3453 | S: Maintained |
3412 | F: drivers/video/matrox/matroxfb_* | 3454 | F: drivers/video/matrox/matroxfb_* |
3413 | F: include/linux/matroxfb.h | 3455 | F: include/linux/matroxfb.h |
@@ -3794,7 +3836,7 @@ F: fs/ntfs/ | |||
3794 | 3836 | ||
3795 | NVIDIA (rivafb and nvidiafb) FRAMEBUFFER DRIVER | 3837 | NVIDIA (rivafb and nvidiafb) FRAMEBUFFER DRIVER |
3796 | M: Antonino Daplas <adaplas@gmail.com> | 3838 | M: Antonino Daplas <adaplas@gmail.com> |
3797 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 3839 | L: linux-fbdev@vger.kernel.org |
3798 | S: Maintained | 3840 | S: Maintained |
3799 | F: drivers/video/riva/ | 3841 | F: drivers/video/riva/ |
3800 | F: drivers/video/nvidia/ | 3842 | F: drivers/video/nvidia/ |
@@ -3829,7 +3871,7 @@ F: sound/soc/omap/ | |||
3829 | 3871 | ||
3830 | OMAP FRAMEBUFFER SUPPORT | 3872 | OMAP FRAMEBUFFER SUPPORT |
3831 | M: Imre Deak <imre.deak@nokia.com> | 3873 | M: Imre Deak <imre.deak@nokia.com> |
3832 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 3874 | L: linux-fbdev@vger.kernel.org |
3833 | L: linux-omap@vger.kernel.org | 3875 | L: linux-omap@vger.kernel.org |
3834 | S: Maintained | 3876 | S: Maintained |
3835 | F: drivers/video/omap/ | 3877 | F: drivers/video/omap/ |
@@ -4335,14 +4377,14 @@ F: include/linux/qnxtypes.h | |||
4335 | 4377 | ||
4336 | RADEON FRAMEBUFFER DISPLAY DRIVER | 4378 | RADEON FRAMEBUFFER DISPLAY DRIVER |
4337 | M: Benjamin Herrenschmidt <benh@kernel.crashing.org> | 4379 | M: Benjamin Herrenschmidt <benh@kernel.crashing.org> |
4338 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 4380 | L: linux-fbdev@vger.kernel.org |
4339 | S: Maintained | 4381 | S: Maintained |
4340 | F: drivers/video/aty/radeon* | 4382 | F: drivers/video/aty/radeon* |
4341 | F: include/linux/radeonfb.h | 4383 | F: include/linux/radeonfb.h |
4342 | 4384 | ||
4343 | RAGE128 FRAMEBUFFER DISPLAY DRIVER | 4385 | RAGE128 FRAMEBUFFER DISPLAY DRIVER |
4344 | M: Paul Mackerras <paulus@samba.org> | 4386 | M: Paul Mackerras <paulus@samba.org> |
4345 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 4387 | L: linux-fbdev@vger.kernel.org |
4346 | S: Maintained | 4388 | S: Maintained |
4347 | F: drivers/video/aty/aty128fb.c | 4389 | F: drivers/video/aty/aty128fb.c |
4348 | 4390 | ||
@@ -4481,7 +4523,7 @@ F: drivers/net/wireless/rtl818x/rtl8187* | |||
4481 | 4523 | ||
4482 | S3 SAVAGE FRAMEBUFFER DRIVER | 4524 | S3 SAVAGE FRAMEBUFFER DRIVER |
4483 | M: Antonino Daplas <adaplas@gmail.com> | 4525 | M: Antonino Daplas <adaplas@gmail.com> |
4484 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 4526 | L: linux-fbdev@vger.kernel.org |
4485 | S: Maintained | 4527 | S: Maintained |
4486 | F: drivers/video/savage/ | 4528 | F: drivers/video/savage/ |
4487 | 4529 | ||
@@ -5644,7 +5686,7 @@ S: Maintained | |||
5644 | 5686 | ||
5645 | UVESAFB DRIVER | 5687 | UVESAFB DRIVER |
5646 | M: Michal Januszewski <spock@gentoo.org> | 5688 | M: Michal Januszewski <spock@gentoo.org> |
5647 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 5689 | L: linux-fbdev@vger.kernel.org |
5648 | W: http://dev.gentoo.org/~spock/projects/uvesafb/ | 5690 | W: http://dev.gentoo.org/~spock/projects/uvesafb/ |
5649 | S: Maintained | 5691 | S: Maintained |
5650 | F: Documentation/fb/uvesafb.txt | 5692 | F: Documentation/fb/uvesafb.txt |
@@ -5677,7 +5719,7 @@ F: drivers/mmc/host/via-sdmmc.c | |||
5677 | VIA UNICHROME(PRO)/CHROME9 FRAMEBUFFER DRIVER | 5719 | VIA UNICHROME(PRO)/CHROME9 FRAMEBUFFER DRIVER |
5678 | M: Joseph Chan <JosephChan@via.com.tw> | 5720 | M: Joseph Chan <JosephChan@via.com.tw> |
5679 | M: Scott Fang <ScottFang@viatech.com.cn> | 5721 | M: Scott Fang <ScottFang@viatech.com.cn> |
5680 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 5722 | L: linux-fbdev@vger.kernel.org |
5681 | S: Maintained | 5723 | S: Maintained |
5682 | F: drivers/video/via/ | 5724 | F: drivers/video/via/ |
5683 | 5725 | ||
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 7d0818797c85..cf8a99f19dc4 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -713,6 +713,16 @@ config ARCH_BCMRING | |||
713 | help | 713 | help |
714 | Support for Broadcom's BCMRing platform. | 714 | Support for Broadcom's BCMRing platform. |
715 | 715 | ||
716 | config ARCH_U8500 | ||
717 | bool "ST-Ericsson U8500 Series" | ||
718 | select CPU_V7 | ||
719 | select ARM_AMBA | ||
720 | select GENERIC_TIME | ||
721 | select GENERIC_CLOCKEVENTS | ||
722 | select COMMON_CLKDEV | ||
723 | help | ||
724 | Support for ST-Ericsson's Ux500 architecture | ||
725 | |||
716 | endchoice | 726 | endchoice |
717 | 727 | ||
718 | source "arch/arm/mach-clps711x/Kconfig" | 728 | source "arch/arm/mach-clps711x/Kconfig" |
@@ -801,6 +811,7 @@ source "arch/arm/mach-at91/Kconfig" | |||
801 | source "arch/arm/plat-mxc/Kconfig" | 811 | source "arch/arm/plat-mxc/Kconfig" |
802 | 812 | ||
803 | source "arch/arm/mach-nomadik/Kconfig" | 813 | source "arch/arm/mach-nomadik/Kconfig" |
814 | source "arch/arm/plat-nomadik/Kconfig" | ||
804 | 815 | ||
805 | source "arch/arm/mach-netx/Kconfig" | 816 | source "arch/arm/mach-netx/Kconfig" |
806 | 817 | ||
@@ -818,6 +829,8 @@ source "arch/arm/mach-w90x900/Kconfig" | |||
818 | 829 | ||
819 | source "arch/arm/mach-bcmring/Kconfig" | 830 | source "arch/arm/mach-bcmring/Kconfig" |
820 | 831 | ||
832 | source "arch/arm/mach-ux500/Kconfig" | ||
833 | |||
821 | # Definitions to make life easier | 834 | # Definitions to make life easier |
822 | config ARCH_ACORN | 835 | config ARCH_ACORN |
823 | bool | 836 | bool |
@@ -971,10 +984,10 @@ source "kernel/time/Kconfig" | |||
971 | config SMP | 984 | config SMP |
972 | bool "Symmetric Multi-Processing (EXPERIMENTAL)" | 985 | bool "Symmetric Multi-Processing (EXPERIMENTAL)" |
973 | depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\ | 986 | depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\ |
974 | MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4) | 987 | MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || ARCH_U8500) |
975 | depends on GENERIC_CLOCKEVENTS | 988 | depends on GENERIC_CLOCKEVENTS |
976 | select USE_GENERIC_SMP_HELPERS | 989 | select USE_GENERIC_SMP_HELPERS |
977 | select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4) | 990 | select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500) |
978 | help | 991 | help |
979 | This enables support for systems with more than one CPU. If you have | 992 | This enables support for systems with more than one CPU. If you have |
980 | a system with only one CPU, like most personal computers, say N. If | 993 | a system with only one CPU, like most personal computers, say N. If |
@@ -1043,9 +1056,9 @@ config HOTPLUG_CPU | |||
1043 | config LOCAL_TIMERS | 1056 | config LOCAL_TIMERS |
1044 | bool "Use local timer interrupts" | 1057 | bool "Use local timer interrupts" |
1045 | depends on SMP && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || \ | 1058 | depends on SMP && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || \ |
1046 | REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4) | 1059 | REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || ARCH_U8500) |
1047 | default y | 1060 | default y |
1048 | select HAVE_ARM_TWD if (ARCH_REALVIEW || ARCH_OMAP4) | 1061 | select HAVE_ARM_TWD if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500) |
1049 | help | 1062 | help |
1050 | Enable support for local timers on SMP platforms, rather then the | 1063 | Enable support for local timers on SMP platforms, rather then the |
1051 | legacy IPI broadcast method. Local timers allows the system | 1064 | legacy IPI broadcast method. Local timers allows the system |
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 1a6f70e52921..ff54c23d085e 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug | |||
@@ -83,6 +83,14 @@ config DEBUG_ICEDCC | |||
83 | It does include a timeout to ensure that the system does not | 83 | It does include a timeout to ensure that the system does not |
84 | totally freeze when there is nothing connected to read. | 84 | totally freeze when there is nothing connected to read. |
85 | 85 | ||
86 | config OC_ETM | ||
87 | bool "On-chip ETM and ETB" | ||
88 | select ARM_AMBA | ||
89 | help | ||
90 | Enables the on-chip embedded trace macrocell and embedded trace | ||
91 | buffer driver that will allow you to collect traces of the | ||
92 | kernel code. | ||
93 | |||
86 | config DEBUG_DC21285_PORT | 94 | config DEBUG_DC21285_PORT |
87 | bool "Kernel low-level debugging messages via footbridge serial port" | 95 | bool "Kernel low-level debugging messages via footbridge serial port" |
88 | depends on DEBUG_LL && FOOTBRIDGE | 96 | depends on DEBUG_LL && FOOTBRIDGE |
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 8c0d08fbd991..fa0cdab2e1d3 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile | |||
@@ -167,6 +167,7 @@ machine-$(CONFIG_ARCH_SHARK) := shark | |||
167 | machine-$(CONFIG_ARCH_STMP378X) := stmp378x | 167 | machine-$(CONFIG_ARCH_STMP378X) := stmp378x |
168 | machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx | 168 | machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx |
169 | machine-$(CONFIG_ARCH_U300) := u300 | 169 | machine-$(CONFIG_ARCH_U300) := u300 |
170 | machine-$(CONFIG_ARCH_U8500) := ux500 | ||
170 | machine-$(CONFIG_ARCH_VERSATILE) := versatile | 171 | machine-$(CONFIG_ARCH_VERSATILE) := versatile |
171 | machine-$(CONFIG_ARCH_W90X900) := w90x900 | 172 | machine-$(CONFIG_ARCH_W90X900) := w90x900 |
172 | machine-$(CONFIG_FOOTBRIDGE) := footbridge | 173 | machine-$(CONFIG_FOOTBRIDGE) := footbridge |
@@ -177,6 +178,7 @@ machine-$(CONFIG_ARCH_MXC91231) := mxc91231 | |||
177 | plat-$(CONFIG_ARCH_MXC) := mxc | 178 | plat-$(CONFIG_ARCH_MXC) := mxc |
178 | plat-$(CONFIG_ARCH_OMAP) := omap | 179 | plat-$(CONFIG_ARCH_OMAP) := omap |
179 | plat-$(CONFIG_PLAT_IOP) := iop | 180 | plat-$(CONFIG_PLAT_IOP) := iop |
181 | plat-$(CONFIG_PLAT_NOMADIK) := nomadik | ||
180 | plat-$(CONFIG_PLAT_ORION) := orion | 182 | plat-$(CONFIG_PLAT_ORION) := orion |
181 | plat-$(CONFIG_PLAT_PXA) := pxa | 183 | plat-$(CONFIG_PLAT_PXA) := pxa |
182 | plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx s3c samsung | 184 | plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx s3c samsung |
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c index 734ac9135998..5a375e5fef21 100644 --- a/arch/arm/common/dmabounce.c +++ b/arch/arm/common/dmabounce.c | |||
@@ -342,6 +342,22 @@ dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, | |||
342 | } | 342 | } |
343 | EXPORT_SYMBOL(dma_map_single); | 343 | EXPORT_SYMBOL(dma_map_single); |
344 | 344 | ||
345 | /* | ||
346 | * see if a mapped address was really a "safe" buffer and if so, copy | ||
347 | * the data from the safe buffer back to the unsafe buffer and free up | ||
348 | * the safe buffer. (basically return things back to the way they | ||
349 | * should be) | ||
350 | */ | ||
351 | void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, | ||
352 | enum dma_data_direction dir) | ||
353 | { | ||
354 | dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", | ||
355 | __func__, (void *) dma_addr, size, dir); | ||
356 | |||
357 | unmap_single(dev, dma_addr, size, dir); | ||
358 | } | ||
359 | EXPORT_SYMBOL(dma_unmap_single); | ||
360 | |||
345 | dma_addr_t dma_map_page(struct device *dev, struct page *page, | 361 | dma_addr_t dma_map_page(struct device *dev, struct page *page, |
346 | unsigned long offset, size_t size, enum dma_data_direction dir) | 362 | unsigned long offset, size_t size, enum dma_data_direction dir) |
347 | { | 363 | { |
@@ -366,8 +382,7 @@ EXPORT_SYMBOL(dma_map_page); | |||
366 | * the safe buffer. (basically return things back to the way they | 382 | * the safe buffer. (basically return things back to the way they |
367 | * should be) | 383 | * should be) |
368 | */ | 384 | */ |
369 | 385 | void dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, | |
370 | void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, | ||
371 | enum dma_data_direction dir) | 386 | enum dma_data_direction dir) |
372 | { | 387 | { |
373 | dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", | 388 | dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", |
@@ -375,7 +390,7 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, | |||
375 | 390 | ||
376 | unmap_single(dev, dma_addr, size, dir); | 391 | unmap_single(dev, dma_addr, size, dir); |
377 | } | 392 | } |
378 | EXPORT_SYMBOL(dma_unmap_single); | 393 | EXPORT_SYMBOL(dma_unmap_page); |
379 | 394 | ||
380 | int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr, | 395 | int dmabounce_sync_for_cpu(struct device *dev, dma_addr_t addr, |
381 | unsigned long off, size_t sz, enum dma_data_direction dir) | 396 | unsigned long off, size_t sz, enum dma_data_direction dir) |
diff --git a/arch/arm/configs/at91rm9200dk_defconfig b/arch/arm/configs/at91rm9200dk_defconfig index 238b218394e3..c97e1022ada1 100644 --- a/arch/arm/configs/at91rm9200dk_defconfig +++ b/arch/arm/configs/at91rm9200dk_defconfig | |||
@@ -120,6 +120,7 @@ CONFIG_ARCH_AT91RM9200DK=y | |||
120 | # CONFIG_MACH_CARMEVA is not set | 120 | # CONFIG_MACH_CARMEVA is not set |
121 | # CONFIG_MACH_KB9200 is not set | 121 | # CONFIG_MACH_KB9200 is not set |
122 | # CONFIG_MACH_ATEB9200 is not set | 122 | # CONFIG_MACH_ATEB9200 is not set |
123 | CONFIG_MACH_ECO920=y | ||
123 | 124 | ||
124 | # | 125 | # |
125 | # AT91RM9200 Feature Selections | 126 | # AT91RM9200 Feature Selections |
diff --git a/arch/arm/configs/w90p910_defconfig b/arch/arm/configs/nuc910_defconfig index 5245655a0ad3..5245655a0ad3 100644 --- a/arch/arm/configs/w90p910_defconfig +++ b/arch/arm/configs/nuc910_defconfig | |||
diff --git a/arch/arm/configs/nuc950_defconfig b/arch/arm/configs/nuc950_defconfig new file mode 100644 index 000000000000..df1de9b45ca4 --- /dev/null +++ b/arch/arm/configs/nuc950_defconfig | |||
@@ -0,0 +1,922 @@ | |||
1 | # | ||
2 | # Automatically generated make config: don't edit | ||
3 | # Linux kernel version: 2.6.32-rc7 | ||
4 | # Tue Nov 17 12:31:33 2009 | ||
5 | # | ||
6 | CONFIG_ARM=y | ||
7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y | ||
8 | CONFIG_GENERIC_GPIO=y | ||
9 | CONFIG_GENERIC_TIME=y | ||
10 | CONFIG_GENERIC_CLOCKEVENTS=y | ||
11 | CONFIG_GENERIC_HARDIRQS=y | ||
12 | CONFIG_STACKTRACE_SUPPORT=y | ||
13 | CONFIG_HAVE_LATENCYTOP_SUPPORT=y | ||
14 | CONFIG_LOCKDEP_SUPPORT=y | ||
15 | CONFIG_TRACE_IRQFLAGS_SUPPORT=y | ||
16 | CONFIG_HARDIRQS_SW_RESEND=y | ||
17 | CONFIG_GENERIC_IRQ_PROBE=y | ||
18 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
19 | CONFIG_GENERIC_HWEIGHT=y | ||
20 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
21 | CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y | ||
22 | CONFIG_VECTORS_BASE=0xffff0000 | ||
23 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
24 | CONFIG_CONSTRUCTORS=y | ||
25 | |||
26 | # | ||
27 | # General setup | ||
28 | # | ||
29 | CONFIG_EXPERIMENTAL=y | ||
30 | CONFIG_BROKEN_ON_SMP=y | ||
31 | CONFIG_LOCK_KERNEL=y | ||
32 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
33 | CONFIG_LOCALVERSION="" | ||
34 | # CONFIG_LOCALVERSION_AUTO is not set | ||
35 | CONFIG_SWAP=y | ||
36 | CONFIG_SYSVIPC=y | ||
37 | CONFIG_SYSVIPC_SYSCTL=y | ||
38 | CONFIG_BSD_PROCESS_ACCT=y | ||
39 | # CONFIG_BSD_PROCESS_ACCT_V3 is not set | ||
40 | |||
41 | # | ||
42 | # RCU Subsystem | ||
43 | # | ||
44 | CONFIG_TREE_RCU=y | ||
45 | # CONFIG_TREE_PREEMPT_RCU is not set | ||
46 | # CONFIG_RCU_TRACE is not set | ||
47 | CONFIG_RCU_FANOUT=32 | ||
48 | # CONFIG_RCU_FANOUT_EXACT is not set | ||
49 | # CONFIG_TREE_RCU_TRACE is not set | ||
50 | # CONFIG_IKCONFIG is not set | ||
51 | CONFIG_LOG_BUF_SHIFT=17 | ||
52 | # CONFIG_GROUP_SCHED is not set | ||
53 | # CONFIG_CGROUPS is not set | ||
54 | CONFIG_SYSFS_DEPRECATED=y | ||
55 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
56 | CONFIG_RELAY=y | ||
57 | CONFIG_NAMESPACES=y | ||
58 | # CONFIG_UTS_NS is not set | ||
59 | # CONFIG_IPC_NS is not set | ||
60 | CONFIG_USER_NS=y | ||
61 | # CONFIG_PID_NS is not set | ||
62 | CONFIG_BLK_DEV_INITRD=y | ||
63 | CONFIG_INITRAMFS_SOURCE="" | ||
64 | CONFIG_RD_GZIP=y | ||
65 | CONFIG_RD_BZIP2=y | ||
66 | CONFIG_RD_LZMA=y | ||
67 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
68 | CONFIG_SYSCTL=y | ||
69 | CONFIG_ANON_INODES=y | ||
70 | # CONFIG_EMBEDDED is not set | ||
71 | CONFIG_UID16=y | ||
72 | CONFIG_SYSCTL_SYSCALL=y | ||
73 | CONFIG_KALLSYMS=y | ||
74 | CONFIG_KALLSYMS_EXTRA_PASS=y | ||
75 | CONFIG_HOTPLUG=y | ||
76 | CONFIG_PRINTK=y | ||
77 | CONFIG_BUG=y | ||
78 | CONFIG_ELF_CORE=y | ||
79 | CONFIG_BASE_FULL=y | ||
80 | CONFIG_FUTEX=y | ||
81 | CONFIG_EPOLL=y | ||
82 | CONFIG_SIGNALFD=y | ||
83 | CONFIG_TIMERFD=y | ||
84 | CONFIG_EVENTFD=y | ||
85 | CONFIG_SHMEM=y | ||
86 | CONFIG_AIO=y | ||
87 | |||
88 | # | ||
89 | # Kernel Performance Events And Counters | ||
90 | # | ||
91 | CONFIG_VM_EVENT_COUNTERS=y | ||
92 | CONFIG_COMPAT_BRK=y | ||
93 | CONFIG_SLAB=y | ||
94 | # CONFIG_SLUB is not set | ||
95 | # CONFIG_SLOB is not set | ||
96 | # CONFIG_PROFILING is not set | ||
97 | CONFIG_HAVE_OPROFILE=y | ||
98 | CONFIG_HAVE_KPROBES=y | ||
99 | CONFIG_HAVE_KRETPROBES=y | ||
100 | CONFIG_HAVE_CLK=y | ||
101 | |||
102 | # | ||
103 | # GCOV-based kernel profiling | ||
104 | # | ||
105 | # CONFIG_GCOV_KERNEL is not set | ||
106 | # CONFIG_SLOW_WORK is not set | ||
107 | CONFIG_HAVE_GENERIC_DMA_COHERENT=y | ||
108 | CONFIG_SLABINFO=y | ||
109 | CONFIG_RT_MUTEXES=y | ||
110 | CONFIG_BASE_SMALL=0 | ||
111 | # CONFIG_MODULES is not set | ||
112 | CONFIG_BLOCK=y | ||
113 | CONFIG_LBDAF=y | ||
114 | CONFIG_BLK_DEV_BSG=y | ||
115 | # CONFIG_BLK_DEV_INTEGRITY is not set | ||
116 | |||
117 | # | ||
118 | # IO Schedulers | ||
119 | # | ||
120 | CONFIG_IOSCHED_NOOP=y | ||
121 | CONFIG_IOSCHED_AS=y | ||
122 | CONFIG_IOSCHED_DEADLINE=y | ||
123 | CONFIG_IOSCHED_CFQ=y | ||
124 | # CONFIG_DEFAULT_AS is not set | ||
125 | # CONFIG_DEFAULT_DEADLINE is not set | ||
126 | CONFIG_DEFAULT_CFQ=y | ||
127 | # CONFIG_DEFAULT_NOOP is not set | ||
128 | CONFIG_DEFAULT_IOSCHED="cfq" | ||
129 | # CONFIG_FREEZER is not set | ||
130 | |||
131 | # | ||
132 | # System Type | ||
133 | # | ||
134 | CONFIG_MMU=y | ||
135 | # CONFIG_ARCH_AAEC2000 is not set | ||
136 | # CONFIG_ARCH_INTEGRATOR is not set | ||
137 | # CONFIG_ARCH_REALVIEW is not set | ||
138 | # CONFIG_ARCH_VERSATILE is not set | ||
139 | # CONFIG_ARCH_AT91 is not set | ||
140 | # CONFIG_ARCH_CLPS711X is not set | ||
141 | # CONFIG_ARCH_GEMINI is not set | ||
142 | # CONFIG_ARCH_EBSA110 is not set | ||
143 | # CONFIG_ARCH_EP93XX is not set | ||
144 | # CONFIG_ARCH_FOOTBRIDGE is not set | ||
145 | # CONFIG_ARCH_MXC is not set | ||
146 | # CONFIG_ARCH_STMP3XXX is not set | ||
147 | # CONFIG_ARCH_NETX is not set | ||
148 | # CONFIG_ARCH_H720X is not set | ||
149 | # CONFIG_ARCH_NOMADIK is not set | ||
150 | # CONFIG_ARCH_IOP13XX is not set | ||
151 | # CONFIG_ARCH_IOP32X is not set | ||
152 | # CONFIG_ARCH_IOP33X is not set | ||
153 | # CONFIG_ARCH_IXP23XX is not set | ||
154 | # CONFIG_ARCH_IXP2000 is not set | ||
155 | # CONFIG_ARCH_IXP4XX is not set | ||
156 | # CONFIG_ARCH_L7200 is not set | ||
157 | # CONFIG_ARCH_KIRKWOOD is not set | ||
158 | # CONFIG_ARCH_LOKI is not set | ||
159 | # CONFIG_ARCH_MV78XX0 is not set | ||
160 | # CONFIG_ARCH_ORION5X is not set | ||
161 | # CONFIG_ARCH_MMP is not set | ||
162 | # CONFIG_ARCH_KS8695 is not set | ||
163 | # CONFIG_ARCH_NS9XXX is not set | ||
164 | CONFIG_ARCH_W90X900=y | ||
165 | # CONFIG_ARCH_PNX4008 is not set | ||
166 | # CONFIG_ARCH_PXA is not set | ||
167 | # CONFIG_ARCH_MSM is not set | ||
168 | # CONFIG_ARCH_RPC is not set | ||
169 | # CONFIG_ARCH_SA1100 is not set | ||
170 | # CONFIG_ARCH_S3C2410 is not set | ||
171 | # CONFIG_ARCH_S3C64XX is not set | ||
172 | # CONFIG_ARCH_S5PC1XX is not set | ||
173 | # CONFIG_ARCH_SHARK is not set | ||
174 | # CONFIG_ARCH_LH7A40X is not set | ||
175 | # CONFIG_ARCH_U300 is not set | ||
176 | # CONFIG_ARCH_DAVINCI is not set | ||
177 | # CONFIG_ARCH_OMAP is not set | ||
178 | # CONFIG_ARCH_BCMRING is not set | ||
179 | CONFIG_CPU_NUC950=y | ||
180 | |||
181 | # | ||
182 | # W90P910 Machines | ||
183 | # | ||
184 | # CONFIG_MACH_W90P910EVB is not set | ||
185 | |||
186 | # | ||
187 | # NUC950 Machines | ||
188 | # | ||
189 | CONFIG_MACH_W90P950EVB=y | ||
190 | |||
191 | # | ||
192 | # NUC960 Machines | ||
193 | # | ||
194 | # CONFIG_MACH_W90N960EVB is not set | ||
195 | |||
196 | # | ||
197 | # NUC932 Machines | ||
198 | # | ||
199 | # CONFIG_MACH_NUC932EVB is not set | ||
200 | |||
201 | # | ||
202 | # Processor Type | ||
203 | # | ||
204 | CONFIG_CPU_32=y | ||
205 | CONFIG_CPU_ARM926T=y | ||
206 | CONFIG_CPU_32v5=y | ||
207 | CONFIG_CPU_ABRT_EV5TJ=y | ||
208 | CONFIG_CPU_PABRT_LEGACY=y | ||
209 | CONFIG_CPU_CACHE_VIVT=y | ||
210 | CONFIG_CPU_COPY_V4WB=y | ||
211 | CONFIG_CPU_TLB_V4WBI=y | ||
212 | CONFIG_CPU_CP15=y | ||
213 | CONFIG_CPU_CP15_MMU=y | ||
214 | |||
215 | # | ||
216 | # Processor Features | ||
217 | # | ||
218 | CONFIG_ARM_THUMB=y | ||
219 | # CONFIG_CPU_ICACHE_DISABLE is not set | ||
220 | # CONFIG_CPU_DCACHE_DISABLE is not set | ||
221 | # CONFIG_CPU_DCACHE_WRITETHROUGH is not set | ||
222 | # CONFIG_CPU_CACHE_ROUND_ROBIN is not set | ||
223 | CONFIG_ARM_L1_CACHE_SHIFT=5 | ||
224 | CONFIG_COMMON_CLKDEV=y | ||
225 | |||
226 | # | ||
227 | # Bus support | ||
228 | # | ||
229 | # CONFIG_PCI_SYSCALL is not set | ||
230 | # CONFIG_ARCH_SUPPORTS_MSI is not set | ||
231 | # CONFIG_PCCARD is not set | ||
232 | |||
233 | # | ||
234 | # Kernel Features | ||
235 | # | ||
236 | CONFIG_TICK_ONESHOT=y | ||
237 | CONFIG_NO_HZ=y | ||
238 | CONFIG_HIGH_RES_TIMERS=y | ||
239 | CONFIG_GENERIC_CLOCKEVENTS_BUILD=y | ||
240 | CONFIG_VMSPLIT_3G=y | ||
241 | # CONFIG_VMSPLIT_2G is not set | ||
242 | # CONFIG_VMSPLIT_1G is not set | ||
243 | CONFIG_PAGE_OFFSET=0xC0000000 | ||
244 | # CONFIG_PREEMPT_NONE is not set | ||
245 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
246 | CONFIG_PREEMPT=y | ||
247 | CONFIG_HZ=100 | ||
248 | CONFIG_AEABI=y | ||
249 | CONFIG_OABI_COMPAT=y | ||
250 | # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set | ||
251 | # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set | ||
252 | # CONFIG_HIGHMEM is not set | ||
253 | CONFIG_SELECT_MEMORY_MODEL=y | ||
254 | CONFIG_FLATMEM_MANUAL=y | ||
255 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
256 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
257 | CONFIG_FLATMEM=y | ||
258 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
259 | CONFIG_PAGEFLAGS_EXTENDED=y | ||
260 | CONFIG_SPLIT_PTLOCK_CPUS=4096 | ||
261 | # CONFIG_PHYS_ADDR_T_64BIT is not set | ||
262 | CONFIG_ZONE_DMA_FLAG=0 | ||
263 | CONFIG_VIRT_TO_BUS=y | ||
264 | CONFIG_HAVE_MLOCK=y | ||
265 | CONFIG_HAVE_MLOCKED_PAGE_BIT=y | ||
266 | # CONFIG_KSM is not set | ||
267 | CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 | ||
268 | CONFIG_ALIGNMENT_TRAP=y | ||
269 | # CONFIG_UACCESS_WITH_MEMCPY is not set | ||
270 | |||
271 | # | ||
272 | # Boot options | ||
273 | # | ||
274 | CONFIG_ZBOOT_ROM_TEXT=0 | ||
275 | CONFIG_ZBOOT_ROM_BSS=0 | ||
276 | CONFIG_CMDLINE="root=/dev/ram0 console=ttyS0,115200n8 rdinit=/sbin/init mem=64M" | ||
277 | # CONFIG_XIP_KERNEL is not set | ||
278 | CONFIG_KEXEC=y | ||
279 | CONFIG_ATAGS_PROC=y | ||
280 | |||
281 | # | ||
282 | # CPU Power Management | ||
283 | # | ||
284 | # CONFIG_CPU_IDLE is not set | ||
285 | |||
286 | # | ||
287 | # Floating point emulation | ||
288 | # | ||
289 | |||
290 | # | ||
291 | # At least one emulation must be selected | ||
292 | # | ||
293 | CONFIG_FPE_NWFPE=y | ||
294 | # CONFIG_FPE_NWFPE_XP is not set | ||
295 | # CONFIG_FPE_FASTFPE is not set | ||
296 | # CONFIG_VFP is not set | ||
297 | |||
298 | # | ||
299 | # Userspace binary formats | ||
300 | # | ||
301 | CONFIG_BINFMT_ELF=y | ||
302 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
303 | CONFIG_HAVE_AOUT=y | ||
304 | CONFIG_BINFMT_AOUT=y | ||
305 | CONFIG_BINFMT_MISC=y | ||
306 | |||
307 | # | ||
308 | # Power management options | ||
309 | # | ||
310 | # CONFIG_PM is not set | ||
311 | CONFIG_ARCH_SUSPEND_POSSIBLE=y | ||
312 | # CONFIG_NET is not set | ||
313 | |||
314 | # | ||
315 | # Device Drivers | ||
316 | # | ||
317 | |||
318 | # | ||
319 | # Generic Driver Options | ||
320 | # | ||
321 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
322 | # CONFIG_DEVTMPFS is not set | ||
323 | CONFIG_STANDALONE=y | ||
324 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
325 | CONFIG_FW_LOADER=y | ||
326 | CONFIG_FIRMWARE_IN_KERNEL=y | ||
327 | CONFIG_EXTRA_FIRMWARE="" | ||
328 | # CONFIG_SYS_HYPERVISOR is not set | ||
329 | CONFIG_MTD=y | ||
330 | # CONFIG_MTD_DEBUG is not set | ||
331 | CONFIG_MTD_CONCAT=y | ||
332 | CONFIG_MTD_PARTITIONS=y | ||
333 | # CONFIG_MTD_REDBOOT_PARTS is not set | ||
334 | # CONFIG_MTD_CMDLINE_PARTS is not set | ||
335 | # CONFIG_MTD_AFS_PARTS is not set | ||
336 | # CONFIG_MTD_AR7_PARTS is not set | ||
337 | |||
338 | # | ||
339 | # User Modules And Translation Layers | ||
340 | # | ||
341 | CONFIG_MTD_CHAR=y | ||
342 | CONFIG_MTD_BLKDEVS=y | ||
343 | CONFIG_MTD_BLOCK=y | ||
344 | # CONFIG_FTL is not set | ||
345 | # CONFIG_NFTL is not set | ||
346 | # CONFIG_INFTL is not set | ||
347 | # CONFIG_RFD_FTL is not set | ||
348 | # CONFIG_SSFDC is not set | ||
349 | # CONFIG_MTD_OOPS is not set | ||
350 | |||
351 | # | ||
352 | # RAM/ROM/Flash chip drivers | ||
353 | # | ||
354 | CONFIG_MTD_CFI=y | ||
355 | # CONFIG_MTD_JEDECPROBE is not set | ||
356 | CONFIG_MTD_GEN_PROBE=y | ||
357 | # CONFIG_MTD_CFI_ADV_OPTIONS is not set | ||
358 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
359 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
360 | CONFIG_MTD_MAP_BANK_WIDTH_4=y | ||
361 | # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set | ||
362 | # CONFIG_MTD_MAP_BANK_WIDTH_16 is not set | ||
363 | # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set | ||
364 | CONFIG_MTD_CFI_I1=y | ||
365 | CONFIG_MTD_CFI_I2=y | ||
366 | # CONFIG_MTD_CFI_I4 is not set | ||
367 | # CONFIG_MTD_CFI_I8 is not set | ||
368 | # CONFIG_MTD_CFI_INTELEXT is not set | ||
369 | CONFIG_MTD_CFI_AMDSTD=y | ||
370 | # CONFIG_MTD_CFI_STAA is not set | ||
371 | CONFIG_MTD_CFI_UTIL=y | ||
372 | # CONFIG_MTD_RAM is not set | ||
373 | # CONFIG_MTD_ROM is not set | ||
374 | # CONFIG_MTD_ABSENT is not set | ||
375 | |||
376 | # | ||
377 | # Mapping drivers for chip access | ||
378 | # | ||
379 | # CONFIG_MTD_COMPLEX_MAPPINGS is not set | ||
380 | CONFIG_MTD_PHYSMAP=y | ||
381 | # CONFIG_MTD_PHYSMAP_COMPAT is not set | ||
382 | # CONFIG_MTD_ARM_INTEGRATOR is not set | ||
383 | # CONFIG_MTD_PLATRAM is not set | ||
384 | |||
385 | # | ||
386 | # Self-contained MTD device drivers | ||
387 | # | ||
388 | # CONFIG_MTD_SLRAM is not set | ||
389 | # CONFIG_MTD_PHRAM is not set | ||
390 | # CONFIG_MTD_MTDRAM is not set | ||
391 | # CONFIG_MTD_BLOCK2MTD is not set | ||
392 | |||
393 | # | ||
394 | # Disk-On-Chip Device Drivers | ||
395 | # | ||
396 | # CONFIG_MTD_DOC2000 is not set | ||
397 | # CONFIG_MTD_DOC2001 is not set | ||
398 | # CONFIG_MTD_DOC2001PLUS is not set | ||
399 | # CONFIG_MTD_NAND is not set | ||
400 | # CONFIG_MTD_ONENAND is not set | ||
401 | |||
402 | # | ||
403 | # LPDDR flash memory drivers | ||
404 | # | ||
405 | # CONFIG_MTD_LPDDR is not set | ||
406 | |||
407 | # | ||
408 | # UBI - Unsorted block images | ||
409 | # | ||
410 | # CONFIG_MTD_UBI is not set | ||
411 | # CONFIG_PARPORT is not set | ||
412 | CONFIG_BLK_DEV=y | ||
413 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
414 | # CONFIG_BLK_DEV_LOOP is not set | ||
415 | # CONFIG_BLK_DEV_UB is not set | ||
416 | CONFIG_BLK_DEV_RAM=y | ||
417 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
418 | CONFIG_BLK_DEV_RAM_SIZE=16384 | ||
419 | # CONFIG_BLK_DEV_XIP is not set | ||
420 | # CONFIG_CDROM_PKTCDVD is not set | ||
421 | # CONFIG_MG_DISK is not set | ||
422 | # CONFIG_MISC_DEVICES is not set | ||
423 | CONFIG_HAVE_IDE=y | ||
424 | # CONFIG_IDE is not set | ||
425 | |||
426 | # | ||
427 | # SCSI device support | ||
428 | # | ||
429 | # CONFIG_RAID_ATTRS is not set | ||
430 | CONFIG_SCSI=y | ||
431 | CONFIG_SCSI_DMA=y | ||
432 | # CONFIG_SCSI_TGT is not set | ||
433 | # CONFIG_SCSI_NETLINK is not set | ||
434 | # CONFIG_SCSI_PROC_FS is not set | ||
435 | |||
436 | # | ||
437 | # SCSI support type (disk, tape, CD-ROM) | ||
438 | # | ||
439 | CONFIG_BLK_DEV_SD=y | ||
440 | # CONFIG_CHR_DEV_ST is not set | ||
441 | # CONFIG_CHR_DEV_OSST is not set | ||
442 | # CONFIG_BLK_DEV_SR is not set | ||
443 | # CONFIG_CHR_DEV_SG is not set | ||
444 | # CONFIG_CHR_DEV_SCH is not set | ||
445 | # CONFIG_SCSI_MULTI_LUN is not set | ||
446 | # CONFIG_SCSI_CONSTANTS is not set | ||
447 | # CONFIG_SCSI_LOGGING is not set | ||
448 | # CONFIG_SCSI_SCAN_ASYNC is not set | ||
449 | |||
450 | # | ||
451 | # SCSI Transports | ||
452 | # | ||
453 | # CONFIG_SCSI_SPI_ATTRS is not set | ||
454 | # CONFIG_SCSI_FC_ATTRS is not set | ||
455 | # CONFIG_SCSI_SAS_ATTRS is not set | ||
456 | # CONFIG_SCSI_SAS_LIBSAS is not set | ||
457 | # CONFIG_SCSI_SRP_ATTRS is not set | ||
458 | # CONFIG_SCSI_LOWLEVEL is not set | ||
459 | # CONFIG_SCSI_DH is not set | ||
460 | # CONFIG_SCSI_OSD_INITIATOR is not set | ||
461 | # CONFIG_ATA is not set | ||
462 | # CONFIG_MD is not set | ||
463 | # CONFIG_PHONE is not set | ||
464 | |||
465 | # | ||
466 | # Input device support | ||
467 | # | ||
468 | CONFIG_INPUT=y | ||
469 | # CONFIG_INPUT_FF_MEMLESS is not set | ||
470 | # CONFIG_INPUT_POLLDEV is not set | ||
471 | |||
472 | # | ||
473 | # Userland interfaces | ||
474 | # | ||
475 | CONFIG_INPUT_MOUSEDEV=y | ||
476 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set | ||
477 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | ||
478 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | ||
479 | # CONFIG_INPUT_JOYDEV is not set | ||
480 | # CONFIG_INPUT_EVDEV is not set | ||
481 | # CONFIG_INPUT_EVBUG is not set | ||
482 | |||
483 | # | ||
484 | # Input Device Drivers | ||
485 | # | ||
486 | # CONFIG_INPUT_KEYBOARD is not set | ||
487 | # CONFIG_INPUT_MOUSE is not set | ||
488 | # CONFIG_INPUT_JOYSTICK is not set | ||
489 | # CONFIG_INPUT_TABLET is not set | ||
490 | # CONFIG_INPUT_TOUCHSCREEN is not set | ||
491 | # CONFIG_INPUT_MISC is not set | ||
492 | |||
493 | # | ||
494 | # Hardware I/O ports | ||
495 | # | ||
496 | # CONFIG_SERIO is not set | ||
497 | # CONFIG_GAMEPORT is not set | ||
498 | |||
499 | # | ||
500 | # Character devices | ||
501 | # | ||
502 | CONFIG_VT=y | ||
503 | CONFIG_CONSOLE_TRANSLATIONS=y | ||
504 | CONFIG_VT_CONSOLE=y | ||
505 | CONFIG_HW_CONSOLE=y | ||
506 | # CONFIG_VT_HW_CONSOLE_BINDING is not set | ||
507 | # CONFIG_DEVKMEM is not set | ||
508 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
509 | |||
510 | # | ||
511 | # Serial drivers | ||
512 | # | ||
513 | CONFIG_SERIAL_8250=y | ||
514 | CONFIG_SERIAL_8250_CONSOLE=y | ||
515 | CONFIG_SERIAL_8250_NR_UARTS=1 | ||
516 | CONFIG_SERIAL_8250_RUNTIME_UARTS=1 | ||
517 | # CONFIG_SERIAL_8250_EXTENDED is not set | ||
518 | |||
519 | # | ||
520 | # Non-8250 serial port support | ||
521 | # | ||
522 | CONFIG_SERIAL_CORE=y | ||
523 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
524 | CONFIG_UNIX98_PTYS=y | ||
525 | # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set | ||
526 | # CONFIG_LEGACY_PTYS is not set | ||
527 | # CONFIG_IPMI_HANDLER is not set | ||
528 | # CONFIG_HW_RANDOM is not set | ||
529 | # CONFIG_R3964 is not set | ||
530 | # CONFIG_RAW_DRIVER is not set | ||
531 | # CONFIG_TCG_TPM is not set | ||
532 | # CONFIG_I2C is not set | ||
533 | # CONFIG_SPI is not set | ||
534 | |||
535 | # | ||
536 | # PPS support | ||
537 | # | ||
538 | # CONFIG_PPS is not set | ||
539 | CONFIG_ARCH_REQUIRE_GPIOLIB=y | ||
540 | CONFIG_GPIOLIB=y | ||
541 | # CONFIG_GPIO_SYSFS is not set | ||
542 | |||
543 | # | ||
544 | # Memory mapped GPIO expanders: | ||
545 | # | ||
546 | |||
547 | # | ||
548 | # I2C GPIO expanders: | ||
549 | # | ||
550 | |||
551 | # | ||
552 | # PCI GPIO expanders: | ||
553 | # | ||
554 | |||
555 | # | ||
556 | # SPI GPIO expanders: | ||
557 | # | ||
558 | |||
559 | # | ||
560 | # AC97 GPIO expanders: | ||
561 | # | ||
562 | # CONFIG_W1 is not set | ||
563 | # CONFIG_POWER_SUPPLY is not set | ||
564 | # CONFIG_HWMON is not set | ||
565 | # CONFIG_THERMAL is not set | ||
566 | # CONFIG_WATCHDOG is not set | ||
567 | CONFIG_SSB_POSSIBLE=y | ||
568 | |||
569 | # | ||
570 | # Sonics Silicon Backplane | ||
571 | # | ||
572 | # CONFIG_SSB is not set | ||
573 | |||
574 | # | ||
575 | # Multifunction device drivers | ||
576 | # | ||
577 | # CONFIG_MFD_CORE is not set | ||
578 | # CONFIG_MFD_SM501 is not set | ||
579 | # CONFIG_MFD_ASIC3 is not set | ||
580 | # CONFIG_HTC_EGPIO is not set | ||
581 | # CONFIG_HTC_PASIC3 is not set | ||
582 | # CONFIG_MFD_TMIO is not set | ||
583 | # CONFIG_MFD_T7L66XB is not set | ||
584 | # CONFIG_MFD_TC6387XB is not set | ||
585 | # CONFIG_MFD_TC6393XB is not set | ||
586 | # CONFIG_REGULATOR is not set | ||
587 | # CONFIG_MEDIA_SUPPORT is not set | ||
588 | |||
589 | # | ||
590 | # Graphics support | ||
591 | # | ||
592 | # CONFIG_VGASTATE is not set | ||
593 | # CONFIG_VIDEO_OUTPUT_CONTROL is not set | ||
594 | # CONFIG_FB is not set | ||
595 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
596 | |||
597 | # | ||
598 | # Display device support | ||
599 | # | ||
600 | # CONFIG_DISPLAY_SUPPORT is not set | ||
601 | |||
602 | # | ||
603 | # Console display driver support | ||
604 | # | ||
605 | # CONFIG_VGA_CONSOLE is not set | ||
606 | CONFIG_DUMMY_CONSOLE=y | ||
607 | # CONFIG_SOUND is not set | ||
608 | # CONFIG_HID_SUPPORT is not set | ||
609 | CONFIG_USB_SUPPORT=y | ||
610 | CONFIG_USB_ARCH_HAS_HCD=y | ||
611 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
612 | CONFIG_USB_ARCH_HAS_EHCI=y | ||
613 | CONFIG_USB=y | ||
614 | # CONFIG_USB_DEBUG is not set | ||
615 | # CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set | ||
616 | |||
617 | # | ||
618 | # Miscellaneous USB options | ||
619 | # | ||
620 | # CONFIG_USB_DEVICEFS is not set | ||
621 | CONFIG_USB_DEVICE_CLASS=y | ||
622 | # CONFIG_USB_DYNAMIC_MINORS is not set | ||
623 | # CONFIG_USB_OTG is not set | ||
624 | CONFIG_USB_MON=y | ||
625 | # CONFIG_USB_WUSB is not set | ||
626 | # CONFIG_USB_WUSB_CBAF is not set | ||
627 | |||
628 | # | ||
629 | # USB Host Controller Drivers | ||
630 | # | ||
631 | # CONFIG_USB_C67X00_HCD is not set | ||
632 | # CONFIG_USB_EHCI_HCD is not set | ||
633 | # CONFIG_USB_OXU210HP_HCD is not set | ||
634 | # CONFIG_USB_ISP116X_HCD is not set | ||
635 | # CONFIG_USB_ISP1760_HCD is not set | ||
636 | # CONFIG_USB_ISP1362_HCD is not set | ||
637 | # CONFIG_USB_OHCI_HCD is not set | ||
638 | # CONFIG_USB_SL811_HCD is not set | ||
639 | # CONFIG_USB_R8A66597_HCD is not set | ||
640 | # CONFIG_USB_HWA_HCD is not set | ||
641 | # CONFIG_USB_MUSB_HDRC is not set | ||
642 | |||
643 | # | ||
644 | # USB Device Class drivers | ||
645 | # | ||
646 | # CONFIG_USB_ACM is not set | ||
647 | # CONFIG_USB_PRINTER is not set | ||
648 | # CONFIG_USB_WDM is not set | ||
649 | # CONFIG_USB_TMC is not set | ||
650 | |||
651 | # | ||
652 | # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may | ||
653 | # | ||
654 | |||
655 | # | ||
656 | # also be needed; see USB_STORAGE Help for more info | ||
657 | # | ||
658 | CONFIG_USB_STORAGE=y | ||
659 | # CONFIG_USB_STORAGE_DEBUG is not set | ||
660 | # CONFIG_USB_STORAGE_DATAFAB is not set | ||
661 | # CONFIG_USB_STORAGE_FREECOM is not set | ||
662 | # CONFIG_USB_STORAGE_ISD200 is not set | ||
663 | # CONFIG_USB_STORAGE_USBAT is not set | ||
664 | # CONFIG_USB_STORAGE_SDDR09 is not set | ||
665 | # CONFIG_USB_STORAGE_SDDR55 is not set | ||
666 | # CONFIG_USB_STORAGE_JUMPSHOT is not set | ||
667 | # CONFIG_USB_STORAGE_ALAUDA is not set | ||
668 | # CONFIG_USB_STORAGE_ONETOUCH is not set | ||
669 | # CONFIG_USB_STORAGE_KARMA is not set | ||
670 | # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set | ||
671 | # CONFIG_USB_LIBUSUAL is not set | ||
672 | |||
673 | # | ||
674 | # USB Imaging devices | ||
675 | # | ||
676 | # CONFIG_USB_MDC800 is not set | ||
677 | # CONFIG_USB_MICROTEK is not set | ||
678 | |||
679 | # | ||
680 | # USB port drivers | ||
681 | # | ||
682 | # CONFIG_USB_SERIAL is not set | ||
683 | |||
684 | # | ||
685 | # USB Miscellaneous drivers | ||
686 | # | ||
687 | # CONFIG_USB_EMI62 is not set | ||
688 | # CONFIG_USB_EMI26 is not set | ||
689 | # CONFIG_USB_ADUTUX is not set | ||
690 | # CONFIG_USB_SEVSEG is not set | ||
691 | # CONFIG_USB_RIO500 is not set | ||
692 | # CONFIG_USB_LEGOTOWER is not set | ||
693 | # CONFIG_USB_LCD is not set | ||
694 | # CONFIG_USB_BERRY_CHARGE is not set | ||
695 | # CONFIG_USB_LED is not set | ||
696 | # CONFIG_USB_CYPRESS_CY7C63 is not set | ||
697 | # CONFIG_USB_CYTHERM is not set | ||
698 | # CONFIG_USB_IDMOUSE is not set | ||
699 | # CONFIG_USB_FTDI_ELAN is not set | ||
700 | # CONFIG_USB_APPLEDISPLAY is not set | ||
701 | # CONFIG_USB_LD is not set | ||
702 | # CONFIG_USB_TRANCEVIBRATOR is not set | ||
703 | # CONFIG_USB_IOWARRIOR is not set | ||
704 | # CONFIG_USB_TEST is not set | ||
705 | # CONFIG_USB_ISIGHTFW is not set | ||
706 | # CONFIG_USB_VST is not set | ||
707 | # CONFIG_USB_GADGET is not set | ||
708 | |||
709 | # | ||
710 | # OTG and related infrastructure | ||
711 | # | ||
712 | # CONFIG_USB_GPIO_VBUS is not set | ||
713 | # CONFIG_NOP_USB_XCEIV is not set | ||
714 | # CONFIG_MMC is not set | ||
715 | # CONFIG_MEMSTICK is not set | ||
716 | # CONFIG_NEW_LEDS is not set | ||
717 | # CONFIG_ACCESSIBILITY is not set | ||
718 | CONFIG_RTC_LIB=y | ||
719 | # CONFIG_RTC_CLASS is not set | ||
720 | # CONFIG_DMADEVICES is not set | ||
721 | # CONFIG_AUXDISPLAY is not set | ||
722 | # CONFIG_UIO is not set | ||
723 | |||
724 | # | ||
725 | # TI VLYNQ | ||
726 | # | ||
727 | # CONFIG_STAGING is not set | ||
728 | |||
729 | # | ||
730 | # File systems | ||
731 | # | ||
732 | # CONFIG_EXT2_FS is not set | ||
733 | # CONFIG_EXT3_FS is not set | ||
734 | # CONFIG_EXT4_FS is not set | ||
735 | # CONFIG_REISERFS_FS is not set | ||
736 | # CONFIG_JFS_FS is not set | ||
737 | CONFIG_FS_POSIX_ACL=y | ||
738 | # CONFIG_XFS_FS is not set | ||
739 | # CONFIG_GFS2_FS is not set | ||
740 | # CONFIG_BTRFS_FS is not set | ||
741 | # CONFIG_NILFS2_FS is not set | ||
742 | CONFIG_FILE_LOCKING=y | ||
743 | CONFIG_FSNOTIFY=y | ||
744 | # CONFIG_DNOTIFY is not set | ||
745 | # CONFIG_INOTIFY is not set | ||
746 | CONFIG_INOTIFY_USER=y | ||
747 | # CONFIG_QUOTA is not set | ||
748 | # CONFIG_AUTOFS_FS is not set | ||
749 | # CONFIG_AUTOFS4_FS is not set | ||
750 | # CONFIG_FUSE_FS is not set | ||
751 | CONFIG_GENERIC_ACL=y | ||
752 | |||
753 | # | ||
754 | # Caches | ||
755 | # | ||
756 | # CONFIG_FSCACHE is not set | ||
757 | |||
758 | # | ||
759 | # CD-ROM/DVD Filesystems | ||
760 | # | ||
761 | # CONFIG_ISO9660_FS is not set | ||
762 | # CONFIG_UDF_FS is not set | ||
763 | |||
764 | # | ||
765 | # DOS/FAT/NT Filesystems | ||
766 | # | ||
767 | # CONFIG_MSDOS_FS is not set | ||
768 | # CONFIG_VFAT_FS is not set | ||
769 | # CONFIG_NTFS_FS is not set | ||
770 | |||
771 | # | ||
772 | # Pseudo filesystems | ||
773 | # | ||
774 | CONFIG_PROC_FS=y | ||
775 | CONFIG_PROC_SYSCTL=y | ||
776 | CONFIG_PROC_PAGE_MONITOR=y | ||
777 | CONFIG_SYSFS=y | ||
778 | CONFIG_TMPFS=y | ||
779 | CONFIG_TMPFS_POSIX_ACL=y | ||
780 | # CONFIG_HUGETLB_PAGE is not set | ||
781 | # CONFIG_CONFIGFS_FS is not set | ||
782 | CONFIG_MISC_FILESYSTEMS=y | ||
783 | # CONFIG_ADFS_FS is not set | ||
784 | # CONFIG_AFFS_FS is not set | ||
785 | # CONFIG_HFS_FS is not set | ||
786 | # CONFIG_HFSPLUS_FS is not set | ||
787 | # CONFIG_BEFS_FS is not set | ||
788 | # CONFIG_BFS_FS is not set | ||
789 | # CONFIG_EFS_FS is not set | ||
790 | # CONFIG_JFFS2_FS is not set | ||
791 | # CONFIG_CRAMFS is not set | ||
792 | # CONFIG_SQUASHFS is not set | ||
793 | # CONFIG_VXFS_FS is not set | ||
794 | # CONFIG_MINIX_FS is not set | ||
795 | # CONFIG_OMFS_FS is not set | ||
796 | # CONFIG_HPFS_FS is not set | ||
797 | # CONFIG_QNX4FS_FS is not set | ||
798 | CONFIG_ROMFS_FS=y | ||
799 | CONFIG_ROMFS_BACKED_BY_BLOCK=y | ||
800 | # CONFIG_ROMFS_BACKED_BY_MTD is not set | ||
801 | # CONFIG_ROMFS_BACKED_BY_BOTH is not set | ||
802 | CONFIG_ROMFS_ON_BLOCK=y | ||
803 | # CONFIG_SYSV_FS is not set | ||
804 | # CONFIG_UFS_FS is not set | ||
805 | |||
806 | # | ||
807 | # Partition Types | ||
808 | # | ||
809 | CONFIG_PARTITION_ADVANCED=y | ||
810 | # CONFIG_ACORN_PARTITION is not set | ||
811 | # CONFIG_OSF_PARTITION is not set | ||
812 | # CONFIG_AMIGA_PARTITION is not set | ||
813 | # CONFIG_ATARI_PARTITION is not set | ||
814 | # CONFIG_MAC_PARTITION is not set | ||
815 | CONFIG_MSDOS_PARTITION=y | ||
816 | # CONFIG_BSD_DISKLABEL is not set | ||
817 | # CONFIG_MINIX_SUBPARTITION is not set | ||
818 | # CONFIG_SOLARIS_X86_PARTITION is not set | ||
819 | # CONFIG_UNIXWARE_DISKLABEL is not set | ||
820 | # CONFIG_LDM_PARTITION is not set | ||
821 | # CONFIG_SGI_PARTITION is not set | ||
822 | # CONFIG_ULTRIX_PARTITION is not set | ||
823 | # CONFIG_SUN_PARTITION is not set | ||
824 | # CONFIG_KARMA_PARTITION is not set | ||
825 | # CONFIG_EFI_PARTITION is not set | ||
826 | # CONFIG_SYSV68_PARTITION is not set | ||
827 | CONFIG_NLS=y | ||
828 | CONFIG_NLS_DEFAULT="iso8859-1" | ||
829 | CONFIG_NLS_CODEPAGE_437=y | ||
830 | # CONFIG_NLS_CODEPAGE_737 is not set | ||
831 | # CONFIG_NLS_CODEPAGE_775 is not set | ||
832 | # CONFIG_NLS_CODEPAGE_850 is not set | ||
833 | # CONFIG_NLS_CODEPAGE_852 is not set | ||
834 | # CONFIG_NLS_CODEPAGE_855 is not set | ||
835 | # CONFIG_NLS_CODEPAGE_857 is not set | ||
836 | # CONFIG_NLS_CODEPAGE_860 is not set | ||
837 | # CONFIG_NLS_CODEPAGE_861 is not set | ||
838 | # CONFIG_NLS_CODEPAGE_862 is not set | ||
839 | # CONFIG_NLS_CODEPAGE_863 is not set | ||
840 | # CONFIG_NLS_CODEPAGE_864 is not set | ||
841 | # CONFIG_NLS_CODEPAGE_865 is not set | ||
842 | # CONFIG_NLS_CODEPAGE_866 is not set | ||
843 | # CONFIG_NLS_CODEPAGE_869 is not set | ||
844 | # CONFIG_NLS_CODEPAGE_936 is not set | ||
845 | # CONFIG_NLS_CODEPAGE_950 is not set | ||
846 | # CONFIG_NLS_CODEPAGE_932 is not set | ||
847 | # CONFIG_NLS_CODEPAGE_949 is not set | ||
848 | # CONFIG_NLS_CODEPAGE_874 is not set | ||
849 | # CONFIG_NLS_ISO8859_8 is not set | ||
850 | # CONFIG_NLS_CODEPAGE_1250 is not set | ||
851 | # CONFIG_NLS_CODEPAGE_1251 is not set | ||
852 | # CONFIG_NLS_ASCII is not set | ||
853 | CONFIG_NLS_ISO8859_1=y | ||
854 | # CONFIG_NLS_ISO8859_2 is not set | ||
855 | # CONFIG_NLS_ISO8859_3 is not set | ||
856 | # CONFIG_NLS_ISO8859_4 is not set | ||
857 | # CONFIG_NLS_ISO8859_5 is not set | ||
858 | # CONFIG_NLS_ISO8859_6 is not set | ||
859 | # CONFIG_NLS_ISO8859_7 is not set | ||
860 | # CONFIG_NLS_ISO8859_9 is not set | ||
861 | # CONFIG_NLS_ISO8859_13 is not set | ||
862 | # CONFIG_NLS_ISO8859_14 is not set | ||
863 | # CONFIG_NLS_ISO8859_15 is not set | ||
864 | # CONFIG_NLS_KOI8_R is not set | ||
865 | # CONFIG_NLS_KOI8_U is not set | ||
866 | # CONFIG_NLS_UTF8 is not set | ||
867 | |||
868 | # | ||
869 | # Kernel hacking | ||
870 | # | ||
871 | # CONFIG_PRINTK_TIME is not set | ||
872 | # CONFIG_ENABLE_WARN_DEPRECATED is not set | ||
873 | # CONFIG_ENABLE_MUST_CHECK is not set | ||
874 | CONFIG_FRAME_WARN=1024 | ||
875 | # CONFIG_MAGIC_SYSRQ is not set | ||
876 | # CONFIG_STRIP_ASM_SYMS is not set | ||
877 | # CONFIG_UNUSED_SYMBOLS is not set | ||
878 | CONFIG_DEBUG_FS=y | ||
879 | # CONFIG_HEADERS_CHECK is not set | ||
880 | # CONFIG_DEBUG_KERNEL is not set | ||
881 | CONFIG_DEBUG_BUGVERBOSE=y | ||
882 | CONFIG_DEBUG_MEMORY_INIT=y | ||
883 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
884 | # CONFIG_LATENCYTOP is not set | ||
885 | # CONFIG_SYSCTL_SYSCALL_CHECK is not set | ||
886 | CONFIG_HAVE_FUNCTION_TRACER=y | ||
887 | CONFIG_TRACING_SUPPORT=y | ||
888 | # CONFIG_FTRACE is not set | ||
889 | # CONFIG_DYNAMIC_DEBUG is not set | ||
890 | # CONFIG_SAMPLES is not set | ||
891 | CONFIG_HAVE_ARCH_KGDB=y | ||
892 | CONFIG_ARM_UNWIND=y | ||
893 | # CONFIG_DEBUG_USER is not set | ||
894 | |||
895 | # | ||
896 | # Security options | ||
897 | # | ||
898 | # CONFIG_KEYS is not set | ||
899 | # CONFIG_SECURITY is not set | ||
900 | # CONFIG_SECURITYFS is not set | ||
901 | # CONFIG_SECURITY_FILE_CAPABILITIES is not set | ||
902 | # CONFIG_CRYPTO is not set | ||
903 | # CONFIG_BINARY_PRINTF is not set | ||
904 | |||
905 | # | ||
906 | # Library routines | ||
907 | # | ||
908 | CONFIG_GENERIC_FIND_LAST_BIT=y | ||
909 | # CONFIG_CRC_CCITT is not set | ||
910 | # CONFIG_CRC16 is not set | ||
911 | # CONFIG_CRC_T10DIF is not set | ||
912 | # CONFIG_CRC_ITU_T is not set | ||
913 | # CONFIG_CRC32 is not set | ||
914 | # CONFIG_CRC7 is not set | ||
915 | # CONFIG_LIBCRC32C is not set | ||
916 | CONFIG_ZLIB_INFLATE=y | ||
917 | CONFIG_DECOMPRESS_GZIP=y | ||
918 | CONFIG_DECOMPRESS_BZIP2=y | ||
919 | CONFIG_DECOMPRESS_LZMA=y | ||
920 | CONFIG_HAS_IOMEM=y | ||
921 | CONFIG_HAS_IOPORT=y | ||
922 | CONFIG_HAS_DMA=y | ||
diff --git a/arch/arm/configs/nuc960_defconfig b/arch/arm/configs/nuc960_defconfig new file mode 100644 index 000000000000..4b2cd9eae9bc --- /dev/null +++ b/arch/arm/configs/nuc960_defconfig | |||
@@ -0,0 +1,922 @@ | |||
1 | # | ||
2 | # Automatically generated make config: don't edit | ||
3 | # Linux kernel version: 2.6.32-rc7 | ||
4 | # Tue Nov 17 12:20:11 2009 | ||
5 | # | ||
6 | CONFIG_ARM=y | ||
7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y | ||
8 | CONFIG_GENERIC_GPIO=y | ||
9 | CONFIG_GENERIC_TIME=y | ||
10 | CONFIG_GENERIC_CLOCKEVENTS=y | ||
11 | CONFIG_GENERIC_HARDIRQS=y | ||
12 | CONFIG_STACKTRACE_SUPPORT=y | ||
13 | CONFIG_HAVE_LATENCYTOP_SUPPORT=y | ||
14 | CONFIG_LOCKDEP_SUPPORT=y | ||
15 | CONFIG_TRACE_IRQFLAGS_SUPPORT=y | ||
16 | CONFIG_HARDIRQS_SW_RESEND=y | ||
17 | CONFIG_GENERIC_IRQ_PROBE=y | ||
18 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
19 | CONFIG_GENERIC_HWEIGHT=y | ||
20 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
21 | CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y | ||
22 | CONFIG_VECTORS_BASE=0xffff0000 | ||
23 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
24 | CONFIG_CONSTRUCTORS=y | ||
25 | |||
26 | # | ||
27 | # General setup | ||
28 | # | ||
29 | CONFIG_EXPERIMENTAL=y | ||
30 | CONFIG_BROKEN_ON_SMP=y | ||
31 | CONFIG_LOCK_KERNEL=y | ||
32 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
33 | CONFIG_LOCALVERSION="" | ||
34 | # CONFIG_LOCALVERSION_AUTO is not set | ||
35 | CONFIG_SWAP=y | ||
36 | CONFIG_SYSVIPC=y | ||
37 | CONFIG_SYSVIPC_SYSCTL=y | ||
38 | CONFIG_BSD_PROCESS_ACCT=y | ||
39 | # CONFIG_BSD_PROCESS_ACCT_V3 is not set | ||
40 | |||
41 | # | ||
42 | # RCU Subsystem | ||
43 | # | ||
44 | CONFIG_TREE_RCU=y | ||
45 | # CONFIG_TREE_PREEMPT_RCU is not set | ||
46 | # CONFIG_RCU_TRACE is not set | ||
47 | CONFIG_RCU_FANOUT=32 | ||
48 | # CONFIG_RCU_FANOUT_EXACT is not set | ||
49 | # CONFIG_TREE_RCU_TRACE is not set | ||
50 | # CONFIG_IKCONFIG is not set | ||
51 | CONFIG_LOG_BUF_SHIFT=17 | ||
52 | # CONFIG_GROUP_SCHED is not set | ||
53 | # CONFIG_CGROUPS is not set | ||
54 | CONFIG_SYSFS_DEPRECATED=y | ||
55 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
56 | CONFIG_RELAY=y | ||
57 | CONFIG_NAMESPACES=y | ||
58 | # CONFIG_UTS_NS is not set | ||
59 | # CONFIG_IPC_NS is not set | ||
60 | CONFIG_USER_NS=y | ||
61 | # CONFIG_PID_NS is not set | ||
62 | CONFIG_BLK_DEV_INITRD=y | ||
63 | CONFIG_INITRAMFS_SOURCE="" | ||
64 | CONFIG_RD_GZIP=y | ||
65 | CONFIG_RD_BZIP2=y | ||
66 | CONFIG_RD_LZMA=y | ||
67 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
68 | CONFIG_SYSCTL=y | ||
69 | CONFIG_ANON_INODES=y | ||
70 | # CONFIG_EMBEDDED is not set | ||
71 | CONFIG_UID16=y | ||
72 | CONFIG_SYSCTL_SYSCALL=y | ||
73 | CONFIG_KALLSYMS=y | ||
74 | CONFIG_KALLSYMS_EXTRA_PASS=y | ||
75 | CONFIG_HOTPLUG=y | ||
76 | CONFIG_PRINTK=y | ||
77 | CONFIG_BUG=y | ||
78 | CONFIG_ELF_CORE=y | ||
79 | CONFIG_BASE_FULL=y | ||
80 | CONFIG_FUTEX=y | ||
81 | CONFIG_EPOLL=y | ||
82 | CONFIG_SIGNALFD=y | ||
83 | CONFIG_TIMERFD=y | ||
84 | CONFIG_EVENTFD=y | ||
85 | CONFIG_SHMEM=y | ||
86 | CONFIG_AIO=y | ||
87 | |||
88 | # | ||
89 | # Kernel Performance Events And Counters | ||
90 | # | ||
91 | CONFIG_VM_EVENT_COUNTERS=y | ||
92 | CONFIG_COMPAT_BRK=y | ||
93 | CONFIG_SLAB=y | ||
94 | # CONFIG_SLUB is not set | ||
95 | # CONFIG_SLOB is not set | ||
96 | # CONFIG_PROFILING is not set | ||
97 | CONFIG_HAVE_OPROFILE=y | ||
98 | CONFIG_HAVE_KPROBES=y | ||
99 | CONFIG_HAVE_KRETPROBES=y | ||
100 | CONFIG_HAVE_CLK=y | ||
101 | |||
102 | # | ||
103 | # GCOV-based kernel profiling | ||
104 | # | ||
105 | # CONFIG_GCOV_KERNEL is not set | ||
106 | # CONFIG_SLOW_WORK is not set | ||
107 | CONFIG_HAVE_GENERIC_DMA_COHERENT=y | ||
108 | CONFIG_SLABINFO=y | ||
109 | CONFIG_RT_MUTEXES=y | ||
110 | CONFIG_BASE_SMALL=0 | ||
111 | # CONFIG_MODULES is not set | ||
112 | CONFIG_BLOCK=y | ||
113 | CONFIG_LBDAF=y | ||
114 | CONFIG_BLK_DEV_BSG=y | ||
115 | # CONFIG_BLK_DEV_INTEGRITY is not set | ||
116 | |||
117 | # | ||
118 | # IO Schedulers | ||
119 | # | ||
120 | CONFIG_IOSCHED_NOOP=y | ||
121 | CONFIG_IOSCHED_AS=y | ||
122 | CONFIG_IOSCHED_DEADLINE=y | ||
123 | CONFIG_IOSCHED_CFQ=y | ||
124 | # CONFIG_DEFAULT_AS is not set | ||
125 | # CONFIG_DEFAULT_DEADLINE is not set | ||
126 | CONFIG_DEFAULT_CFQ=y | ||
127 | # CONFIG_DEFAULT_NOOP is not set | ||
128 | CONFIG_DEFAULT_IOSCHED="cfq" | ||
129 | # CONFIG_FREEZER is not set | ||
130 | |||
131 | # | ||
132 | # System Type | ||
133 | # | ||
134 | CONFIG_MMU=y | ||
135 | # CONFIG_ARCH_AAEC2000 is not set | ||
136 | # CONFIG_ARCH_INTEGRATOR is not set | ||
137 | # CONFIG_ARCH_REALVIEW is not set | ||
138 | # CONFIG_ARCH_VERSATILE is not set | ||
139 | # CONFIG_ARCH_AT91 is not set | ||
140 | # CONFIG_ARCH_CLPS711X is not set | ||
141 | # CONFIG_ARCH_GEMINI is not set | ||
142 | # CONFIG_ARCH_EBSA110 is not set | ||
143 | # CONFIG_ARCH_EP93XX is not set | ||
144 | # CONFIG_ARCH_FOOTBRIDGE is not set | ||
145 | # CONFIG_ARCH_MXC is not set | ||
146 | # CONFIG_ARCH_STMP3XXX is not set | ||
147 | # CONFIG_ARCH_NETX is not set | ||
148 | # CONFIG_ARCH_H720X is not set | ||
149 | # CONFIG_ARCH_NOMADIK is not set | ||
150 | # CONFIG_ARCH_IOP13XX is not set | ||
151 | # CONFIG_ARCH_IOP32X is not set | ||
152 | # CONFIG_ARCH_IOP33X is not set | ||
153 | # CONFIG_ARCH_IXP23XX is not set | ||
154 | # CONFIG_ARCH_IXP2000 is not set | ||
155 | # CONFIG_ARCH_IXP4XX is not set | ||
156 | # CONFIG_ARCH_L7200 is not set | ||
157 | # CONFIG_ARCH_KIRKWOOD is not set | ||
158 | # CONFIG_ARCH_LOKI is not set | ||
159 | # CONFIG_ARCH_MV78XX0 is not set | ||
160 | # CONFIG_ARCH_ORION5X is not set | ||
161 | # CONFIG_ARCH_MMP is not set | ||
162 | # CONFIG_ARCH_KS8695 is not set | ||
163 | # CONFIG_ARCH_NS9XXX is not set | ||
164 | CONFIG_ARCH_W90X900=y | ||
165 | # CONFIG_ARCH_PNX4008 is not set | ||
166 | # CONFIG_ARCH_PXA is not set | ||
167 | # CONFIG_ARCH_MSM is not set | ||
168 | # CONFIG_ARCH_RPC is not set | ||
169 | # CONFIG_ARCH_SA1100 is not set | ||
170 | # CONFIG_ARCH_S3C2410 is not set | ||
171 | # CONFIG_ARCH_S3C64XX is not set | ||
172 | # CONFIG_ARCH_S5PC1XX is not set | ||
173 | # CONFIG_ARCH_SHARK is not set | ||
174 | # CONFIG_ARCH_LH7A40X is not set | ||
175 | # CONFIG_ARCH_U300 is not set | ||
176 | # CONFIG_ARCH_DAVINCI is not set | ||
177 | # CONFIG_ARCH_OMAP is not set | ||
178 | # CONFIG_ARCH_BCMRING is not set | ||
179 | CONFIG_CPU_NUC960=y | ||
180 | |||
181 | # | ||
182 | # W90P910 Machines | ||
183 | # | ||
184 | # CONFIG_MACH_W90P910EVB is not set | ||
185 | |||
186 | # | ||
187 | # NUC950 Machines | ||
188 | # | ||
189 | # CONFIG_MACH_W90P950EVB is not set | ||
190 | |||
191 | # | ||
192 | # NUC960 Machines | ||
193 | # | ||
194 | CONFIG_MACH_W90N960EVB=y | ||
195 | |||
196 | # | ||
197 | # NUC932 Machines | ||
198 | # | ||
199 | # CONFIG_MACH_NUC932EVB is not set | ||
200 | |||
201 | # | ||
202 | # Processor Type | ||
203 | # | ||
204 | CONFIG_CPU_32=y | ||
205 | CONFIG_CPU_ARM926T=y | ||
206 | CONFIG_CPU_32v5=y | ||
207 | CONFIG_CPU_ABRT_EV5TJ=y | ||
208 | CONFIG_CPU_PABRT_LEGACY=y | ||
209 | CONFIG_CPU_CACHE_VIVT=y | ||
210 | CONFIG_CPU_COPY_V4WB=y | ||
211 | CONFIG_CPU_TLB_V4WBI=y | ||
212 | CONFIG_CPU_CP15=y | ||
213 | CONFIG_CPU_CP15_MMU=y | ||
214 | |||
215 | # | ||
216 | # Processor Features | ||
217 | # | ||
218 | CONFIG_ARM_THUMB=y | ||
219 | # CONFIG_CPU_ICACHE_DISABLE is not set | ||
220 | # CONFIG_CPU_DCACHE_DISABLE is not set | ||
221 | # CONFIG_CPU_DCACHE_WRITETHROUGH is not set | ||
222 | # CONFIG_CPU_CACHE_ROUND_ROBIN is not set | ||
223 | CONFIG_ARM_L1_CACHE_SHIFT=5 | ||
224 | CONFIG_COMMON_CLKDEV=y | ||
225 | |||
226 | # | ||
227 | # Bus support | ||
228 | # | ||
229 | # CONFIG_PCI_SYSCALL is not set | ||
230 | # CONFIG_ARCH_SUPPORTS_MSI is not set | ||
231 | # CONFIG_PCCARD is not set | ||
232 | |||
233 | # | ||
234 | # Kernel Features | ||
235 | # | ||
236 | CONFIG_TICK_ONESHOT=y | ||
237 | CONFIG_NO_HZ=y | ||
238 | CONFIG_HIGH_RES_TIMERS=y | ||
239 | CONFIG_GENERIC_CLOCKEVENTS_BUILD=y | ||
240 | CONFIG_VMSPLIT_3G=y | ||
241 | # CONFIG_VMSPLIT_2G is not set | ||
242 | # CONFIG_VMSPLIT_1G is not set | ||
243 | CONFIG_PAGE_OFFSET=0xC0000000 | ||
244 | # CONFIG_PREEMPT_NONE is not set | ||
245 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
246 | CONFIG_PREEMPT=y | ||
247 | CONFIG_HZ=100 | ||
248 | CONFIG_AEABI=y | ||
249 | CONFIG_OABI_COMPAT=y | ||
250 | # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set | ||
251 | # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set | ||
252 | # CONFIG_HIGHMEM is not set | ||
253 | CONFIG_SELECT_MEMORY_MODEL=y | ||
254 | CONFIG_FLATMEM_MANUAL=y | ||
255 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
256 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
257 | CONFIG_FLATMEM=y | ||
258 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
259 | CONFIG_PAGEFLAGS_EXTENDED=y | ||
260 | CONFIG_SPLIT_PTLOCK_CPUS=4096 | ||
261 | # CONFIG_PHYS_ADDR_T_64BIT is not set | ||
262 | CONFIG_ZONE_DMA_FLAG=0 | ||
263 | CONFIG_VIRT_TO_BUS=y | ||
264 | CONFIG_HAVE_MLOCK=y | ||
265 | CONFIG_HAVE_MLOCKED_PAGE_BIT=y | ||
266 | # CONFIG_KSM is not set | ||
267 | CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 | ||
268 | CONFIG_ALIGNMENT_TRAP=y | ||
269 | # CONFIG_UACCESS_WITH_MEMCPY is not set | ||
270 | |||
271 | # | ||
272 | # Boot options | ||
273 | # | ||
274 | CONFIG_ZBOOT_ROM_TEXT=0 | ||
275 | CONFIG_ZBOOT_ROM_BSS=0 | ||
276 | CONFIG_CMDLINE="root=/dev/ram0 console=ttyS0,115200n8 rdinit=/sbin/init mem=64M" | ||
277 | # CONFIG_XIP_KERNEL is not set | ||
278 | CONFIG_KEXEC=y | ||
279 | CONFIG_ATAGS_PROC=y | ||
280 | |||
281 | # | ||
282 | # CPU Power Management | ||
283 | # | ||
284 | # CONFIG_CPU_IDLE is not set | ||
285 | |||
286 | # | ||
287 | # Floating point emulation | ||
288 | # | ||
289 | |||
290 | # | ||
291 | # At least one emulation must be selected | ||
292 | # | ||
293 | CONFIG_FPE_NWFPE=y | ||
294 | # CONFIG_FPE_NWFPE_XP is not set | ||
295 | # CONFIG_FPE_FASTFPE is not set | ||
296 | # CONFIG_VFP is not set | ||
297 | |||
298 | # | ||
299 | # Userspace binary formats | ||
300 | # | ||
301 | CONFIG_BINFMT_ELF=y | ||
302 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
303 | CONFIG_HAVE_AOUT=y | ||
304 | CONFIG_BINFMT_AOUT=y | ||
305 | CONFIG_BINFMT_MISC=y | ||
306 | |||
307 | # | ||
308 | # Power management options | ||
309 | # | ||
310 | # CONFIG_PM is not set | ||
311 | CONFIG_ARCH_SUSPEND_POSSIBLE=y | ||
312 | # CONFIG_NET is not set | ||
313 | |||
314 | # | ||
315 | # Device Drivers | ||
316 | # | ||
317 | |||
318 | # | ||
319 | # Generic Driver Options | ||
320 | # | ||
321 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
322 | # CONFIG_DEVTMPFS is not set | ||
323 | CONFIG_STANDALONE=y | ||
324 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
325 | CONFIG_FW_LOADER=y | ||
326 | CONFIG_FIRMWARE_IN_KERNEL=y | ||
327 | CONFIG_EXTRA_FIRMWARE="" | ||
328 | # CONFIG_SYS_HYPERVISOR is not set | ||
329 | CONFIG_MTD=y | ||
330 | # CONFIG_MTD_DEBUG is not set | ||
331 | CONFIG_MTD_CONCAT=y | ||
332 | CONFIG_MTD_PARTITIONS=y | ||
333 | # CONFIG_MTD_REDBOOT_PARTS is not set | ||
334 | # CONFIG_MTD_CMDLINE_PARTS is not set | ||
335 | # CONFIG_MTD_AFS_PARTS is not set | ||
336 | # CONFIG_MTD_AR7_PARTS is not set | ||
337 | |||
338 | # | ||
339 | # User Modules And Translation Layers | ||
340 | # | ||
341 | CONFIG_MTD_CHAR=y | ||
342 | CONFIG_MTD_BLKDEVS=y | ||
343 | CONFIG_MTD_BLOCK=y | ||
344 | # CONFIG_FTL is not set | ||
345 | # CONFIG_NFTL is not set | ||
346 | # CONFIG_INFTL is not set | ||
347 | # CONFIG_RFD_FTL is not set | ||
348 | # CONFIG_SSFDC is not set | ||
349 | # CONFIG_MTD_OOPS is not set | ||
350 | |||
351 | # | ||
352 | # RAM/ROM/Flash chip drivers | ||
353 | # | ||
354 | CONFIG_MTD_CFI=y | ||
355 | # CONFIG_MTD_JEDECPROBE is not set | ||
356 | CONFIG_MTD_GEN_PROBE=y | ||
357 | # CONFIG_MTD_CFI_ADV_OPTIONS is not set | ||
358 | CONFIG_MTD_MAP_BANK_WIDTH_1=y | ||
359 | CONFIG_MTD_MAP_BANK_WIDTH_2=y | ||
360 | CONFIG_MTD_MAP_BANK_WIDTH_4=y | ||
361 | # CONFIG_MTD_MAP_BANK_WIDTH_8 is not set | ||
362 | # CONFIG_MTD_MAP_BANK_WIDTH_16 is not set | ||
363 | # CONFIG_MTD_MAP_BANK_WIDTH_32 is not set | ||
364 | CONFIG_MTD_CFI_I1=y | ||
365 | CONFIG_MTD_CFI_I2=y | ||
366 | # CONFIG_MTD_CFI_I4 is not set | ||
367 | # CONFIG_MTD_CFI_I8 is not set | ||
368 | # CONFIG_MTD_CFI_INTELEXT is not set | ||
369 | CONFIG_MTD_CFI_AMDSTD=y | ||
370 | # CONFIG_MTD_CFI_STAA is not set | ||
371 | CONFIG_MTD_CFI_UTIL=y | ||
372 | # CONFIG_MTD_RAM is not set | ||
373 | # CONFIG_MTD_ROM is not set | ||
374 | # CONFIG_MTD_ABSENT is not set | ||
375 | |||
376 | # | ||
377 | # Mapping drivers for chip access | ||
378 | # | ||
379 | # CONFIG_MTD_COMPLEX_MAPPINGS is not set | ||
380 | CONFIG_MTD_PHYSMAP=y | ||
381 | # CONFIG_MTD_PHYSMAP_COMPAT is not set | ||
382 | # CONFIG_MTD_ARM_INTEGRATOR is not set | ||
383 | # CONFIG_MTD_PLATRAM is not set | ||
384 | |||
385 | # | ||
386 | # Self-contained MTD device drivers | ||
387 | # | ||
388 | # CONFIG_MTD_SLRAM is not set | ||
389 | # CONFIG_MTD_PHRAM is not set | ||
390 | # CONFIG_MTD_MTDRAM is not set | ||
391 | # CONFIG_MTD_BLOCK2MTD is not set | ||
392 | |||
393 | # | ||
394 | # Disk-On-Chip Device Drivers | ||
395 | # | ||
396 | # CONFIG_MTD_DOC2000 is not set | ||
397 | # CONFIG_MTD_DOC2001 is not set | ||
398 | # CONFIG_MTD_DOC2001PLUS is not set | ||
399 | # CONFIG_MTD_NAND is not set | ||
400 | # CONFIG_MTD_ONENAND is not set | ||
401 | |||
402 | # | ||
403 | # LPDDR flash memory drivers | ||
404 | # | ||
405 | # CONFIG_MTD_LPDDR is not set | ||
406 | |||
407 | # | ||
408 | # UBI - Unsorted block images | ||
409 | # | ||
410 | # CONFIG_MTD_UBI is not set | ||
411 | # CONFIG_PARPORT is not set | ||
412 | CONFIG_BLK_DEV=y | ||
413 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
414 | # CONFIG_BLK_DEV_LOOP is not set | ||
415 | # CONFIG_BLK_DEV_UB is not set | ||
416 | CONFIG_BLK_DEV_RAM=y | ||
417 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
418 | CONFIG_BLK_DEV_RAM_SIZE=16384 | ||
419 | # CONFIG_BLK_DEV_XIP is not set | ||
420 | # CONFIG_CDROM_PKTCDVD is not set | ||
421 | # CONFIG_MG_DISK is not set | ||
422 | # CONFIG_MISC_DEVICES is not set | ||
423 | CONFIG_HAVE_IDE=y | ||
424 | # CONFIG_IDE is not set | ||
425 | |||
426 | # | ||
427 | # SCSI device support | ||
428 | # | ||
429 | # CONFIG_RAID_ATTRS is not set | ||
430 | CONFIG_SCSI=y | ||
431 | CONFIG_SCSI_DMA=y | ||
432 | # CONFIG_SCSI_TGT is not set | ||
433 | # CONFIG_SCSI_NETLINK is not set | ||
434 | # CONFIG_SCSI_PROC_FS is not set | ||
435 | |||
436 | # | ||
437 | # SCSI support type (disk, tape, CD-ROM) | ||
438 | # | ||
439 | CONFIG_BLK_DEV_SD=y | ||
440 | # CONFIG_CHR_DEV_ST is not set | ||
441 | # CONFIG_CHR_DEV_OSST is not set | ||
442 | # CONFIG_BLK_DEV_SR is not set | ||
443 | # CONFIG_CHR_DEV_SG is not set | ||
444 | # CONFIG_CHR_DEV_SCH is not set | ||
445 | # CONFIG_SCSI_MULTI_LUN is not set | ||
446 | # CONFIG_SCSI_CONSTANTS is not set | ||
447 | # CONFIG_SCSI_LOGGING is not set | ||
448 | # CONFIG_SCSI_SCAN_ASYNC is not set | ||
449 | |||
450 | # | ||
451 | # SCSI Transports | ||
452 | # | ||
453 | # CONFIG_SCSI_SPI_ATTRS is not set | ||
454 | # CONFIG_SCSI_FC_ATTRS is not set | ||
455 | # CONFIG_SCSI_SAS_ATTRS is not set | ||
456 | # CONFIG_SCSI_SAS_LIBSAS is not set | ||
457 | # CONFIG_SCSI_SRP_ATTRS is not set | ||
458 | # CONFIG_SCSI_LOWLEVEL is not set | ||
459 | # CONFIG_SCSI_DH is not set | ||
460 | # CONFIG_SCSI_OSD_INITIATOR is not set | ||
461 | # CONFIG_ATA is not set | ||
462 | # CONFIG_MD is not set | ||
463 | # CONFIG_PHONE is not set | ||
464 | |||
465 | # | ||
466 | # Input device support | ||
467 | # | ||
468 | CONFIG_INPUT=y | ||
469 | # CONFIG_INPUT_FF_MEMLESS is not set | ||
470 | # CONFIG_INPUT_POLLDEV is not set | ||
471 | |||
472 | # | ||
473 | # Userland interfaces | ||
474 | # | ||
475 | CONFIG_INPUT_MOUSEDEV=y | ||
476 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set | ||
477 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | ||
478 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | ||
479 | # CONFIG_INPUT_JOYDEV is not set | ||
480 | # CONFIG_INPUT_EVDEV is not set | ||
481 | # CONFIG_INPUT_EVBUG is not set | ||
482 | |||
483 | # | ||
484 | # Input Device Drivers | ||
485 | # | ||
486 | # CONFIG_INPUT_KEYBOARD is not set | ||
487 | # CONFIG_INPUT_MOUSE is not set | ||
488 | # CONFIG_INPUT_JOYSTICK is not set | ||
489 | # CONFIG_INPUT_TABLET is not set | ||
490 | # CONFIG_INPUT_TOUCHSCREEN is not set | ||
491 | # CONFIG_INPUT_MISC is not set | ||
492 | |||
493 | # | ||
494 | # Hardware I/O ports | ||
495 | # | ||
496 | # CONFIG_SERIO is not set | ||
497 | # CONFIG_GAMEPORT is not set | ||
498 | |||
499 | # | ||
500 | # Character devices | ||
501 | # | ||
502 | CONFIG_VT=y | ||
503 | CONFIG_CONSOLE_TRANSLATIONS=y | ||
504 | CONFIG_VT_CONSOLE=y | ||
505 | CONFIG_HW_CONSOLE=y | ||
506 | # CONFIG_VT_HW_CONSOLE_BINDING is not set | ||
507 | # CONFIG_DEVKMEM is not set | ||
508 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
509 | |||
510 | # | ||
511 | # Serial drivers | ||
512 | # | ||
513 | CONFIG_SERIAL_8250=y | ||
514 | CONFIG_SERIAL_8250_CONSOLE=y | ||
515 | CONFIG_SERIAL_8250_NR_UARTS=1 | ||
516 | CONFIG_SERIAL_8250_RUNTIME_UARTS=1 | ||
517 | # CONFIG_SERIAL_8250_EXTENDED is not set | ||
518 | |||
519 | # | ||
520 | # Non-8250 serial port support | ||
521 | # | ||
522 | CONFIG_SERIAL_CORE=y | ||
523 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
524 | CONFIG_UNIX98_PTYS=y | ||
525 | # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set | ||
526 | # CONFIG_LEGACY_PTYS is not set | ||
527 | # CONFIG_IPMI_HANDLER is not set | ||
528 | # CONFIG_HW_RANDOM is not set | ||
529 | # CONFIG_R3964 is not set | ||
530 | # CONFIG_RAW_DRIVER is not set | ||
531 | # CONFIG_TCG_TPM is not set | ||
532 | # CONFIG_I2C is not set | ||
533 | # CONFIG_SPI is not set | ||
534 | |||
535 | # | ||
536 | # PPS support | ||
537 | # | ||
538 | # CONFIG_PPS is not set | ||
539 | CONFIG_ARCH_REQUIRE_GPIOLIB=y | ||
540 | CONFIG_GPIOLIB=y | ||
541 | # CONFIG_GPIO_SYSFS is not set | ||
542 | |||
543 | # | ||
544 | # Memory mapped GPIO expanders: | ||
545 | # | ||
546 | |||
547 | # | ||
548 | # I2C GPIO expanders: | ||
549 | # | ||
550 | |||
551 | # | ||
552 | # PCI GPIO expanders: | ||
553 | # | ||
554 | |||
555 | # | ||
556 | # SPI GPIO expanders: | ||
557 | # | ||
558 | |||
559 | # | ||
560 | # AC97 GPIO expanders: | ||
561 | # | ||
562 | # CONFIG_W1 is not set | ||
563 | # CONFIG_POWER_SUPPLY is not set | ||
564 | # CONFIG_HWMON is not set | ||
565 | # CONFIG_THERMAL is not set | ||
566 | # CONFIG_WATCHDOG is not set | ||
567 | CONFIG_SSB_POSSIBLE=y | ||
568 | |||
569 | # | ||
570 | # Sonics Silicon Backplane | ||
571 | # | ||
572 | # CONFIG_SSB is not set | ||
573 | |||
574 | # | ||
575 | # Multifunction device drivers | ||
576 | # | ||
577 | # CONFIG_MFD_CORE is not set | ||
578 | # CONFIG_MFD_SM501 is not set | ||
579 | # CONFIG_MFD_ASIC3 is not set | ||
580 | # CONFIG_HTC_EGPIO is not set | ||
581 | # CONFIG_HTC_PASIC3 is not set | ||
582 | # CONFIG_MFD_TMIO is not set | ||
583 | # CONFIG_MFD_T7L66XB is not set | ||
584 | # CONFIG_MFD_TC6387XB is not set | ||
585 | # CONFIG_MFD_TC6393XB is not set | ||
586 | # CONFIG_REGULATOR is not set | ||
587 | # CONFIG_MEDIA_SUPPORT is not set | ||
588 | |||
589 | # | ||
590 | # Graphics support | ||
591 | # | ||
592 | # CONFIG_VGASTATE is not set | ||
593 | # CONFIG_VIDEO_OUTPUT_CONTROL is not set | ||
594 | # CONFIG_FB is not set | ||
595 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
596 | |||
597 | # | ||
598 | # Display device support | ||
599 | # | ||
600 | # CONFIG_DISPLAY_SUPPORT is not set | ||
601 | |||
602 | # | ||
603 | # Console display driver support | ||
604 | # | ||
605 | # CONFIG_VGA_CONSOLE is not set | ||
606 | CONFIG_DUMMY_CONSOLE=y | ||
607 | # CONFIG_SOUND is not set | ||
608 | # CONFIG_HID_SUPPORT is not set | ||
609 | CONFIG_USB_SUPPORT=y | ||
610 | CONFIG_USB_ARCH_HAS_HCD=y | ||
611 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
612 | CONFIG_USB_ARCH_HAS_EHCI=y | ||
613 | CONFIG_USB=y | ||
614 | # CONFIG_USB_DEBUG is not set | ||
615 | # CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set | ||
616 | |||
617 | # | ||
618 | # Miscellaneous USB options | ||
619 | # | ||
620 | # CONFIG_USB_DEVICEFS is not set | ||
621 | CONFIG_USB_DEVICE_CLASS=y | ||
622 | # CONFIG_USB_DYNAMIC_MINORS is not set | ||
623 | # CONFIG_USB_OTG is not set | ||
624 | CONFIG_USB_MON=y | ||
625 | # CONFIG_USB_WUSB is not set | ||
626 | # CONFIG_USB_WUSB_CBAF is not set | ||
627 | |||
628 | # | ||
629 | # USB Host Controller Drivers | ||
630 | # | ||
631 | # CONFIG_USB_C67X00_HCD is not set | ||
632 | # CONFIG_USB_EHCI_HCD is not set | ||
633 | # CONFIG_USB_OXU210HP_HCD is not set | ||
634 | # CONFIG_USB_ISP116X_HCD is not set | ||
635 | # CONFIG_USB_ISP1760_HCD is not set | ||
636 | # CONFIG_USB_ISP1362_HCD is not set | ||
637 | # CONFIG_USB_OHCI_HCD is not set | ||
638 | # CONFIG_USB_SL811_HCD is not set | ||
639 | # CONFIG_USB_R8A66597_HCD is not set | ||
640 | # CONFIG_USB_HWA_HCD is not set | ||
641 | # CONFIG_USB_MUSB_HDRC is not set | ||
642 | |||
643 | # | ||
644 | # USB Device Class drivers | ||
645 | # | ||
646 | # CONFIG_USB_ACM is not set | ||
647 | # CONFIG_USB_PRINTER is not set | ||
648 | # CONFIG_USB_WDM is not set | ||
649 | # CONFIG_USB_TMC is not set | ||
650 | |||
651 | # | ||
652 | # NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may | ||
653 | # | ||
654 | |||
655 | # | ||
656 | # also be needed; see USB_STORAGE Help for more info | ||
657 | # | ||
658 | CONFIG_USB_STORAGE=y | ||
659 | # CONFIG_USB_STORAGE_DEBUG is not set | ||
660 | # CONFIG_USB_STORAGE_DATAFAB is not set | ||
661 | # CONFIG_USB_STORAGE_FREECOM is not set | ||
662 | # CONFIG_USB_STORAGE_ISD200 is not set | ||
663 | # CONFIG_USB_STORAGE_USBAT is not set | ||
664 | # CONFIG_USB_STORAGE_SDDR09 is not set | ||
665 | # CONFIG_USB_STORAGE_SDDR55 is not set | ||
666 | # CONFIG_USB_STORAGE_JUMPSHOT is not set | ||
667 | # CONFIG_USB_STORAGE_ALAUDA is not set | ||
668 | # CONFIG_USB_STORAGE_ONETOUCH is not set | ||
669 | # CONFIG_USB_STORAGE_KARMA is not set | ||
670 | # CONFIG_USB_STORAGE_CYPRESS_ATACB is not set | ||
671 | # CONFIG_USB_LIBUSUAL is not set | ||
672 | |||
673 | # | ||
674 | # USB Imaging devices | ||
675 | # | ||
676 | # CONFIG_USB_MDC800 is not set | ||
677 | # CONFIG_USB_MICROTEK is not set | ||
678 | |||
679 | # | ||
680 | # USB port drivers | ||
681 | # | ||
682 | # CONFIG_USB_SERIAL is not set | ||
683 | |||
684 | # | ||
685 | # USB Miscellaneous drivers | ||
686 | # | ||
687 | # CONFIG_USB_EMI62 is not set | ||
688 | # CONFIG_USB_EMI26 is not set | ||
689 | # CONFIG_USB_ADUTUX is not set | ||
690 | # CONFIG_USB_SEVSEG is not set | ||
691 | # CONFIG_USB_RIO500 is not set | ||
692 | # CONFIG_USB_LEGOTOWER is not set | ||
693 | # CONFIG_USB_LCD is not set | ||
694 | # CONFIG_USB_BERRY_CHARGE is not set | ||
695 | # CONFIG_USB_LED is not set | ||
696 | # CONFIG_USB_CYPRESS_CY7C63 is not set | ||
697 | # CONFIG_USB_CYTHERM is not set | ||
698 | # CONFIG_USB_IDMOUSE is not set | ||
699 | # CONFIG_USB_FTDI_ELAN is not set | ||
700 | # CONFIG_USB_APPLEDISPLAY is not set | ||
701 | # CONFIG_USB_LD is not set | ||
702 | # CONFIG_USB_TRANCEVIBRATOR is not set | ||
703 | # CONFIG_USB_IOWARRIOR is not set | ||
704 | # CONFIG_USB_TEST is not set | ||
705 | # CONFIG_USB_ISIGHTFW is not set | ||
706 | # CONFIG_USB_VST is not set | ||
707 | # CONFIG_USB_GADGET is not set | ||
708 | |||
709 | # | ||
710 | # OTG and related infrastructure | ||
711 | # | ||
712 | # CONFIG_USB_GPIO_VBUS is not set | ||
713 | # CONFIG_NOP_USB_XCEIV is not set | ||
714 | # CONFIG_MMC is not set | ||
715 | # CONFIG_MEMSTICK is not set | ||
716 | # CONFIG_NEW_LEDS is not set | ||
717 | # CONFIG_ACCESSIBILITY is not set | ||
718 | CONFIG_RTC_LIB=y | ||
719 | # CONFIG_RTC_CLASS is not set | ||
720 | # CONFIG_DMADEVICES is not set | ||
721 | # CONFIG_AUXDISPLAY is not set | ||
722 | # CONFIG_UIO is not set | ||
723 | |||
724 | # | ||
725 | # TI VLYNQ | ||
726 | # | ||
727 | # CONFIG_STAGING is not set | ||
728 | |||
729 | # | ||
730 | # File systems | ||
731 | # | ||
732 | # CONFIG_EXT2_FS is not set | ||
733 | # CONFIG_EXT3_FS is not set | ||
734 | # CONFIG_EXT4_FS is not set | ||
735 | # CONFIG_REISERFS_FS is not set | ||
736 | # CONFIG_JFS_FS is not set | ||
737 | CONFIG_FS_POSIX_ACL=y | ||
738 | # CONFIG_XFS_FS is not set | ||
739 | # CONFIG_GFS2_FS is not set | ||
740 | # CONFIG_BTRFS_FS is not set | ||
741 | # CONFIG_NILFS2_FS is not set | ||
742 | CONFIG_FILE_LOCKING=y | ||
743 | CONFIG_FSNOTIFY=y | ||
744 | # CONFIG_DNOTIFY is not set | ||
745 | # CONFIG_INOTIFY is not set | ||
746 | CONFIG_INOTIFY_USER=y | ||
747 | # CONFIG_QUOTA is not set | ||
748 | # CONFIG_AUTOFS_FS is not set | ||
749 | # CONFIG_AUTOFS4_FS is not set | ||
750 | # CONFIG_FUSE_FS is not set | ||
751 | CONFIG_GENERIC_ACL=y | ||
752 | |||
753 | # | ||
754 | # Caches | ||
755 | # | ||
756 | # CONFIG_FSCACHE is not set | ||
757 | |||
758 | # | ||
759 | # CD-ROM/DVD Filesystems | ||
760 | # | ||
761 | # CONFIG_ISO9660_FS is not set | ||
762 | # CONFIG_UDF_FS is not set | ||
763 | |||
764 | # | ||
765 | # DOS/FAT/NT Filesystems | ||
766 | # | ||
767 | # CONFIG_MSDOS_FS is not set | ||
768 | # CONFIG_VFAT_FS is not set | ||
769 | # CONFIG_NTFS_FS is not set | ||
770 | |||
771 | # | ||
772 | # Pseudo filesystems | ||
773 | # | ||
774 | CONFIG_PROC_FS=y | ||
775 | CONFIG_PROC_SYSCTL=y | ||
776 | CONFIG_PROC_PAGE_MONITOR=y | ||
777 | CONFIG_SYSFS=y | ||
778 | CONFIG_TMPFS=y | ||
779 | CONFIG_TMPFS_POSIX_ACL=y | ||
780 | # CONFIG_HUGETLB_PAGE is not set | ||
781 | # CONFIG_CONFIGFS_FS is not set | ||
782 | CONFIG_MISC_FILESYSTEMS=y | ||
783 | # CONFIG_ADFS_FS is not set | ||
784 | # CONFIG_AFFS_FS is not set | ||
785 | # CONFIG_HFS_FS is not set | ||
786 | # CONFIG_HFSPLUS_FS is not set | ||
787 | # CONFIG_BEFS_FS is not set | ||
788 | # CONFIG_BFS_FS is not set | ||
789 | # CONFIG_EFS_FS is not set | ||
790 | # CONFIG_JFFS2_FS is not set | ||
791 | # CONFIG_CRAMFS is not set | ||
792 | # CONFIG_SQUASHFS is not set | ||
793 | # CONFIG_VXFS_FS is not set | ||
794 | # CONFIG_MINIX_FS is not set | ||
795 | # CONFIG_OMFS_FS is not set | ||
796 | # CONFIG_HPFS_FS is not set | ||
797 | # CONFIG_QNX4FS_FS is not set | ||
798 | CONFIG_ROMFS_FS=y | ||
799 | CONFIG_ROMFS_BACKED_BY_BLOCK=y | ||
800 | # CONFIG_ROMFS_BACKED_BY_MTD is not set | ||
801 | # CONFIG_ROMFS_BACKED_BY_BOTH is not set | ||
802 | CONFIG_ROMFS_ON_BLOCK=y | ||
803 | # CONFIG_SYSV_FS is not set | ||
804 | # CONFIG_UFS_FS is not set | ||
805 | |||
806 | # | ||
807 | # Partition Types | ||
808 | # | ||
809 | CONFIG_PARTITION_ADVANCED=y | ||
810 | # CONFIG_ACORN_PARTITION is not set | ||
811 | # CONFIG_OSF_PARTITION is not set | ||
812 | # CONFIG_AMIGA_PARTITION is not set | ||
813 | # CONFIG_ATARI_PARTITION is not set | ||
814 | # CONFIG_MAC_PARTITION is not set | ||
815 | CONFIG_MSDOS_PARTITION=y | ||
816 | # CONFIG_BSD_DISKLABEL is not set | ||
817 | # CONFIG_MINIX_SUBPARTITION is not set | ||
818 | # CONFIG_SOLARIS_X86_PARTITION is not set | ||
819 | # CONFIG_UNIXWARE_DISKLABEL is not set | ||
820 | # CONFIG_LDM_PARTITION is not set | ||
821 | # CONFIG_SGI_PARTITION is not set | ||
822 | # CONFIG_ULTRIX_PARTITION is not set | ||
823 | # CONFIG_SUN_PARTITION is not set | ||
824 | # CONFIG_KARMA_PARTITION is not set | ||
825 | # CONFIG_EFI_PARTITION is not set | ||
826 | # CONFIG_SYSV68_PARTITION is not set | ||
827 | CONFIG_NLS=y | ||
828 | CONFIG_NLS_DEFAULT="iso8859-1" | ||
829 | CONFIG_NLS_CODEPAGE_437=y | ||
830 | # CONFIG_NLS_CODEPAGE_737 is not set | ||
831 | # CONFIG_NLS_CODEPAGE_775 is not set | ||
832 | # CONFIG_NLS_CODEPAGE_850 is not set | ||
833 | # CONFIG_NLS_CODEPAGE_852 is not set | ||
834 | # CONFIG_NLS_CODEPAGE_855 is not set | ||
835 | # CONFIG_NLS_CODEPAGE_857 is not set | ||
836 | # CONFIG_NLS_CODEPAGE_860 is not set | ||
837 | # CONFIG_NLS_CODEPAGE_861 is not set | ||
838 | # CONFIG_NLS_CODEPAGE_862 is not set | ||
839 | # CONFIG_NLS_CODEPAGE_863 is not set | ||
840 | # CONFIG_NLS_CODEPAGE_864 is not set | ||
841 | # CONFIG_NLS_CODEPAGE_865 is not set | ||
842 | # CONFIG_NLS_CODEPAGE_866 is not set | ||
843 | # CONFIG_NLS_CODEPAGE_869 is not set | ||
844 | # CONFIG_NLS_CODEPAGE_936 is not set | ||
845 | # CONFIG_NLS_CODEPAGE_950 is not set | ||
846 | # CONFIG_NLS_CODEPAGE_932 is not set | ||
847 | # CONFIG_NLS_CODEPAGE_949 is not set | ||
848 | # CONFIG_NLS_CODEPAGE_874 is not set | ||
849 | # CONFIG_NLS_ISO8859_8 is not set | ||
850 | # CONFIG_NLS_CODEPAGE_1250 is not set | ||
851 | # CONFIG_NLS_CODEPAGE_1251 is not set | ||
852 | # CONFIG_NLS_ASCII is not set | ||
853 | CONFIG_NLS_ISO8859_1=y | ||
854 | # CONFIG_NLS_ISO8859_2 is not set | ||
855 | # CONFIG_NLS_ISO8859_3 is not set | ||
856 | # CONFIG_NLS_ISO8859_4 is not set | ||
857 | # CONFIG_NLS_ISO8859_5 is not set | ||
858 | # CONFIG_NLS_ISO8859_6 is not set | ||
859 | # CONFIG_NLS_ISO8859_7 is not set | ||
860 | # CONFIG_NLS_ISO8859_9 is not set | ||
861 | # CONFIG_NLS_ISO8859_13 is not set | ||
862 | # CONFIG_NLS_ISO8859_14 is not set | ||
863 | # CONFIG_NLS_ISO8859_15 is not set | ||
864 | # CONFIG_NLS_KOI8_R is not set | ||
865 | # CONFIG_NLS_KOI8_U is not set | ||
866 | # CONFIG_NLS_UTF8 is not set | ||
867 | |||
868 | # | ||
869 | # Kernel hacking | ||
870 | # | ||
871 | # CONFIG_PRINTK_TIME is not set | ||
872 | # CONFIG_ENABLE_WARN_DEPRECATED is not set | ||
873 | # CONFIG_ENABLE_MUST_CHECK is not set | ||
874 | CONFIG_FRAME_WARN=1024 | ||
875 | # CONFIG_MAGIC_SYSRQ is not set | ||
876 | # CONFIG_STRIP_ASM_SYMS is not set | ||
877 | # CONFIG_UNUSED_SYMBOLS is not set | ||
878 | CONFIG_DEBUG_FS=y | ||
879 | # CONFIG_HEADERS_CHECK is not set | ||
880 | # CONFIG_DEBUG_KERNEL is not set | ||
881 | CONFIG_DEBUG_BUGVERBOSE=y | ||
882 | CONFIG_DEBUG_MEMORY_INIT=y | ||
883 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
884 | # CONFIG_LATENCYTOP is not set | ||
885 | # CONFIG_SYSCTL_SYSCALL_CHECK is not set | ||
886 | CONFIG_HAVE_FUNCTION_TRACER=y | ||
887 | CONFIG_TRACING_SUPPORT=y | ||
888 | # CONFIG_FTRACE is not set | ||
889 | # CONFIG_DYNAMIC_DEBUG is not set | ||
890 | # CONFIG_SAMPLES is not set | ||
891 | CONFIG_HAVE_ARCH_KGDB=y | ||
892 | CONFIG_ARM_UNWIND=y | ||
893 | # CONFIG_DEBUG_USER is not set | ||
894 | |||
895 | # | ||
896 | # Security options | ||
897 | # | ||
898 | # CONFIG_KEYS is not set | ||
899 | # CONFIG_SECURITY is not set | ||
900 | # CONFIG_SECURITYFS is not set | ||
901 | # CONFIG_SECURITY_FILE_CAPABILITIES is not set | ||
902 | # CONFIG_CRYPTO is not set | ||
903 | # CONFIG_BINARY_PRINTF is not set | ||
904 | |||
905 | # | ||
906 | # Library routines | ||
907 | # | ||
908 | CONFIG_GENERIC_FIND_LAST_BIT=y | ||
909 | # CONFIG_CRC_CCITT is not set | ||
910 | # CONFIG_CRC16 is not set | ||
911 | # CONFIG_CRC_T10DIF is not set | ||
912 | # CONFIG_CRC_ITU_T is not set | ||
913 | # CONFIG_CRC32 is not set | ||
914 | # CONFIG_CRC7 is not set | ||
915 | # CONFIG_LIBCRC32C is not set | ||
916 | CONFIG_ZLIB_INFLATE=y | ||
917 | CONFIG_DECOMPRESS_GZIP=y | ||
918 | CONFIG_DECOMPRESS_BZIP2=y | ||
919 | CONFIG_DECOMPRESS_LZMA=y | ||
920 | CONFIG_HAS_IOMEM=y | ||
921 | CONFIG_HAS_IOPORT=y | ||
922 | CONFIG_HAS_DMA=y | ||
diff --git a/arch/arm/configs/u8500_defconfig b/arch/arm/configs/u8500_defconfig new file mode 100644 index 000000000000..15fde22ce3f3 --- /dev/null +++ b/arch/arm/configs/u8500_defconfig | |||
@@ -0,0 +1,680 @@ | |||
1 | # | ||
2 | # Automatically generated make config: don't edit | ||
3 | # Linux kernel version: 2.6.32-rc8 | ||
4 | # Mon Nov 30 11:11:29 2009 | ||
5 | # | ||
6 | CONFIG_ARM=y | ||
7 | CONFIG_SYS_SUPPORTS_APM_EMULATION=y | ||
8 | CONFIG_GENERIC_TIME=y | ||
9 | CONFIG_GENERIC_CLOCKEVENTS=y | ||
10 | CONFIG_GENERIC_HARDIRQS=y | ||
11 | CONFIG_STACKTRACE_SUPPORT=y | ||
12 | CONFIG_LOCKDEP_SUPPORT=y | ||
13 | CONFIG_TRACE_IRQFLAGS_SUPPORT=y | ||
14 | CONFIG_HARDIRQS_SW_RESEND=y | ||
15 | CONFIG_GENERIC_IRQ_PROBE=y | ||
16 | CONFIG_GENERIC_LOCKBREAK=y | ||
17 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
18 | CONFIG_GENERIC_HWEIGHT=y | ||
19 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
20 | CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y | ||
21 | CONFIG_VECTORS_BASE=0xffff0000 | ||
22 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | ||
23 | CONFIG_CONSTRUCTORS=y | ||
24 | |||
25 | # | ||
26 | # General setup | ||
27 | # | ||
28 | CONFIG_EXPERIMENTAL=y | ||
29 | CONFIG_LOCK_KERNEL=y | ||
30 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
31 | CONFIG_LOCALVERSION="" | ||
32 | CONFIG_LOCALVERSION_AUTO=y | ||
33 | # CONFIG_SWAP is not set | ||
34 | CONFIG_SYSVIPC=y | ||
35 | CONFIG_SYSVIPC_SYSCTL=y | ||
36 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
37 | |||
38 | # | ||
39 | # RCU Subsystem | ||
40 | # | ||
41 | CONFIG_TREE_RCU=y | ||
42 | # CONFIG_TREE_PREEMPT_RCU is not set | ||
43 | # CONFIG_RCU_TRACE is not set | ||
44 | CONFIG_RCU_FANOUT=32 | ||
45 | # CONFIG_RCU_FANOUT_EXACT is not set | ||
46 | # CONFIG_TREE_RCU_TRACE is not set | ||
47 | # CONFIG_IKCONFIG is not set | ||
48 | CONFIG_LOG_BUF_SHIFT=17 | ||
49 | CONFIG_GROUP_SCHED=y | ||
50 | CONFIG_FAIR_GROUP_SCHED=y | ||
51 | CONFIG_RT_GROUP_SCHED=y | ||
52 | CONFIG_USER_SCHED=y | ||
53 | # CONFIG_CGROUP_SCHED is not set | ||
54 | # CONFIG_CGROUPS is not set | ||
55 | CONFIG_SYSFS_DEPRECATED=y | ||
56 | CONFIG_SYSFS_DEPRECATED_V2=y | ||
57 | # CONFIG_RELAY is not set | ||
58 | CONFIG_NAMESPACES=y | ||
59 | # CONFIG_UTS_NS is not set | ||
60 | # CONFIG_IPC_NS is not set | ||
61 | # CONFIG_USER_NS is not set | ||
62 | # CONFIG_PID_NS is not set | ||
63 | CONFIG_BLK_DEV_INITRD=y | ||
64 | CONFIG_INITRAMFS_SOURCE="" | ||
65 | CONFIG_RD_GZIP=y | ||
66 | CONFIG_RD_BZIP2=y | ||
67 | CONFIG_RD_LZMA=y | ||
68 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | ||
69 | CONFIG_SYSCTL=y | ||
70 | CONFIG_ANON_INODES=y | ||
71 | # CONFIG_EMBEDDED is not set | ||
72 | CONFIG_UID16=y | ||
73 | CONFIG_SYSCTL_SYSCALL=y | ||
74 | CONFIG_KALLSYMS=y | ||
75 | CONFIG_KALLSYMS_ALL=y | ||
76 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
77 | CONFIG_HOTPLUG=y | ||
78 | CONFIG_PRINTK=y | ||
79 | CONFIG_BUG=y | ||
80 | CONFIG_ELF_CORE=y | ||
81 | CONFIG_BASE_FULL=y | ||
82 | CONFIG_FUTEX=y | ||
83 | CONFIG_EPOLL=y | ||
84 | CONFIG_SIGNALFD=y | ||
85 | CONFIG_TIMERFD=y | ||
86 | CONFIG_EVENTFD=y | ||
87 | CONFIG_SHMEM=y | ||
88 | CONFIG_AIO=y | ||
89 | |||
90 | # | ||
91 | # Kernel Performance Events And Counters | ||
92 | # | ||
93 | CONFIG_VM_EVENT_COUNTERS=y | ||
94 | CONFIG_SLUB_DEBUG=y | ||
95 | CONFIG_COMPAT_BRK=y | ||
96 | # CONFIG_SLAB is not set | ||
97 | CONFIG_SLUB=y | ||
98 | # CONFIG_SLOB is not set | ||
99 | # CONFIG_PROFILING is not set | ||
100 | CONFIG_HAVE_OPROFILE=y | ||
101 | # CONFIG_KPROBES is not set | ||
102 | CONFIG_HAVE_KPROBES=y | ||
103 | CONFIG_HAVE_KRETPROBES=y | ||
104 | CONFIG_USE_GENERIC_SMP_HELPERS=y | ||
105 | |||
106 | # | ||
107 | # GCOV-based kernel profiling | ||
108 | # | ||
109 | # CONFIG_SLOW_WORK is not set | ||
110 | CONFIG_HAVE_GENERIC_DMA_COHERENT=y | ||
111 | CONFIG_SLABINFO=y | ||
112 | CONFIG_RT_MUTEXES=y | ||
113 | CONFIG_BASE_SMALL=0 | ||
114 | CONFIG_MODULES=y | ||
115 | # CONFIG_MODULE_FORCE_LOAD is not set | ||
116 | CONFIG_MODULE_UNLOAD=y | ||
117 | # CONFIG_MODULE_FORCE_UNLOAD is not set | ||
118 | # CONFIG_MODVERSIONS is not set | ||
119 | # CONFIG_MODULE_SRCVERSION_ALL is not set | ||
120 | CONFIG_STOP_MACHINE=y | ||
121 | CONFIG_BLOCK=y | ||
122 | # CONFIG_LBDAF is not set | ||
123 | # CONFIG_BLK_DEV_BSG is not set | ||
124 | # CONFIG_BLK_DEV_INTEGRITY is not set | ||
125 | |||
126 | # | ||
127 | # IO Schedulers | ||
128 | # | ||
129 | CONFIG_IOSCHED_NOOP=y | ||
130 | CONFIG_IOSCHED_AS=y | ||
131 | CONFIG_IOSCHED_DEADLINE=y | ||
132 | CONFIG_IOSCHED_CFQ=y | ||
133 | # CONFIG_DEFAULT_AS is not set | ||
134 | # CONFIG_DEFAULT_DEADLINE is not set | ||
135 | CONFIG_DEFAULT_CFQ=y | ||
136 | # CONFIG_DEFAULT_NOOP is not set | ||
137 | CONFIG_DEFAULT_IOSCHED="cfq" | ||
138 | # CONFIG_FREEZER is not set | ||
139 | |||
140 | # | ||
141 | # System Type | ||
142 | # | ||
143 | CONFIG_MMU=y | ||
144 | # CONFIG_ARCH_AAEC2000 is not set | ||
145 | # CONFIG_ARCH_INTEGRATOR is not set | ||
146 | # CONFIG_ARCH_REALVIEW is not set | ||
147 | # CONFIG_ARCH_VERSATILE is not set | ||
148 | # CONFIG_ARCH_AT91 is not set | ||
149 | # CONFIG_ARCH_CLPS711X is not set | ||
150 | # CONFIG_ARCH_GEMINI is not set | ||
151 | # CONFIG_ARCH_EBSA110 is not set | ||
152 | # CONFIG_ARCH_EP93XX is not set | ||
153 | # CONFIG_ARCH_FOOTBRIDGE is not set | ||
154 | # CONFIG_ARCH_MXC is not set | ||
155 | # CONFIG_ARCH_STMP3XXX is not set | ||
156 | # CONFIG_ARCH_NETX is not set | ||
157 | # CONFIG_ARCH_H720X is not set | ||
158 | # CONFIG_ARCH_NOMADIK is not set | ||
159 | # CONFIG_ARCH_IOP13XX is not set | ||
160 | # CONFIG_ARCH_IOP32X is not set | ||
161 | # CONFIG_ARCH_IOP33X is not set | ||
162 | # CONFIG_ARCH_IXP23XX is not set | ||
163 | # CONFIG_ARCH_IXP2000 is not set | ||
164 | # CONFIG_ARCH_IXP4XX is not set | ||
165 | # CONFIG_ARCH_L7200 is not set | ||
166 | # CONFIG_ARCH_KIRKWOOD is not set | ||
167 | # CONFIG_ARCH_LOKI is not set | ||
168 | # CONFIG_ARCH_MV78XX0 is not set | ||
169 | # CONFIG_ARCH_ORION5X is not set | ||
170 | # CONFIG_ARCH_MMP is not set | ||
171 | # CONFIG_ARCH_KS8695 is not set | ||
172 | # CONFIG_ARCH_NS9XXX is not set | ||
173 | # CONFIG_ARCH_W90X900 is not set | ||
174 | # CONFIG_ARCH_PNX4008 is not set | ||
175 | # CONFIG_ARCH_PXA is not set | ||
176 | # CONFIG_ARCH_MSM is not set | ||
177 | # CONFIG_ARCH_RPC is not set | ||
178 | # CONFIG_ARCH_SA1100 is not set | ||
179 | # CONFIG_ARCH_S3C2410 is not set | ||
180 | # CONFIG_ARCH_S3C64XX is not set | ||
181 | # CONFIG_ARCH_S5PC1XX is not set | ||
182 | # CONFIG_ARCH_SHARK is not set | ||
183 | # CONFIG_ARCH_LH7A40X is not set | ||
184 | # CONFIG_ARCH_U300 is not set | ||
185 | # CONFIG_ARCH_DAVINCI is not set | ||
186 | # CONFIG_ARCH_OMAP is not set | ||
187 | # CONFIG_ARCH_BCMRING is not set | ||
188 | CONFIG_ARCH_U8500=y | ||
189 | CONFIG_PLAT_NOMADIK=y | ||
190 | CONFIG_HAS_MTU=y | ||
191 | |||
192 | # | ||
193 | # ST-Ericsson platform type | ||
194 | # | ||
195 | |||
196 | # | ||
197 | # ST-Ericsson Multicore Mobile Platforms | ||
198 | # | ||
199 | CONFIG_MACH_U8500_MOP=y | ||
200 | |||
201 | # | ||
202 | # Processor Type | ||
203 | # | ||
204 | CONFIG_CPU_32=y | ||
205 | CONFIG_CPU_32v6K=y | ||
206 | CONFIG_CPU_V7=y | ||
207 | CONFIG_CPU_32v7=y | ||
208 | CONFIG_CPU_ABRT_EV7=y | ||
209 | CONFIG_CPU_PABRT_V7=y | ||
210 | CONFIG_CPU_CACHE_V7=y | ||
211 | CONFIG_CPU_CACHE_VIPT=y | ||
212 | CONFIG_CPU_COPY_V6=y | ||
213 | CONFIG_CPU_TLB_V7=y | ||
214 | CONFIG_CPU_HAS_ASID=y | ||
215 | CONFIG_CPU_CP15=y | ||
216 | CONFIG_CPU_CP15_MMU=y | ||
217 | |||
218 | # | ||
219 | # Processor Features | ||
220 | # | ||
221 | CONFIG_ARM_THUMB=y | ||
222 | # CONFIG_ARM_THUMBEE is not set | ||
223 | # CONFIG_CPU_ICACHE_DISABLE is not set | ||
224 | # CONFIG_CPU_DCACHE_DISABLE is not set | ||
225 | # CONFIG_CPU_BPREDICT_DISABLE is not set | ||
226 | CONFIG_HAS_TLS_REG=y | ||
227 | CONFIG_ARM_L1_CACHE_SHIFT=5 | ||
228 | # CONFIG_ARM_ERRATA_430973 is not set | ||
229 | # CONFIG_ARM_ERRATA_458693 is not set | ||
230 | # CONFIG_ARM_ERRATA_460075 is not set | ||
231 | CONFIG_ARM_GIC=y | ||
232 | CONFIG_COMMON_CLKDEV=y | ||
233 | |||
234 | # | ||
235 | # Bus support | ||
236 | # | ||
237 | CONFIG_ARM_AMBA=y | ||
238 | # CONFIG_PCI_SYSCALL is not set | ||
239 | # CONFIG_ARCH_SUPPORTS_MSI is not set | ||
240 | # CONFIG_PCCARD is not set | ||
241 | |||
242 | # | ||
243 | # Kernel Features | ||
244 | # | ||
245 | # CONFIG_NO_HZ is not set | ||
246 | # CONFIG_HIGH_RES_TIMERS is not set | ||
247 | CONFIG_GENERIC_CLOCKEVENTS_BUILD=y | ||
248 | CONFIG_SMP=y | ||
249 | CONFIG_HAVE_ARM_SCU=y | ||
250 | CONFIG_HAVE_ARM_TWD=y | ||
251 | CONFIG_VMSPLIT_3G=y | ||
252 | # CONFIG_VMSPLIT_2G is not set | ||
253 | # CONFIG_VMSPLIT_1G is not set | ||
254 | CONFIG_PAGE_OFFSET=0xC0000000 | ||
255 | CONFIG_NR_CPUS=2 | ||
256 | # CONFIG_HOTPLUG_CPU is not set | ||
257 | CONFIG_LOCAL_TIMERS=y | ||
258 | # CONFIG_PREEMPT_NONE is not set | ||
259 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
260 | CONFIG_PREEMPT=y | ||
261 | CONFIG_HZ=100 | ||
262 | # CONFIG_THUMB2_KERNEL is not set | ||
263 | CONFIG_AEABI=y | ||
264 | CONFIG_OABI_COMPAT=y | ||
265 | # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set | ||
266 | # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set | ||
267 | # CONFIG_HIGHMEM is not set | ||
268 | CONFIG_SELECT_MEMORY_MODEL=y | ||
269 | CONFIG_FLATMEM_MANUAL=y | ||
270 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
271 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
272 | CONFIG_FLATMEM=y | ||
273 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
274 | CONFIG_PAGEFLAGS_EXTENDED=y | ||
275 | CONFIG_SPLIT_PTLOCK_CPUS=4 | ||
276 | # CONFIG_PHYS_ADDR_T_64BIT is not set | ||
277 | CONFIG_ZONE_DMA_FLAG=0 | ||
278 | CONFIG_VIRT_TO_BUS=y | ||
279 | CONFIG_HAVE_MLOCK=y | ||
280 | CONFIG_HAVE_MLOCKED_PAGE_BIT=y | ||
281 | # CONFIG_KSM is not set | ||
282 | CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 | ||
283 | CONFIG_ALIGNMENT_TRAP=y | ||
284 | # CONFIG_UACCESS_WITH_MEMCPY is not set | ||
285 | |||
286 | # | ||
287 | # Boot options | ||
288 | # | ||
289 | CONFIG_ZBOOT_ROM_TEXT=0 | ||
290 | CONFIG_ZBOOT_ROM_BSS=0 | ||
291 | CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA2,115200n8" | ||
292 | # CONFIG_XIP_KERNEL is not set | ||
293 | # CONFIG_KEXEC is not set | ||
294 | |||
295 | # | ||
296 | # CPU Power Management | ||
297 | # | ||
298 | # CONFIG_CPU_IDLE is not set | ||
299 | |||
300 | # | ||
301 | # Floating point emulation | ||
302 | # | ||
303 | |||
304 | # | ||
305 | # At least one emulation must be selected | ||
306 | # | ||
307 | # CONFIG_FPE_NWFPE is not set | ||
308 | # CONFIG_FPE_FASTFPE is not set | ||
309 | CONFIG_VFP=y | ||
310 | CONFIG_VFPv3=y | ||
311 | CONFIG_NEON=y | ||
312 | |||
313 | # | ||
314 | # Userspace binary formats | ||
315 | # | ||
316 | CONFIG_BINFMT_ELF=y | ||
317 | # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set | ||
318 | CONFIG_HAVE_AOUT=y | ||
319 | # CONFIG_BINFMT_AOUT is not set | ||
320 | # CONFIG_BINFMT_MISC is not set | ||
321 | |||
322 | # | ||
323 | # Power management options | ||
324 | # | ||
325 | # CONFIG_PM is not set | ||
326 | CONFIG_ARCH_SUSPEND_POSSIBLE=y | ||
327 | # CONFIG_NET is not set | ||
328 | |||
329 | # | ||
330 | # Device Drivers | ||
331 | # | ||
332 | |||
333 | # | ||
334 | # Generic Driver Options | ||
335 | # | ||
336 | CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" | ||
337 | # CONFIG_DEVTMPFS is not set | ||
338 | CONFIG_STANDALONE=y | ||
339 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
340 | CONFIG_FW_LOADER=y | ||
341 | CONFIG_FIRMWARE_IN_KERNEL=y | ||
342 | CONFIG_EXTRA_FIRMWARE="" | ||
343 | # CONFIG_DEBUG_DRIVER is not set | ||
344 | # CONFIG_DEBUG_DEVRES is not set | ||
345 | # CONFIG_SYS_HYPERVISOR is not set | ||
346 | # CONFIG_MTD is not set | ||
347 | # CONFIG_PARPORT is not set | ||
348 | CONFIG_BLK_DEV=y | ||
349 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
350 | # CONFIG_BLK_DEV_LOOP is not set | ||
351 | CONFIG_BLK_DEV_RAM=y | ||
352 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
353 | CONFIG_BLK_DEV_RAM_SIZE=65536 | ||
354 | # CONFIG_BLK_DEV_XIP is not set | ||
355 | # CONFIG_CDROM_PKTCDVD is not set | ||
356 | # CONFIG_MISC_DEVICES is not set | ||
357 | CONFIG_HAVE_IDE=y | ||
358 | # CONFIG_IDE is not set | ||
359 | |||
360 | # | ||
361 | # SCSI device support | ||
362 | # | ||
363 | # CONFIG_RAID_ATTRS is not set | ||
364 | # CONFIG_SCSI is not set | ||
365 | # CONFIG_SCSI_DMA is not set | ||
366 | # CONFIG_SCSI_NETLINK is not set | ||
367 | # CONFIG_ATA is not set | ||
368 | # CONFIG_MD is not set | ||
369 | # CONFIG_PHONE is not set | ||
370 | |||
371 | # | ||
372 | # Input device support | ||
373 | # | ||
374 | CONFIG_INPUT=y | ||
375 | # CONFIG_INPUT_FF_MEMLESS is not set | ||
376 | # CONFIG_INPUT_POLLDEV is not set | ||
377 | |||
378 | # | ||
379 | # Userland interfaces | ||
380 | # | ||
381 | CONFIG_INPUT_MOUSEDEV=y | ||
382 | # CONFIG_INPUT_MOUSEDEV_PSAUX is not set | ||
383 | CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | ||
384 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | ||
385 | # CONFIG_INPUT_JOYDEV is not set | ||
386 | CONFIG_INPUT_EVDEV=y | ||
387 | # CONFIG_INPUT_EVBUG is not set | ||
388 | |||
389 | # | ||
390 | # Input Device Drivers | ||
391 | # | ||
392 | # CONFIG_INPUT_KEYBOARD is not set | ||
393 | # CONFIG_INPUT_MOUSE is not set | ||
394 | # CONFIG_INPUT_JOYSTICK is not set | ||
395 | # CONFIG_INPUT_TABLET is not set | ||
396 | # CONFIG_INPUT_TOUCHSCREEN is not set | ||
397 | # CONFIG_INPUT_MISC is not set | ||
398 | |||
399 | # | ||
400 | # Hardware I/O ports | ||
401 | # | ||
402 | # CONFIG_SERIO is not set | ||
403 | # CONFIG_GAMEPORT is not set | ||
404 | |||
405 | # | ||
406 | # Character devices | ||
407 | # | ||
408 | CONFIG_VT=y | ||
409 | CONFIG_CONSOLE_TRANSLATIONS=y | ||
410 | CONFIG_VT_CONSOLE=y | ||
411 | CONFIG_HW_CONSOLE=y | ||
412 | CONFIG_VT_HW_CONSOLE_BINDING=y | ||
413 | CONFIG_DEVKMEM=y | ||
414 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
415 | |||
416 | # | ||
417 | # Serial drivers | ||
418 | # | ||
419 | # CONFIG_SERIAL_8250 is not set | ||
420 | |||
421 | # | ||
422 | # Non-8250 serial port support | ||
423 | # | ||
424 | # CONFIG_SERIAL_AMBA_PL010 is not set | ||
425 | CONFIG_SERIAL_AMBA_PL011=y | ||
426 | CONFIG_SERIAL_AMBA_PL011_CONSOLE=y | ||
427 | # CONFIG_SERIAL_MAX3100 is not set | ||
428 | CONFIG_SERIAL_CORE=y | ||
429 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
430 | CONFIG_UNIX98_PTYS=y | ||
431 | # CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set | ||
432 | # CONFIG_LEGACY_PTYS is not set | ||
433 | # CONFIG_IPMI_HANDLER is not set | ||
434 | # CONFIG_HW_RANDOM is not set | ||
435 | # CONFIG_R3964 is not set | ||
436 | # CONFIG_RAW_DRIVER is not set | ||
437 | # CONFIG_TCG_TPM is not set | ||
438 | # CONFIG_I2C is not set | ||
439 | CONFIG_SPI=y | ||
440 | # CONFIG_SPI_DEBUG is not set | ||
441 | CONFIG_SPI_MASTER=y | ||
442 | |||
443 | # | ||
444 | # SPI Master Controller Drivers | ||
445 | # | ||
446 | # CONFIG_SPI_BITBANG is not set | ||
447 | CONFIG_SPI_PL022=y | ||
448 | |||
449 | # | ||
450 | # SPI Protocol Masters | ||
451 | # | ||
452 | # CONFIG_SPI_SPIDEV is not set | ||
453 | # CONFIG_SPI_TLE62X0 is not set | ||
454 | |||
455 | # | ||
456 | # PPS support | ||
457 | # | ||
458 | # CONFIG_PPS is not set | ||
459 | # CONFIG_W1 is not set | ||
460 | # CONFIG_POWER_SUPPLY is not set | ||
461 | # CONFIG_HWMON is not set | ||
462 | # CONFIG_THERMAL is not set | ||
463 | # CONFIG_WATCHDOG is not set | ||
464 | CONFIG_SSB_POSSIBLE=y | ||
465 | |||
466 | # | ||
467 | # Sonics Silicon Backplane | ||
468 | # | ||
469 | # CONFIG_SSB is not set | ||
470 | |||
471 | # | ||
472 | # Multifunction device drivers | ||
473 | # | ||
474 | # CONFIG_MFD_CORE is not set | ||
475 | # CONFIG_MFD_SM501 is not set | ||
476 | # CONFIG_HTC_PASIC3 is not set | ||
477 | # CONFIG_MFD_TMIO is not set | ||
478 | # CONFIG_MFD_MC13783 is not set | ||
479 | # CONFIG_EZX_PCAP is not set | ||
480 | # CONFIG_REGULATOR is not set | ||
481 | # CONFIG_MEDIA_SUPPORT is not set | ||
482 | |||
483 | # | ||
484 | # Graphics support | ||
485 | # | ||
486 | # CONFIG_VGASTATE is not set | ||
487 | # CONFIG_VIDEO_OUTPUT_CONTROL is not set | ||
488 | # CONFIG_FB is not set | ||
489 | # CONFIG_BACKLIGHT_LCD_SUPPORT is not set | ||
490 | |||
491 | # | ||
492 | # Display device support | ||
493 | # | ||
494 | # CONFIG_DISPLAY_SUPPORT is not set | ||
495 | |||
496 | # | ||
497 | # Console display driver support | ||
498 | # | ||
499 | # CONFIG_VGA_CONSOLE is not set | ||
500 | CONFIG_DUMMY_CONSOLE=y | ||
501 | # CONFIG_SOUND is not set | ||
502 | # CONFIG_HID_SUPPORT is not set | ||
503 | # CONFIG_USB_SUPPORT is not set | ||
504 | # CONFIG_MMC is not set | ||
505 | # CONFIG_MEMSTICK is not set | ||
506 | # CONFIG_NEW_LEDS is not set | ||
507 | # CONFIG_ACCESSIBILITY is not set | ||
508 | CONFIG_RTC_LIB=y | ||
509 | # CONFIG_RTC_CLASS is not set | ||
510 | # CONFIG_DMADEVICES is not set | ||
511 | # CONFIG_AUXDISPLAY is not set | ||
512 | # CONFIG_UIO is not set | ||
513 | |||
514 | # | ||
515 | # TI VLYNQ | ||
516 | # | ||
517 | # CONFIG_STAGING is not set | ||
518 | |||
519 | # | ||
520 | # File systems | ||
521 | # | ||
522 | CONFIG_EXT2_FS=y | ||
523 | CONFIG_EXT2_FS_XATTR=y | ||
524 | CONFIG_EXT2_FS_POSIX_ACL=y | ||
525 | CONFIG_EXT2_FS_SECURITY=y | ||
526 | # CONFIG_EXT2_FS_XIP is not set | ||
527 | # CONFIG_EXT3_FS is not set | ||
528 | # CONFIG_EXT4_FS is not set | ||
529 | CONFIG_FS_MBCACHE=y | ||
530 | # CONFIG_REISERFS_FS is not set | ||
531 | # CONFIG_JFS_FS is not set | ||
532 | CONFIG_FS_POSIX_ACL=y | ||
533 | # CONFIG_XFS_FS is not set | ||
534 | # CONFIG_BTRFS_FS is not set | ||
535 | # CONFIG_NILFS2_FS is not set | ||
536 | CONFIG_FILE_LOCKING=y | ||
537 | CONFIG_FSNOTIFY=y | ||
538 | CONFIG_DNOTIFY=y | ||
539 | CONFIG_INOTIFY=y | ||
540 | CONFIG_INOTIFY_USER=y | ||
541 | # CONFIG_QUOTA is not set | ||
542 | # CONFIG_AUTOFS_FS is not set | ||
543 | # CONFIG_AUTOFS4_FS is not set | ||
544 | # CONFIG_FUSE_FS is not set | ||
545 | CONFIG_GENERIC_ACL=y | ||
546 | |||
547 | # | ||
548 | # Caches | ||
549 | # | ||
550 | # CONFIG_FSCACHE is not set | ||
551 | |||
552 | # | ||
553 | # CD-ROM/DVD Filesystems | ||
554 | # | ||
555 | # CONFIG_ISO9660_FS is not set | ||
556 | # CONFIG_UDF_FS is not set | ||
557 | |||
558 | # | ||
559 | # DOS/FAT/NT Filesystems | ||
560 | # | ||
561 | # CONFIG_MSDOS_FS is not set | ||
562 | # CONFIG_VFAT_FS is not set | ||
563 | # CONFIG_NTFS_FS is not set | ||
564 | |||
565 | # | ||
566 | # Pseudo filesystems | ||
567 | # | ||
568 | CONFIG_PROC_FS=y | ||
569 | CONFIG_PROC_SYSCTL=y | ||
570 | CONFIG_PROC_PAGE_MONITOR=y | ||
571 | CONFIG_SYSFS=y | ||
572 | CONFIG_TMPFS=y | ||
573 | CONFIG_TMPFS_POSIX_ACL=y | ||
574 | # CONFIG_HUGETLB_PAGE is not set | ||
575 | CONFIG_CONFIGFS_FS=m | ||
576 | # CONFIG_MISC_FILESYSTEMS is not set | ||
577 | |||
578 | # | ||
579 | # Partition Types | ||
580 | # | ||
581 | # CONFIG_PARTITION_ADVANCED is not set | ||
582 | CONFIG_MSDOS_PARTITION=y | ||
583 | # CONFIG_NLS is not set | ||
584 | |||
585 | # | ||
586 | # Kernel hacking | ||
587 | # | ||
588 | # CONFIG_PRINTK_TIME is not set | ||
589 | CONFIG_ENABLE_WARN_DEPRECATED=y | ||
590 | CONFIG_ENABLE_MUST_CHECK=y | ||
591 | CONFIG_FRAME_WARN=1024 | ||
592 | CONFIG_MAGIC_SYSRQ=y | ||
593 | # CONFIG_STRIP_ASM_SYMS is not set | ||
594 | # CONFIG_UNUSED_SYMBOLS is not set | ||
595 | # CONFIG_DEBUG_FS is not set | ||
596 | # CONFIG_HEADERS_CHECK is not set | ||
597 | CONFIG_DEBUG_KERNEL=y | ||
598 | # CONFIG_DEBUG_SHIRQ is not set | ||
599 | CONFIG_DETECT_SOFTLOCKUP=y | ||
600 | # CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set | ||
601 | CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 | ||
602 | CONFIG_DETECT_HUNG_TASK=y | ||
603 | # CONFIG_BOOTPARAM_HUNG_TASK_PANIC is not set | ||
604 | CONFIG_BOOTPARAM_HUNG_TASK_PANIC_VALUE=0 | ||
605 | # CONFIG_SCHED_DEBUG is not set | ||
606 | # CONFIG_SCHEDSTATS is not set | ||
607 | # CONFIG_TIMER_STATS is not set | ||
608 | # CONFIG_DEBUG_OBJECTS is not set | ||
609 | # CONFIG_SLUB_DEBUG_ON is not set | ||
610 | # CONFIG_SLUB_STATS is not set | ||
611 | # CONFIG_DEBUG_KMEMLEAK is not set | ||
612 | # CONFIG_DEBUG_PREEMPT is not set | ||
613 | # CONFIG_DEBUG_RT_MUTEXES is not set | ||
614 | # CONFIG_RT_MUTEX_TESTER is not set | ||
615 | # CONFIG_DEBUG_SPINLOCK is not set | ||
616 | # CONFIG_DEBUG_MUTEXES is not set | ||
617 | # CONFIG_DEBUG_LOCK_ALLOC is not set | ||
618 | # CONFIG_PROVE_LOCKING is not set | ||
619 | # CONFIG_LOCK_STAT is not set | ||
620 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | ||
621 | # CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set | ||
622 | # CONFIG_DEBUG_KOBJECT is not set | ||
623 | CONFIG_DEBUG_BUGVERBOSE=y | ||
624 | CONFIG_DEBUG_INFO=y | ||
625 | # CONFIG_DEBUG_VM is not set | ||
626 | # CONFIG_DEBUG_WRITECOUNT is not set | ||
627 | CONFIG_DEBUG_MEMORY_INIT=y | ||
628 | # CONFIG_DEBUG_LIST is not set | ||
629 | # CONFIG_DEBUG_SG is not set | ||
630 | # CONFIG_DEBUG_NOTIFIERS is not set | ||
631 | # CONFIG_DEBUG_CREDENTIALS is not set | ||
632 | # CONFIG_BOOT_PRINTK_DELAY is not set | ||
633 | # CONFIG_RCU_TORTURE_TEST is not set | ||
634 | # CONFIG_RCU_CPU_STALL_DETECTOR is not set | ||
635 | # CONFIG_BACKTRACE_SELF_TEST is not set | ||
636 | # CONFIG_DEBUG_BLOCK_EXT_DEVT is not set | ||
637 | # CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set | ||
638 | # CONFIG_FAULT_INJECTION is not set | ||
639 | # CONFIG_SYSCTL_SYSCALL_CHECK is not set | ||
640 | # CONFIG_PAGE_POISONING is not set | ||
641 | CONFIG_HAVE_FUNCTION_TRACER=y | ||
642 | CONFIG_TRACING_SUPPORT=y | ||
643 | # CONFIG_FTRACE is not set | ||
644 | # CONFIG_SAMPLES is not set | ||
645 | CONFIG_HAVE_ARCH_KGDB=y | ||
646 | # CONFIG_KGDB is not set | ||
647 | CONFIG_ARM_UNWIND=y | ||
648 | CONFIG_DEBUG_USER=y | ||
649 | CONFIG_DEBUG_ERRORS=y | ||
650 | # CONFIG_DEBUG_STACK_USAGE is not set | ||
651 | # CONFIG_DEBUG_LL is not set | ||
652 | |||
653 | # | ||
654 | # Security options | ||
655 | # | ||
656 | # CONFIG_KEYS is not set | ||
657 | # CONFIG_SECURITY is not set | ||
658 | # CONFIG_SECURITYFS is not set | ||
659 | # CONFIG_SECURITY_FILE_CAPABILITIES is not set | ||
660 | # CONFIG_CRYPTO is not set | ||
661 | # CONFIG_BINARY_PRINTF is not set | ||
662 | |||
663 | # | ||
664 | # Library routines | ||
665 | # | ||
666 | CONFIG_GENERIC_FIND_LAST_BIT=y | ||
667 | # CONFIG_CRC_CCITT is not set | ||
668 | # CONFIG_CRC16 is not set | ||
669 | CONFIG_CRC_T10DIF=m | ||
670 | # CONFIG_CRC_ITU_T is not set | ||
671 | # CONFIG_CRC32 is not set | ||
672 | # CONFIG_CRC7 is not set | ||
673 | # CONFIG_LIBCRC32C is not set | ||
674 | CONFIG_ZLIB_INFLATE=y | ||
675 | CONFIG_DECOMPRESS_GZIP=y | ||
676 | CONFIG_DECOMPRESS_BZIP2=y | ||
677 | CONFIG_DECOMPRESS_LZMA=y | ||
678 | CONFIG_HAS_IOMEM=y | ||
679 | CONFIG_HAS_IOPORT=y | ||
680 | CONFIG_HAS_DMA=y | ||
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h index 3d0cdd21b882..9fd6d3ab68c0 100644 --- a/arch/arm/include/asm/cacheflush.h +++ b/arch/arm/include/asm/cacheflush.h | |||
@@ -331,15 +331,15 @@ static inline void outer_flush_range(unsigned long start, unsigned long end) | |||
331 | * Convert calls to our calling convention. | 331 | * Convert calls to our calling convention. |
332 | */ | 332 | */ |
333 | #define flush_cache_all() __cpuc_flush_kern_all() | 333 | #define flush_cache_all() __cpuc_flush_kern_all() |
334 | #ifndef CONFIG_CPU_CACHE_VIPT | 334 | |
335 | static inline void flush_cache_mm(struct mm_struct *mm) | 335 | static inline void vivt_flush_cache_mm(struct mm_struct *mm) |
336 | { | 336 | { |
337 | if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) | 337 | if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) |
338 | __cpuc_flush_user_all(); | 338 | __cpuc_flush_user_all(); |
339 | } | 339 | } |
340 | 340 | ||
341 | static inline void | 341 | static inline void |
342 | flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) | 342 | vivt_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) |
343 | { | 343 | { |
344 | if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) | 344 | if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) |
345 | __cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end), | 345 | __cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end), |
@@ -347,7 +347,7 @@ flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long | |||
347 | } | 347 | } |
348 | 348 | ||
349 | static inline void | 349 | static inline void |
350 | flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn) | 350 | vivt_flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn) |
351 | { | 351 | { |
352 | if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { | 352 | if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { |
353 | unsigned long addr = user_addr & PAGE_MASK; | 353 | unsigned long addr = user_addr & PAGE_MASK; |
@@ -356,7 +356,7 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned l | |||
356 | } | 356 | } |
357 | 357 | ||
358 | static inline void | 358 | static inline void |
359 | flush_ptrace_access(struct vm_area_struct *vma, struct page *page, | 359 | vivt_flush_ptrace_access(struct vm_area_struct *vma, struct page *page, |
360 | unsigned long uaddr, void *kaddr, | 360 | unsigned long uaddr, void *kaddr, |
361 | unsigned long len, int write) | 361 | unsigned long len, int write) |
362 | { | 362 | { |
@@ -365,6 +365,16 @@ flush_ptrace_access(struct vm_area_struct *vma, struct page *page, | |||
365 | __cpuc_coherent_kern_range(addr, addr + len); | 365 | __cpuc_coherent_kern_range(addr, addr + len); |
366 | } | 366 | } |
367 | } | 367 | } |
368 | |||
369 | #ifndef CONFIG_CPU_CACHE_VIPT | ||
370 | #define flush_cache_mm(mm) \ | ||
371 | vivt_flush_cache_mm(mm) | ||
372 | #define flush_cache_range(vma,start,end) \ | ||
373 | vivt_flush_cache_range(vma,start,end) | ||
374 | #define flush_cache_page(vma,addr,pfn) \ | ||
375 | vivt_flush_cache_page(vma,addr,pfn) | ||
376 | #define flush_ptrace_access(vma,page,ua,ka,len,write) \ | ||
377 | vivt_flush_ptrace_access(vma,page,ua,ka,len,write) | ||
368 | #else | 378 | #else |
369 | extern void flush_cache_mm(struct mm_struct *mm); | 379 | extern void flush_cache_mm(struct mm_struct *mm); |
370 | extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); | 380 | extern void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end); |
@@ -410,8 +420,6 @@ extern void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, | |||
410 | */ | 420 | */ |
411 | extern void flush_dcache_page(struct page *); | 421 | extern void flush_dcache_page(struct page *); |
412 | 422 | ||
413 | extern void __flush_dcache_page(struct address_space *mapping, struct page *page); | ||
414 | |||
415 | static inline void __flush_icache_all(void) | 423 | static inline void __flush_icache_all(void) |
416 | { | 424 | { |
417 | #ifdef CONFIG_ARM_ERRATA_411920 | 425 | #ifdef CONFIG_ARM_ERRATA_411920 |
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index ff46dfa68a97..a96300bf83fd 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h | |||
@@ -15,20 +15,15 @@ | |||
15 | * must not be used by drivers. | 15 | * must not be used by drivers. |
16 | */ | 16 | */ |
17 | #ifndef __arch_page_to_dma | 17 | #ifndef __arch_page_to_dma |
18 | |||
19 | #if !defined(CONFIG_HIGHMEM) | ||
20 | static inline dma_addr_t page_to_dma(struct device *dev, struct page *page) | 18 | static inline dma_addr_t page_to_dma(struct device *dev, struct page *page) |
21 | { | 19 | { |
22 | return (dma_addr_t)__virt_to_bus((unsigned long)page_address(page)); | 20 | return (dma_addr_t)__pfn_to_bus(page_to_pfn(page)); |
23 | } | 21 | } |
24 | #elif defined(__pfn_to_bus) | 22 | |
25 | static inline dma_addr_t page_to_dma(struct device *dev, struct page *page) | 23 | static inline struct page *dma_to_page(struct device *dev, dma_addr_t addr) |
26 | { | 24 | { |
27 | return (dma_addr_t)__pfn_to_bus(page_to_pfn(page)); | 25 | return pfn_to_page(__bus_to_pfn(addr)); |
28 | } | 26 | } |
29 | #else | ||
30 | #error "this machine class needs to define __arch_page_to_dma to use HIGHMEM" | ||
31 | #endif | ||
32 | 27 | ||
33 | static inline void *dma_to_virt(struct device *dev, dma_addr_t addr) | 28 | static inline void *dma_to_virt(struct device *dev, dma_addr_t addr) |
34 | { | 29 | { |
@@ -45,6 +40,11 @@ static inline dma_addr_t page_to_dma(struct device *dev, struct page *page) | |||
45 | return __arch_page_to_dma(dev, page); | 40 | return __arch_page_to_dma(dev, page); |
46 | } | 41 | } |
47 | 42 | ||
43 | static inline struct page *dma_to_page(struct device *dev, dma_addr_t addr) | ||
44 | { | ||
45 | return __arch_dma_to_page(dev, addr); | ||
46 | } | ||
47 | |||
48 | static inline void *dma_to_virt(struct device *dev, dma_addr_t addr) | 48 | static inline void *dma_to_virt(struct device *dev, dma_addr_t addr) |
49 | { | 49 | { |
50 | return __arch_dma_to_virt(dev, addr); | 50 | return __arch_dma_to_virt(dev, addr); |
@@ -257,9 +257,11 @@ extern int dma_needs_bounce(struct device*, dma_addr_t, size_t); | |||
257 | */ | 257 | */ |
258 | extern dma_addr_t dma_map_single(struct device *, void *, size_t, | 258 | extern dma_addr_t dma_map_single(struct device *, void *, size_t, |
259 | enum dma_data_direction); | 259 | enum dma_data_direction); |
260 | extern void dma_unmap_single(struct device *, dma_addr_t, size_t, | ||
261 | enum dma_data_direction); | ||
260 | extern dma_addr_t dma_map_page(struct device *, struct page *, | 262 | extern dma_addr_t dma_map_page(struct device *, struct page *, |
261 | unsigned long, size_t, enum dma_data_direction); | 263 | unsigned long, size_t, enum dma_data_direction); |
262 | extern void dma_unmap_single(struct device *, dma_addr_t, size_t, | 264 | extern void dma_unmap_page(struct device *, dma_addr_t, size_t, |
263 | enum dma_data_direction); | 265 | enum dma_data_direction); |
264 | 266 | ||
265 | /* | 267 | /* |
@@ -352,7 +354,6 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t handle, | |||
352 | { | 354 | { |
353 | /* nothing to do */ | 355 | /* nothing to do */ |
354 | } | 356 | } |
355 | #endif /* CONFIG_DMABOUNCE */ | ||
356 | 357 | ||
357 | /** | 358 | /** |
358 | * dma_unmap_page - unmap a buffer previously mapped through dma_map_page() | 359 | * dma_unmap_page - unmap a buffer previously mapped through dma_map_page() |
@@ -371,8 +372,9 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t handle, | |||
371 | static inline void dma_unmap_page(struct device *dev, dma_addr_t handle, | 372 | static inline void dma_unmap_page(struct device *dev, dma_addr_t handle, |
372 | size_t size, enum dma_data_direction dir) | 373 | size_t size, enum dma_data_direction dir) |
373 | { | 374 | { |
374 | dma_unmap_single(dev, handle, size, dir); | 375 | /* nothing to do */ |
375 | } | 376 | } |
377 | #endif /* CONFIG_DMABOUNCE */ | ||
376 | 378 | ||
377 | /** | 379 | /** |
378 | * dma_sync_single_range_for_cpu | 380 | * dma_sync_single_range_for_cpu |
diff --git a/arch/arm/include/asm/hardware/coresight.h b/arch/arm/include/asm/hardware/coresight.h new file mode 100644 index 000000000000..f82b25d4f73e --- /dev/null +++ b/arch/arm/include/asm/hardware/coresight.h | |||
@@ -0,0 +1,165 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/include/asm/hardware/coresight.h | ||
3 | * | ||
4 | * CoreSight components' registers | ||
5 | * | ||
6 | * Copyright (C) 2009 Nokia Corporation. | ||
7 | * Alexander Shishkin | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #ifndef __ASM_HARDWARE_CORESIGHT_H | ||
15 | #define __ASM_HARDWARE_CORESIGHT_H | ||
16 | |||
17 | #define TRACER_ACCESSED_BIT 0 | ||
18 | #define TRACER_RUNNING_BIT 1 | ||
19 | #define TRACER_CYCLE_ACC_BIT 2 | ||
20 | #define TRACER_ACCESSED BIT(TRACER_ACCESSED_BIT) | ||
21 | #define TRACER_RUNNING BIT(TRACER_RUNNING_BIT) | ||
22 | #define TRACER_CYCLE_ACC BIT(TRACER_CYCLE_ACC_BIT) | ||
23 | |||
24 | struct tracectx { | ||
25 | unsigned int etb_bufsz; | ||
26 | void __iomem *etb_regs; | ||
27 | void __iomem *etm_regs; | ||
28 | unsigned long flags; | ||
29 | int ncmppairs; | ||
30 | int etm_portsz; | ||
31 | struct device *dev; | ||
32 | struct clk *emu_clk; | ||
33 | struct mutex mutex; | ||
34 | }; | ||
35 | |||
36 | #define TRACER_TIMEOUT 10000 | ||
37 | |||
38 | #define etm_writel(t, v, x) \ | ||
39 | (__raw_writel((v), (t)->etm_regs + (x))) | ||
40 | #define etm_readl(t, x) (__raw_readl((t)->etm_regs + (x))) | ||
41 | |||
42 | /* CoreSight Management Registers */ | ||
43 | #define CSMR_LOCKACCESS 0xfb0 | ||
44 | #define CSMR_LOCKSTATUS 0xfb4 | ||
45 | #define CSMR_AUTHSTATUS 0xfb8 | ||
46 | #define CSMR_DEVID 0xfc8 | ||
47 | #define CSMR_DEVTYPE 0xfcc | ||
48 | /* CoreSight Component Registers */ | ||
49 | #define CSCR_CLASS 0xff4 | ||
50 | |||
51 | #define CSCR_PRSR 0x314 | ||
52 | |||
53 | #define UNLOCK_MAGIC 0xc5acce55 | ||
54 | |||
55 | /* ETM control register, "ETM Architecture", 3.3.1 */ | ||
56 | #define ETMR_CTRL 0 | ||
57 | #define ETMCTRL_POWERDOWN 1 | ||
58 | #define ETMCTRL_PROGRAM (1 << 10) | ||
59 | #define ETMCTRL_PORTSEL (1 << 11) | ||
60 | #define ETMCTRL_DO_CONTEXTID (3 << 14) | ||
61 | #define ETMCTRL_PORTMASK1 (7 << 4) | ||
62 | #define ETMCTRL_PORTMASK2 (1 << 21) | ||
63 | #define ETMCTRL_PORTMASK (ETMCTRL_PORTMASK1 | ETMCTRL_PORTMASK2) | ||
64 | #define ETMCTRL_PORTSIZE(x) ((((x) & 7) << 4) | (!!((x) & 8)) << 21) | ||
65 | #define ETMCTRL_DO_CPRT (1 << 1) | ||
66 | #define ETMCTRL_DATAMASK (3 << 2) | ||
67 | #define ETMCTRL_DATA_DO_DATA (1 << 2) | ||
68 | #define ETMCTRL_DATA_DO_ADDR (1 << 3) | ||
69 | #define ETMCTRL_DATA_DO_BOTH (ETMCTRL_DATA_DO_DATA | ETMCTRL_DATA_DO_ADDR) | ||
70 | #define ETMCTRL_BRANCH_OUTPUT (1 << 8) | ||
71 | #define ETMCTRL_CYCLEACCURATE (1 << 12) | ||
72 | |||
73 | /* ETM configuration code register */ | ||
74 | #define ETMR_CONFCODE (0x04) | ||
75 | |||
76 | /* ETM trace start/stop resource control register */ | ||
77 | #define ETMR_TRACESSCTRL (0x18) | ||
78 | |||
79 | /* ETM trigger event register */ | ||
80 | #define ETMR_TRIGEVT (0x08) | ||
81 | |||
82 | /* address access type register bits, "ETM architecture", | ||
83 | * table 3-27 */ | ||
84 | /* - access type */ | ||
85 | #define ETMAAT_IFETCH 0 | ||
86 | #define ETMAAT_IEXEC 1 | ||
87 | #define ETMAAT_IEXECPASS 2 | ||
88 | #define ETMAAT_IEXECFAIL 3 | ||
89 | #define ETMAAT_DLOADSTORE 4 | ||
90 | #define ETMAAT_DLOAD 5 | ||
91 | #define ETMAAT_DSTORE 6 | ||
92 | /* - comparison access size */ | ||
93 | #define ETMAAT_JAVA (0 << 3) | ||
94 | #define ETMAAT_THUMB (1 << 3) | ||
95 | #define ETMAAT_ARM (3 << 3) | ||
96 | /* - data value comparison control */ | ||
97 | #define ETMAAT_NOVALCMP (0 << 5) | ||
98 | #define ETMAAT_VALMATCH (1 << 5) | ||
99 | #define ETMAAT_VALNOMATCH (3 << 5) | ||
100 | /* - exact match */ | ||
101 | #define ETMAAT_EXACTMATCH (1 << 7) | ||
102 | /* - context id comparator control */ | ||
103 | #define ETMAAT_IGNCONTEXTID (0 << 8) | ||
104 | #define ETMAAT_VALUE1 (1 << 8) | ||
105 | #define ETMAAT_VALUE2 (2 << 8) | ||
106 | #define ETMAAT_VALUE3 (3 << 8) | ||
107 | /* - security level control */ | ||
108 | #define ETMAAT_IGNSECURITY (0 << 10) | ||
109 | #define ETMAAT_NSONLY (1 << 10) | ||
110 | #define ETMAAT_SONLY (2 << 10) | ||
111 | |||
112 | #define ETMR_COMP_VAL(x) (0x40 + (x) * 4) | ||
113 | #define ETMR_COMP_ACC_TYPE(x) (0x80 + (x) * 4) | ||
114 | |||
115 | /* ETM status register, "ETM Architecture", 3.3.2 */ | ||
116 | #define ETMR_STATUS (0x10) | ||
117 | #define ETMST_OVERFLOW (1 << 0) | ||
118 | #define ETMST_PROGBIT (1 << 1) | ||
119 | #define ETMST_STARTSTOP (1 << 2) | ||
120 | #define ETMST_TRIGGER (1 << 3) | ||
121 | |||
122 | #define etm_progbit(t) (etm_readl((t), ETMR_STATUS) & ETMST_PROGBIT) | ||
123 | #define etm_started(t) (etm_readl((t), ETMR_STATUS) & ETMST_STARTSTOP) | ||
124 | #define etm_triggered(t) (etm_readl((t), ETMR_STATUS) & ETMST_TRIGGER) | ||
125 | |||
126 | #define ETMR_TRACEENCTRL2 0x1c | ||
127 | #define ETMR_TRACEENCTRL 0x24 | ||
128 | #define ETMTE_INCLEXCL (1 << 24) | ||
129 | #define ETMR_TRACEENEVT 0x20 | ||
130 | #define ETMCTRL_OPTS (ETMCTRL_DO_CPRT | \ | ||
131 | ETMCTRL_DATA_DO_ADDR | \ | ||
132 | ETMCTRL_BRANCH_OUTPUT | \ | ||
133 | ETMCTRL_DO_CONTEXTID) | ||
134 | |||
135 | /* ETB registers, "CoreSight Components TRM", 9.3 */ | ||
136 | #define ETBR_DEPTH 0x04 | ||
137 | #define ETBR_STATUS 0x0c | ||
138 | #define ETBR_READMEM 0x10 | ||
139 | #define ETBR_READADDR 0x14 | ||
140 | #define ETBR_WRITEADDR 0x18 | ||
141 | #define ETBR_TRIGGERCOUNT 0x1c | ||
142 | #define ETBR_CTRL 0x20 | ||
143 | #define ETBR_FORMATTERCTRL 0x304 | ||
144 | #define ETBFF_ENFTC 1 | ||
145 | #define ETBFF_ENFCONT (1 << 1) | ||
146 | #define ETBFF_FONFLIN (1 << 4) | ||
147 | #define ETBFF_MANUAL_FLUSH (1 << 6) | ||
148 | #define ETBFF_TRIGIN (1 << 8) | ||
149 | #define ETBFF_TRIGEVT (1 << 9) | ||
150 | #define ETBFF_TRIGFL (1 << 10) | ||
151 | |||
152 | #define etb_writel(t, v, x) \ | ||
153 | (__raw_writel((v), (t)->etb_regs + (x))) | ||
154 | #define etb_readl(t, x) (__raw_readl((t)->etb_regs + (x))) | ||
155 | |||
156 | #define etm_lock(t) do { etm_writel((t), 0, CSMR_LOCKACCESS); } while (0) | ||
157 | #define etm_unlock(t) \ | ||
158 | do { etm_writel((t), UNLOCK_MAGIC, CSMR_LOCKACCESS); } while (0) | ||
159 | |||
160 | #define etb_lock(t) do { etb_writel((t), 0, CSMR_LOCKACCESS); } while (0) | ||
161 | #define etb_unlock(t) \ | ||
162 | do { etb_writel((t), UNLOCK_MAGIC, CSMR_LOCKACCESS); } while (0) | ||
163 | |||
164 | #endif /* __ASM_HARDWARE_CORESIGHT_H */ | ||
165 | |||
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index cefedf062138..5421d82a2572 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h | |||
@@ -125,8 +125,10 @@ | |||
125 | * private definitions which should NOT be used outside memory.h | 125 | * private definitions which should NOT be used outside memory.h |
126 | * files. Use virt_to_phys/phys_to_virt/__pa/__va instead. | 126 | * files. Use virt_to_phys/phys_to_virt/__pa/__va instead. |
127 | */ | 127 | */ |
128 | #ifndef __virt_to_phys | ||
128 | #define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET) | 129 | #define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET) |
129 | #define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET) | 130 | #define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET) |
131 | #endif | ||
130 | 132 | ||
131 | /* | 133 | /* |
132 | * Convert a physical address to a Page Frame Number and back | 134 | * Convert a physical address to a Page Frame Number and back |
@@ -134,6 +136,12 @@ | |||
134 | #define __phys_to_pfn(paddr) ((paddr) >> PAGE_SHIFT) | 136 | #define __phys_to_pfn(paddr) ((paddr) >> PAGE_SHIFT) |
135 | #define __pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT) | 137 | #define __pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT) |
136 | 138 | ||
139 | /* | ||
140 | * Convert a page to/from a physical address | ||
141 | */ | ||
142 | #define page_to_phys(page) (__pfn_to_phys(page_to_pfn(page))) | ||
143 | #define phys_to_page(phys) (pfn_to_page(__phys_to_pfn(phys))) | ||
144 | |||
137 | #ifndef __ASSEMBLY__ | 145 | #ifndef __ASSEMBLY__ |
138 | 146 | ||
139 | /* | 147 | /* |
@@ -194,7 +202,8 @@ static inline void *phys_to_virt(unsigned long x) | |||
194 | #ifndef __virt_to_bus | 202 | #ifndef __virt_to_bus |
195 | #define __virt_to_bus __virt_to_phys | 203 | #define __virt_to_bus __virt_to_phys |
196 | #define __bus_to_virt __phys_to_virt | 204 | #define __bus_to_virt __phys_to_virt |
197 | #define __pfn_to_bus(x) ((x) << PAGE_SHIFT) | 205 | #define __pfn_to_bus(x) __pfn_to_phys(x) |
206 | #define __bus_to_pfn(x) __phys_to_pfn(x) | ||
198 | #endif | 207 | #endif |
199 | 208 | ||
200 | static inline __deprecated unsigned long virt_to_bus(void *x) | 209 | static inline __deprecated unsigned long virt_to_bus(void *x) |
@@ -293,11 +302,6 @@ static inline __deprecated void *bus_to_virt(unsigned long x) | |||
293 | #endif /* !CONFIG_DISCONTIGMEM */ | 302 | #endif /* !CONFIG_DISCONTIGMEM */ |
294 | 303 | ||
295 | /* | 304 | /* |
296 | * For BIO. "will die". Kill me when bio_to_phys() and bvec_to_phys() die. | ||
297 | */ | ||
298 | #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) | ||
299 | |||
300 | /* | ||
301 | * Optional coherency support. Currently used only by selected | 305 | * Optional coherency support. Currently used only by selected |
302 | * Intel XSC3-based systems. | 306 | * Intel XSC3-based systems. |
303 | */ | 307 | */ |
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index 201ccaa11f61..11397687f42c 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h | |||
@@ -304,13 +304,23 @@ PTE_BIT_FUNC(mkyoung, |= L_PTE_YOUNG); | |||
304 | 304 | ||
305 | static inline pte_t pte_mkspecial(pte_t pte) { return pte; } | 305 | static inline pte_t pte_mkspecial(pte_t pte) { return pte; } |
306 | 306 | ||
307 | #define __pgprot_modify(prot,mask,bits) \ | ||
308 | __pgprot((pgprot_val(prot) & ~(mask)) | (bits)) | ||
309 | |||
307 | /* | 310 | /* |
308 | * Mark the prot value as uncacheable and unbufferable. | 311 | * Mark the prot value as uncacheable and unbufferable. |
309 | */ | 312 | */ |
310 | #define pgprot_noncached(prot) \ | 313 | #define pgprot_noncached(prot) \ |
311 | __pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_UNCACHED) | 314 | __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED) |
312 | #define pgprot_writecombine(prot) \ | 315 | #define pgprot_writecombine(prot) \ |
313 | __pgprot((pgprot_val(prot) & ~L_PTE_MT_MASK) | L_PTE_MT_BUFFERABLE) | 316 | __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_BUFFERABLE) |
317 | #if __LINUX_ARM_ARCH__ >= 7 | ||
318 | #define pgprot_dmacoherent(prot) \ | ||
319 | __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_BUFFERABLE) | ||
320 | #else | ||
321 | #define pgprot_dmacoherent(prot) \ | ||
322 | __pgprot_modify(prot, L_PTE_MT_MASK|L_PTE_EXEC, L_PTE_MT_UNCACHED) | ||
323 | #endif | ||
314 | 324 | ||
315 | #define pmd_none(pmd) (!pmd_val(pmd)) | 325 | #define pmd_none(pmd) (!pmd_val(pmd)) |
316 | #define pmd_present(pmd) (pmd_val(pmd)) | 326 | #define pmd_present(pmd) (pmd_val(pmd)) |
diff --git a/arch/arm/include/asm/swab.h b/arch/arm/include/asm/swab.h index ca2bf2f6d6ea..9997ad20eff1 100644 --- a/arch/arm/include/asm/swab.h +++ b/arch/arm/include/asm/swab.h | |||
@@ -22,6 +22,24 @@ | |||
22 | # define __SWAB_64_THRU_32__ | 22 | # define __SWAB_64_THRU_32__ |
23 | #endif | 23 | #endif |
24 | 24 | ||
25 | #if defined(__KERNEL__) && __LINUX_ARM_ARCH__ >= 6 | ||
26 | |||
27 | static inline __attribute_const__ __u16 __arch_swab16(__u16 x) | ||
28 | { | ||
29 | __asm__ ("rev16 %0, %1" : "=r" (x) : "r" (x)); | ||
30 | return x; | ||
31 | } | ||
32 | #define __arch_swab16 __arch_swab16 | ||
33 | |||
34 | static inline __attribute_const__ __u32 __arch_swab32(__u32 x) | ||
35 | { | ||
36 | __asm__ ("rev %0, %1" : "=r" (x) : "r" (x)); | ||
37 | return x; | ||
38 | } | ||
39 | #define __arch_swab32 __arch_swab32 | ||
40 | |||
41 | #else | ||
42 | |||
25 | static inline __attribute_const__ __u32 __arch_swab32(__u32 x) | 43 | static inline __attribute_const__ __u32 __arch_swab32(__u32 x) |
26 | { | 44 | { |
27 | __u32 t; | 45 | __u32 t; |
@@ -48,3 +66,4 @@ static inline __attribute_const__ __u32 __arch_swab32(__u32 x) | |||
48 | 66 | ||
49 | #endif | 67 | #endif |
50 | 68 | ||
69 | #endif | ||
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index d65b2f5bf41f..058e7e90881d 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h | |||
@@ -138,21 +138,26 @@ extern unsigned int user_debug; | |||
138 | #define dmb() __asm__ __volatile__ ("" : : : "memory") | 138 | #define dmb() __asm__ __volatile__ ("" : : : "memory") |
139 | #endif | 139 | #endif |
140 | 140 | ||
141 | #ifndef CONFIG_SMP | 141 | #if __LINUX_ARM_ARCH__ >= 7 || defined(CONFIG_SMP) |
142 | #define mb() dmb() | ||
143 | #define rmb() dmb() | ||
144 | #define wmb() dmb() | ||
145 | #else | ||
142 | #define mb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) | 146 | #define mb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) |
143 | #define rmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) | 147 | #define rmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) |
144 | #define wmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) | 148 | #define wmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) |
149 | #endif | ||
150 | |||
151 | #ifndef CONFIG_SMP | ||
145 | #define smp_mb() barrier() | 152 | #define smp_mb() barrier() |
146 | #define smp_rmb() barrier() | 153 | #define smp_rmb() barrier() |
147 | #define smp_wmb() barrier() | 154 | #define smp_wmb() barrier() |
148 | #else | 155 | #else |
149 | #define mb() dmb() | 156 | #define smp_mb() mb() |
150 | #define rmb() dmb() | 157 | #define smp_rmb() rmb() |
151 | #define wmb() dmb() | 158 | #define smp_wmb() wmb() |
152 | #define smp_mb() dmb() | ||
153 | #define smp_rmb() dmb() | ||
154 | #define smp_wmb() dmb() | ||
155 | #endif | 159 | #endif |
160 | |||
156 | #define read_barrier_depends() do { } while(0) | 161 | #define read_barrier_depends() do { } while(0) |
157 | #define smp_read_barrier_depends() do { } while(0) | 162 | #define smp_read_barrier_depends() do { } while(0) |
158 | 163 | ||
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 79087dd6d869..e7ccf7e697ce 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile | |||
@@ -17,6 +17,8 @@ obj-y := compat.o elf.o entry-armv.o entry-common.o irq.o \ | |||
17 | process.o ptrace.o return_address.o setup.o signal.o \ | 17 | process.o ptrace.o return_address.o setup.o signal.o \ |
18 | sys_arm.o stacktrace.o time.o traps.o | 18 | sys_arm.o stacktrace.o time.o traps.o |
19 | 19 | ||
20 | obj-$(CONFIG_OC_ETM) += etm.o | ||
21 | |||
20 | obj-$(CONFIG_ISA_DMA_API) += dma.o | 22 | obj-$(CONFIG_ISA_DMA_API) += dma.o |
21 | obj-$(CONFIG_ARCH_ACORN) += ecard.o | 23 | obj-$(CONFIG_ARCH_ACORN) += ecard.o |
22 | obj-$(CONFIG_FIQ) += fiq.o | 24 | obj-$(CONFIG_FIQ) += fiq.o |
diff --git a/arch/arm/kernel/etm.c b/arch/arm/kernel/etm.c new file mode 100644 index 000000000000..827753966301 --- /dev/null +++ b/arch/arm/kernel/etm.c | |||
@@ -0,0 +1,641 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/kernel/etm.c | ||
3 | * | ||
4 | * Driver for ARM's Embedded Trace Macrocell and Embedded Trace Buffer. | ||
5 | * | ||
6 | * Copyright (C) 2009 Nokia Corporation. | ||
7 | * Alexander Shishkin | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/types.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/sysrq.h> | ||
19 | #include <linux/device.h> | ||
20 | #include <linux/clk.h> | ||
21 | #include <linux/amba/bus.h> | ||
22 | #include <linux/fs.h> | ||
23 | #include <linux/uaccess.h> | ||
24 | #include <linux/miscdevice.h> | ||
25 | #include <linux/vmalloc.h> | ||
26 | #include <linux/mutex.h> | ||
27 | #include <asm/hardware/coresight.h> | ||
28 | #include <asm/sections.h> | ||
29 | |||
30 | MODULE_LICENSE("GPL"); | ||
31 | MODULE_AUTHOR("Alexander Shishkin"); | ||
32 | |||
33 | static struct tracectx tracer; | ||
34 | |||
35 | static inline bool trace_isrunning(struct tracectx *t) | ||
36 | { | ||
37 | return !!(t->flags & TRACER_RUNNING); | ||
38 | } | ||
39 | |||
40 | static int etm_setup_address_range(struct tracectx *t, int n, | ||
41 | unsigned long start, unsigned long end, int exclude, int data) | ||
42 | { | ||
43 | u32 flags = ETMAAT_ARM | ETMAAT_IGNCONTEXTID | ETMAAT_NSONLY | \ | ||
44 | ETMAAT_NOVALCMP; | ||
45 | |||
46 | if (n < 1 || n > t->ncmppairs) | ||
47 | return -EINVAL; | ||
48 | |||
49 | /* comparators and ranges are numbered starting with 1 as opposed | ||
50 | * to bits in a word */ | ||
51 | n--; | ||
52 | |||
53 | if (data) | ||
54 | flags |= ETMAAT_DLOADSTORE; | ||
55 | else | ||
56 | flags |= ETMAAT_IEXEC; | ||
57 | |||
58 | /* first comparator for the range */ | ||
59 | etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2)); | ||
60 | etm_writel(t, start, ETMR_COMP_VAL(n * 2)); | ||
61 | |||
62 | /* second comparator is right next to it */ | ||
63 | etm_writel(t, flags, ETMR_COMP_ACC_TYPE(n * 2 + 1)); | ||
64 | etm_writel(t, end, ETMR_COMP_VAL(n * 2 + 1)); | ||
65 | |||
66 | flags = exclude ? ETMTE_INCLEXCL : 0; | ||
67 | etm_writel(t, flags | (1 << n), ETMR_TRACEENCTRL); | ||
68 | |||
69 | return 0; | ||
70 | } | ||
71 | |||
72 | static int trace_start(struct tracectx *t) | ||
73 | { | ||
74 | u32 v; | ||
75 | unsigned long timeout = TRACER_TIMEOUT; | ||
76 | |||
77 | etb_unlock(t); | ||
78 | |||
79 | etb_writel(t, 0, ETBR_FORMATTERCTRL); | ||
80 | etb_writel(t, 1, ETBR_CTRL); | ||
81 | |||
82 | etb_lock(t); | ||
83 | |||
84 | /* configure etm */ | ||
85 | v = ETMCTRL_OPTS | ETMCTRL_PROGRAM | ETMCTRL_PORTSIZE(t->etm_portsz); | ||
86 | |||
87 | if (t->flags & TRACER_CYCLE_ACC) | ||
88 | v |= ETMCTRL_CYCLEACCURATE; | ||
89 | |||
90 | etm_unlock(t); | ||
91 | |||
92 | etm_writel(t, v, ETMR_CTRL); | ||
93 | |||
94 | while (!(etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout) | ||
95 | ; | ||
96 | if (!timeout) { | ||
97 | dev_dbg(t->dev, "Waiting for progbit to assert timed out\n"); | ||
98 | etm_lock(t); | ||
99 | return -EFAULT; | ||
100 | } | ||
101 | |||
102 | etm_setup_address_range(t, 1, (unsigned long)_stext, | ||
103 | (unsigned long)_etext, 0, 0); | ||
104 | etm_writel(t, 0, ETMR_TRACEENCTRL2); | ||
105 | etm_writel(t, 0, ETMR_TRACESSCTRL); | ||
106 | etm_writel(t, 0x6f, ETMR_TRACEENEVT); | ||
107 | |||
108 | v &= ~ETMCTRL_PROGRAM; | ||
109 | v |= ETMCTRL_PORTSEL; | ||
110 | |||
111 | etm_writel(t, v, ETMR_CTRL); | ||
112 | |||
113 | timeout = TRACER_TIMEOUT; | ||
114 | while (etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM && --timeout) | ||
115 | ; | ||
116 | if (!timeout) { | ||
117 | dev_dbg(t->dev, "Waiting for progbit to deassert timed out\n"); | ||
118 | etm_lock(t); | ||
119 | return -EFAULT; | ||
120 | } | ||
121 | |||
122 | etm_lock(t); | ||
123 | |||
124 | t->flags |= TRACER_RUNNING; | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int trace_stop(struct tracectx *t) | ||
130 | { | ||
131 | unsigned long timeout = TRACER_TIMEOUT; | ||
132 | |||
133 | etm_unlock(t); | ||
134 | |||
135 | etm_writel(t, 0x440, ETMR_CTRL); | ||
136 | while (!(etm_readl(t, ETMR_CTRL) & ETMCTRL_PROGRAM) && --timeout) | ||
137 | ; | ||
138 | if (!timeout) { | ||
139 | dev_dbg(t->dev, "Waiting for progbit to assert timed out\n"); | ||
140 | etm_lock(t); | ||
141 | return -EFAULT; | ||
142 | } | ||
143 | |||
144 | etm_lock(t); | ||
145 | |||
146 | etb_unlock(t); | ||
147 | etb_writel(t, ETBFF_MANUAL_FLUSH, ETBR_FORMATTERCTRL); | ||
148 | |||
149 | timeout = TRACER_TIMEOUT; | ||
150 | while (etb_readl(t, ETBR_FORMATTERCTRL) & | ||
151 | ETBFF_MANUAL_FLUSH && --timeout) | ||
152 | ; | ||
153 | if (!timeout) { | ||
154 | dev_dbg(t->dev, "Waiting for formatter flush to commence " | ||
155 | "timed out\n"); | ||
156 | etb_lock(t); | ||
157 | return -EFAULT; | ||
158 | } | ||
159 | |||
160 | etb_writel(t, 0, ETBR_CTRL); | ||
161 | |||
162 | etb_lock(t); | ||
163 | |||
164 | t->flags &= ~TRACER_RUNNING; | ||
165 | |||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static int etb_getdatalen(struct tracectx *t) | ||
170 | { | ||
171 | u32 v; | ||
172 | int rp, wp; | ||
173 | |||
174 | v = etb_readl(t, ETBR_STATUS); | ||
175 | |||
176 | if (v & 1) | ||
177 | return t->etb_bufsz; | ||
178 | |||
179 | rp = etb_readl(t, ETBR_READADDR); | ||
180 | wp = etb_readl(t, ETBR_WRITEADDR); | ||
181 | |||
182 | if (rp > wp) { | ||
183 | etb_writel(t, 0, ETBR_READADDR); | ||
184 | etb_writel(t, 0, ETBR_WRITEADDR); | ||
185 | |||
186 | return 0; | ||
187 | } | ||
188 | |||
189 | return wp - rp; | ||
190 | } | ||
191 | |||
192 | /* sysrq+v will always stop the running trace and leave it at that */ | ||
193 | static void etm_dump(void) | ||
194 | { | ||
195 | struct tracectx *t = &tracer; | ||
196 | u32 first = 0; | ||
197 | int length; | ||
198 | |||
199 | if (!t->etb_regs) { | ||
200 | printk(KERN_INFO "No tracing hardware found\n"); | ||
201 | return; | ||
202 | } | ||
203 | |||
204 | if (trace_isrunning(t)) | ||
205 | trace_stop(t); | ||
206 | |||
207 | etb_unlock(t); | ||
208 | |||
209 | length = etb_getdatalen(t); | ||
210 | |||
211 | if (length == t->etb_bufsz) | ||
212 | first = etb_readl(t, ETBR_WRITEADDR); | ||
213 | |||
214 | etb_writel(t, first, ETBR_READADDR); | ||
215 | |||
216 | printk(KERN_INFO "Trace buffer contents length: %d\n", length); | ||
217 | printk(KERN_INFO "--- ETB buffer begin ---\n"); | ||
218 | for (; length; length--) | ||
219 | printk("%08x", cpu_to_be32(etb_readl(t, ETBR_READMEM))); | ||
220 | printk(KERN_INFO "\n--- ETB buffer end ---\n"); | ||
221 | |||
222 | /* deassert the overflow bit */ | ||
223 | etb_writel(t, 1, ETBR_CTRL); | ||
224 | etb_writel(t, 0, ETBR_CTRL); | ||
225 | |||
226 | etb_writel(t, 0, ETBR_TRIGGERCOUNT); | ||
227 | etb_writel(t, 0, ETBR_READADDR); | ||
228 | etb_writel(t, 0, ETBR_WRITEADDR); | ||
229 | |||
230 | etb_lock(t); | ||
231 | } | ||
232 | |||
233 | static void sysrq_etm_dump(int key, struct tty_struct *tty) | ||
234 | { | ||
235 | dev_dbg(tracer.dev, "Dumping ETB buffer\n"); | ||
236 | etm_dump(); | ||
237 | } | ||
238 | |||
239 | static struct sysrq_key_op sysrq_etm_op = { | ||
240 | .handler = sysrq_etm_dump, | ||
241 | .help_msg = "ETM buffer dump", | ||
242 | .action_msg = "etm", | ||
243 | }; | ||
244 | |||
245 | static int etb_open(struct inode *inode, struct file *file) | ||
246 | { | ||
247 | if (!tracer.etb_regs) | ||
248 | return -ENODEV; | ||
249 | |||
250 | file->private_data = &tracer; | ||
251 | |||
252 | return nonseekable_open(inode, file); | ||
253 | } | ||
254 | |||
255 | static ssize_t etb_read(struct file *file, char __user *data, | ||
256 | size_t len, loff_t *ppos) | ||
257 | { | ||
258 | int total, i; | ||
259 | long length; | ||
260 | struct tracectx *t = file->private_data; | ||
261 | u32 first = 0; | ||
262 | u32 *buf; | ||
263 | |||
264 | mutex_lock(&t->mutex); | ||
265 | |||
266 | if (trace_isrunning(t)) { | ||
267 | length = 0; | ||
268 | goto out; | ||
269 | } | ||
270 | |||
271 | etb_unlock(t); | ||
272 | |||
273 | total = etb_getdatalen(t); | ||
274 | if (total == t->etb_bufsz) | ||
275 | first = etb_readl(t, ETBR_WRITEADDR); | ||
276 | |||
277 | etb_writel(t, first, ETBR_READADDR); | ||
278 | |||
279 | length = min(total * 4, (int)len); | ||
280 | buf = vmalloc(length); | ||
281 | |||
282 | dev_dbg(t->dev, "ETB buffer length: %d\n", total); | ||
283 | dev_dbg(t->dev, "ETB status reg: %x\n", etb_readl(t, ETBR_STATUS)); | ||
284 | for (i = 0; i < length / 4; i++) | ||
285 | buf[i] = etb_readl(t, ETBR_READMEM); | ||
286 | |||
287 | /* the only way to deassert overflow bit in ETB status is this */ | ||
288 | etb_writel(t, 1, ETBR_CTRL); | ||
289 | etb_writel(t, 0, ETBR_CTRL); | ||
290 | |||
291 | etb_writel(t, 0, ETBR_WRITEADDR); | ||
292 | etb_writel(t, 0, ETBR_READADDR); | ||
293 | etb_writel(t, 0, ETBR_TRIGGERCOUNT); | ||
294 | |||
295 | etb_lock(t); | ||
296 | |||
297 | length -= copy_to_user(data, buf, length); | ||
298 | vfree(buf); | ||
299 | |||
300 | out: | ||
301 | mutex_unlock(&t->mutex); | ||
302 | |||
303 | return length; | ||
304 | } | ||
305 | |||
306 | static int etb_release(struct inode *inode, struct file *file) | ||
307 | { | ||
308 | /* there's nothing to do here, actually */ | ||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | static const struct file_operations etb_fops = { | ||
313 | .owner = THIS_MODULE, | ||
314 | .read = etb_read, | ||
315 | .open = etb_open, | ||
316 | .release = etb_release, | ||
317 | }; | ||
318 | |||
319 | static struct miscdevice etb_miscdev = { | ||
320 | .name = "tracebuf", | ||
321 | .minor = 0, | ||
322 | .fops = &etb_fops, | ||
323 | }; | ||
324 | |||
325 | static int __init etb_probe(struct amba_device *dev, struct amba_id *id) | ||
326 | { | ||
327 | struct tracectx *t = &tracer; | ||
328 | int ret = 0; | ||
329 | |||
330 | ret = amba_request_regions(dev, NULL); | ||
331 | if (ret) | ||
332 | goto out; | ||
333 | |||
334 | t->etb_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res)); | ||
335 | if (!t->etb_regs) { | ||
336 | ret = -ENOMEM; | ||
337 | goto out_release; | ||
338 | } | ||
339 | |||
340 | amba_set_drvdata(dev, t); | ||
341 | |||
342 | etb_miscdev.parent = &dev->dev; | ||
343 | |||
344 | ret = misc_register(&etb_miscdev); | ||
345 | if (ret) | ||
346 | goto out_unmap; | ||
347 | |||
348 | t->emu_clk = clk_get(&dev->dev, "emu_src_ck"); | ||
349 | if (IS_ERR(t->emu_clk)) { | ||
350 | dev_dbg(&dev->dev, "Failed to obtain emu_src_ck.\n"); | ||
351 | return -EFAULT; | ||
352 | } | ||
353 | |||
354 | clk_enable(t->emu_clk); | ||
355 | |||
356 | etb_unlock(t); | ||
357 | t->etb_bufsz = etb_readl(t, ETBR_DEPTH); | ||
358 | dev_dbg(&dev->dev, "Size: %x\n", t->etb_bufsz); | ||
359 | |||
360 | /* make sure trace capture is disabled */ | ||
361 | etb_writel(t, 0, ETBR_CTRL); | ||
362 | etb_writel(t, 0x1000, ETBR_FORMATTERCTRL); | ||
363 | etb_lock(t); | ||
364 | |||
365 | dev_dbg(&dev->dev, "ETB AMBA driver initialized.\n"); | ||
366 | |||
367 | out: | ||
368 | return ret; | ||
369 | |||
370 | out_unmap: | ||
371 | amba_set_drvdata(dev, NULL); | ||
372 | iounmap(t->etb_regs); | ||
373 | |||
374 | out_release: | ||
375 | amba_release_regions(dev); | ||
376 | |||
377 | return ret; | ||
378 | } | ||
379 | |||
380 | static int etb_remove(struct amba_device *dev) | ||
381 | { | ||
382 | struct tracectx *t = amba_get_drvdata(dev); | ||
383 | |||
384 | amba_set_drvdata(dev, NULL); | ||
385 | |||
386 | iounmap(t->etb_regs); | ||
387 | t->etb_regs = NULL; | ||
388 | |||
389 | clk_disable(t->emu_clk); | ||
390 | clk_put(t->emu_clk); | ||
391 | |||
392 | amba_release_regions(dev); | ||
393 | |||
394 | return 0; | ||
395 | } | ||
396 | |||
397 | static struct amba_id etb_ids[] = { | ||
398 | { | ||
399 | .id = 0x0003b907, | ||
400 | .mask = 0x0007ffff, | ||
401 | }, | ||
402 | { 0, 0 }, | ||
403 | }; | ||
404 | |||
405 | static struct amba_driver etb_driver = { | ||
406 | .drv = { | ||
407 | .name = "etb", | ||
408 | .owner = THIS_MODULE, | ||
409 | }, | ||
410 | .probe = etb_probe, | ||
411 | .remove = etb_remove, | ||
412 | .id_table = etb_ids, | ||
413 | }; | ||
414 | |||
415 | /* use a sysfs file "trace_running" to start/stop tracing */ | ||
416 | static ssize_t trace_running_show(struct kobject *kobj, | ||
417 | struct kobj_attribute *attr, | ||
418 | char *buf) | ||
419 | { | ||
420 | return sprintf(buf, "%x\n", trace_isrunning(&tracer)); | ||
421 | } | ||
422 | |||
423 | static ssize_t trace_running_store(struct kobject *kobj, | ||
424 | struct kobj_attribute *attr, | ||
425 | const char *buf, size_t n) | ||
426 | { | ||
427 | unsigned int value; | ||
428 | int ret; | ||
429 | |||
430 | if (sscanf(buf, "%u", &value) != 1) | ||
431 | return -EINVAL; | ||
432 | |||
433 | mutex_lock(&tracer.mutex); | ||
434 | ret = value ? trace_start(&tracer) : trace_stop(&tracer); | ||
435 | mutex_unlock(&tracer.mutex); | ||
436 | |||
437 | return ret ? : n; | ||
438 | } | ||
439 | |||
440 | static struct kobj_attribute trace_running_attr = | ||
441 | __ATTR(trace_running, 0644, trace_running_show, trace_running_store); | ||
442 | |||
443 | static ssize_t trace_info_show(struct kobject *kobj, | ||
444 | struct kobj_attribute *attr, | ||
445 | char *buf) | ||
446 | { | ||
447 | u32 etb_wa, etb_ra, etb_st, etb_fc, etm_ctrl, etm_st; | ||
448 | int datalen; | ||
449 | |||
450 | etb_unlock(&tracer); | ||
451 | datalen = etb_getdatalen(&tracer); | ||
452 | etb_wa = etb_readl(&tracer, ETBR_WRITEADDR); | ||
453 | etb_ra = etb_readl(&tracer, ETBR_READADDR); | ||
454 | etb_st = etb_readl(&tracer, ETBR_STATUS); | ||
455 | etb_fc = etb_readl(&tracer, ETBR_FORMATTERCTRL); | ||
456 | etb_lock(&tracer); | ||
457 | |||
458 | etm_unlock(&tracer); | ||
459 | etm_ctrl = etm_readl(&tracer, ETMR_CTRL); | ||
460 | etm_st = etm_readl(&tracer, ETMR_STATUS); | ||
461 | etm_lock(&tracer); | ||
462 | |||
463 | return sprintf(buf, "Trace buffer len: %d\nComparator pairs: %d\n" | ||
464 | "ETBR_WRITEADDR:\t%08x\n" | ||
465 | "ETBR_READADDR:\t%08x\n" | ||
466 | "ETBR_STATUS:\t%08x\n" | ||
467 | "ETBR_FORMATTERCTRL:\t%08x\n" | ||
468 | "ETMR_CTRL:\t%08x\n" | ||
469 | "ETMR_STATUS:\t%08x\n", | ||
470 | datalen, | ||
471 | tracer.ncmppairs, | ||
472 | etb_wa, | ||
473 | etb_ra, | ||
474 | etb_st, | ||
475 | etb_fc, | ||
476 | etm_ctrl, | ||
477 | etm_st | ||
478 | ); | ||
479 | } | ||
480 | |||
481 | static struct kobj_attribute trace_info_attr = | ||
482 | __ATTR(trace_info, 0444, trace_info_show, NULL); | ||
483 | |||
484 | static ssize_t trace_mode_show(struct kobject *kobj, | ||
485 | struct kobj_attribute *attr, | ||
486 | char *buf) | ||
487 | { | ||
488 | return sprintf(buf, "%d %d\n", | ||
489 | !!(tracer.flags & TRACER_CYCLE_ACC), | ||
490 | tracer.etm_portsz); | ||
491 | } | ||
492 | |||
493 | static ssize_t trace_mode_store(struct kobject *kobj, | ||
494 | struct kobj_attribute *attr, | ||
495 | const char *buf, size_t n) | ||
496 | { | ||
497 | unsigned int cycacc, portsz; | ||
498 | |||
499 | if (sscanf(buf, "%u %u", &cycacc, &portsz) != 2) | ||
500 | return -EINVAL; | ||
501 | |||
502 | mutex_lock(&tracer.mutex); | ||
503 | if (cycacc) | ||
504 | tracer.flags |= TRACER_CYCLE_ACC; | ||
505 | else | ||
506 | tracer.flags &= ~TRACER_CYCLE_ACC; | ||
507 | |||
508 | tracer.etm_portsz = portsz & 0x0f; | ||
509 | mutex_unlock(&tracer.mutex); | ||
510 | |||
511 | return n; | ||
512 | } | ||
513 | |||
514 | static struct kobj_attribute trace_mode_attr = | ||
515 | __ATTR(trace_mode, 0644, trace_mode_show, trace_mode_store); | ||
516 | |||
517 | static int __init etm_probe(struct amba_device *dev, struct amba_id *id) | ||
518 | { | ||
519 | struct tracectx *t = &tracer; | ||
520 | int ret = 0; | ||
521 | |||
522 | if (t->etm_regs) { | ||
523 | dev_dbg(&dev->dev, "ETM already initialized\n"); | ||
524 | ret = -EBUSY; | ||
525 | goto out; | ||
526 | } | ||
527 | |||
528 | ret = amba_request_regions(dev, NULL); | ||
529 | if (ret) | ||
530 | goto out; | ||
531 | |||
532 | t->etm_regs = ioremap_nocache(dev->res.start, resource_size(&dev->res)); | ||
533 | if (!t->etm_regs) { | ||
534 | ret = -ENOMEM; | ||
535 | goto out_release; | ||
536 | } | ||
537 | |||
538 | amba_set_drvdata(dev, t); | ||
539 | |||
540 | mutex_init(&t->mutex); | ||
541 | t->dev = &dev->dev; | ||
542 | t->flags = TRACER_CYCLE_ACC; | ||
543 | t->etm_portsz = 1; | ||
544 | |||
545 | etm_unlock(t); | ||
546 | ret = etm_readl(t, CSCR_PRSR); | ||
547 | |||
548 | t->ncmppairs = etm_readl(t, ETMR_CONFCODE) & 0xf; | ||
549 | etm_writel(t, 0x440, ETMR_CTRL); | ||
550 | etm_lock(t); | ||
551 | |||
552 | ret = sysfs_create_file(&dev->dev.kobj, | ||
553 | &trace_running_attr.attr); | ||
554 | if (ret) | ||
555 | goto out_unmap; | ||
556 | |||
557 | /* failing to create any of these two is not fatal */ | ||
558 | ret = sysfs_create_file(&dev->dev.kobj, &trace_info_attr.attr); | ||
559 | if (ret) | ||
560 | dev_dbg(&dev->dev, "Failed to create trace_info in sysfs\n"); | ||
561 | |||
562 | ret = sysfs_create_file(&dev->dev.kobj, &trace_mode_attr.attr); | ||
563 | if (ret) | ||
564 | dev_dbg(&dev->dev, "Failed to create trace_mode in sysfs\n"); | ||
565 | |||
566 | dev_dbg(t->dev, "ETM AMBA driver initialized.\n"); | ||
567 | |||
568 | out: | ||
569 | return ret; | ||
570 | |||
571 | out_unmap: | ||
572 | amba_set_drvdata(dev, NULL); | ||
573 | iounmap(t->etm_regs); | ||
574 | |||
575 | out_release: | ||
576 | amba_release_regions(dev); | ||
577 | |||
578 | return ret; | ||
579 | } | ||
580 | |||
581 | static int etm_remove(struct amba_device *dev) | ||
582 | { | ||
583 | struct tracectx *t = amba_get_drvdata(dev); | ||
584 | |||
585 | amba_set_drvdata(dev, NULL); | ||
586 | |||
587 | iounmap(t->etm_regs); | ||
588 | t->etm_regs = NULL; | ||
589 | |||
590 | amba_release_regions(dev); | ||
591 | |||
592 | sysfs_remove_file(&dev->dev.kobj, &trace_running_attr.attr); | ||
593 | sysfs_remove_file(&dev->dev.kobj, &trace_info_attr.attr); | ||
594 | sysfs_remove_file(&dev->dev.kobj, &trace_mode_attr.attr); | ||
595 | |||
596 | return 0; | ||
597 | } | ||
598 | |||
599 | static struct amba_id etm_ids[] = { | ||
600 | { | ||
601 | .id = 0x0003b921, | ||
602 | .mask = 0x0007ffff, | ||
603 | }, | ||
604 | { 0, 0 }, | ||
605 | }; | ||
606 | |||
607 | static struct amba_driver etm_driver = { | ||
608 | .drv = { | ||
609 | .name = "etm", | ||
610 | .owner = THIS_MODULE, | ||
611 | }, | ||
612 | .probe = etm_probe, | ||
613 | .remove = etm_remove, | ||
614 | .id_table = etm_ids, | ||
615 | }; | ||
616 | |||
617 | static int __init etm_init(void) | ||
618 | { | ||
619 | int retval; | ||
620 | |||
621 | retval = amba_driver_register(&etb_driver); | ||
622 | if (retval) { | ||
623 | printk(KERN_ERR "Failed to register etb\n"); | ||
624 | return retval; | ||
625 | } | ||
626 | |||
627 | retval = amba_driver_register(&etm_driver); | ||
628 | if (retval) { | ||
629 | amba_driver_unregister(&etb_driver); | ||
630 | printk(KERN_ERR "Failed to probe etm\n"); | ||
631 | return retval; | ||
632 | } | ||
633 | |||
634 | /* not being able to install this handler is not fatal */ | ||
635 | (void)register_sysrq_key('v', &sysrq_etm_op); | ||
636 | |||
637 | return 0; | ||
638 | } | ||
639 | |||
640 | device_initcall(etm_init); | ||
641 | |||
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 2a573d4fea24..e7714f367eb8 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c | |||
@@ -662,8 +662,12 @@ static void do_signal(struct pt_regs *regs, int syscall) | |||
662 | regs->ARM_sp -= 4; | 662 | regs->ARM_sp -= 4; |
663 | usp = (u32 __user *)regs->ARM_sp; | 663 | usp = (u32 __user *)regs->ARM_sp; |
664 | 664 | ||
665 | put_user(regs->ARM_pc, usp); | 665 | if (put_user(regs->ARM_pc, usp) == 0) { |
666 | regs->ARM_pc = KERN_RESTART_CODE; | 666 | regs->ARM_pc = KERN_RESTART_CODE; |
667 | } else { | ||
668 | regs->ARM_sp += 4; | ||
669 | force_sigsegv(0, current); | ||
670 | } | ||
667 | #endif | 671 | #endif |
668 | } | 672 | } |
669 | } | 673 | } |
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 3df124e54267..0b2ee953f164 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig | |||
@@ -183,6 +183,11 @@ config MACH_CPUAT91 | |||
183 | Select this if you are using the Eukrea Electromatique's | 183 | Select this if you are using the Eukrea Electromatique's |
184 | CPUAT91 board <http://www.eukrea.com/>. | 184 | CPUAT91 board <http://www.eukrea.com/>. |
185 | 185 | ||
186 | config MACH_ECO920 | ||
187 | bool "eco920" | ||
188 | help | ||
189 | Select this if you are using the eco920 board | ||
190 | |||
186 | endif | 191 | endif |
187 | 192 | ||
188 | # ---------------------------------------------------------- | 193 | # ---------------------------------------------------------- |
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index ada440aab0c5..709fbad4a3ee 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile | |||
@@ -35,6 +35,7 @@ obj-$(CONFIG_MACH_PICOTUX2XX) += board-picotux200.o | |||
35 | obj-$(CONFIG_MACH_ECBAT91) += board-ecbat91.o | 35 | obj-$(CONFIG_MACH_ECBAT91) += board-ecbat91.o |
36 | obj-$(CONFIG_MACH_YL9200) += board-yl-9200.o | 36 | obj-$(CONFIG_MACH_YL9200) += board-yl-9200.o |
37 | obj-$(CONFIG_MACH_CPUAT91) += board-cpuat91.o | 37 | obj-$(CONFIG_MACH_CPUAT91) += board-cpuat91.o |
38 | obj-$(CONFIG_MACH_ECO920) += board-eco920.o | ||
38 | 39 | ||
39 | # AT91SAM9260 board-specific support | 40 | # AT91SAM9260 board-specific support |
40 | obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o | 41 | obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o |
@@ -77,6 +78,7 @@ obj-y += leds.o | |||
77 | # Power Management | 78 | # Power Management |
78 | obj-$(CONFIG_PM) += pm.o | 79 | obj-$(CONFIG_PM) += pm.o |
79 | obj-$(CONFIG_AT91_SLOW_CLOCK) += pm_slowclock.o | 80 | obj-$(CONFIG_AT91_SLOW_CLOCK) += pm_slowclock.o |
81 | obj-$(CONFIG_CPU_IDLE) += cpuidle.o | ||
80 | 82 | ||
81 | ifeq ($(CONFIG_PM_DEBUG),y) | 83 | ifeq ($(CONFIG_PM_DEBUG),y) |
82 | CFLAGS_pm.o += -DDEBUG | 84 | CFLAGS_pm.o += -DDEBUG |
diff --git a/arch/arm/mach-at91/at91sam9g45_devices.c b/arch/arm/mach-at91/at91sam9g45_devices.c index 332b784050b2..a57af3e99c7c 100644 --- a/arch/arm/mach-at91/at91sam9g45_devices.c +++ b/arch/arm/mach-at91/at91sam9g45_devices.c | |||
@@ -131,6 +131,62 @@ void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data) {} | |||
131 | 131 | ||
132 | 132 | ||
133 | /* -------------------------------------------------------------------- | 133 | /* -------------------------------------------------------------------- |
134 | * USB Host HS (EHCI) | ||
135 | * Needs an OHCI host for low and full speed management | ||
136 | * -------------------------------------------------------------------- */ | ||
137 | |||
138 | #if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE) | ||
139 | static u64 ehci_dmamask = DMA_BIT_MASK(32); | ||
140 | static struct at91_usbh_data usbh_ehci_data; | ||
141 | |||
142 | static struct resource usbh_ehci_resources[] = { | ||
143 | [0] = { | ||
144 | .start = AT91SAM9G45_EHCI_BASE, | ||
145 | .end = AT91SAM9G45_EHCI_BASE + SZ_1M - 1, | ||
146 | .flags = IORESOURCE_MEM, | ||
147 | }, | ||
148 | [1] = { | ||
149 | .start = AT91SAM9G45_ID_UHPHS, | ||
150 | .end = AT91SAM9G45_ID_UHPHS, | ||
151 | .flags = IORESOURCE_IRQ, | ||
152 | }, | ||
153 | }; | ||
154 | |||
155 | static struct platform_device at91_usbh_ehci_device = { | ||
156 | .name = "atmel-ehci", | ||
157 | .id = -1, | ||
158 | .dev = { | ||
159 | .dma_mask = &ehci_dmamask, | ||
160 | .coherent_dma_mask = DMA_BIT_MASK(32), | ||
161 | .platform_data = &usbh_ehci_data, | ||
162 | }, | ||
163 | .resource = usbh_ehci_resources, | ||
164 | .num_resources = ARRAY_SIZE(usbh_ehci_resources), | ||
165 | }; | ||
166 | |||
167 | void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) | ||
168 | { | ||
169 | int i; | ||
170 | |||
171 | if (!data) | ||
172 | return; | ||
173 | |||
174 | /* Enable VBus control for UHP ports */ | ||
175 | for (i = 0; i < data->ports; i++) { | ||
176 | if (data->vbus_pin[i]) | ||
177 | at91_set_gpio_output(data->vbus_pin[i], 0); | ||
178 | } | ||
179 | |||
180 | usbh_ehci_data = *data; | ||
181 | at91_clock_associate("uhphs_clk", &at91_usbh_ehci_device.dev, "ehci_clk"); | ||
182 | platform_device_register(&at91_usbh_ehci_device); | ||
183 | } | ||
184 | #else | ||
185 | void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data) {} | ||
186 | #endif | ||
187 | |||
188 | |||
189 | /* -------------------------------------------------------------------- | ||
134 | * USB HS Device (Gadget) | 190 | * USB HS Device (Gadget) |
135 | * -------------------------------------------------------------------- */ | 191 | * -------------------------------------------------------------------- */ |
136 | 192 | ||
diff --git a/arch/arm/mach-at91/board-eco920.c b/arch/arm/mach-at91/board-eco920.c new file mode 100644 index 000000000000..295a96609e71 --- /dev/null +++ b/arch/arm/mach-at91/board-eco920.c | |||
@@ -0,0 +1,158 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License as published by | ||
4 | * the Free Software Foundation; either version 2 of the License, or | ||
5 | * (at your option) any later version. | ||
6 | * | ||
7 | * This program is distributed in the hope that it will be useful, | ||
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | * GNU General Public License for more details. | ||
11 | * | ||
12 | * You should have received a copy of the GNU General Public License | ||
13 | * along with this program; if not, write to the Free Software | ||
14 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
15 | */ | ||
16 | |||
17 | #include <linux/init.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/mtd/physmap.h> | ||
20 | #include <linux/gpio.h> | ||
21 | |||
22 | #include <asm/mach-types.h> | ||
23 | |||
24 | #include <asm/mach/arch.h> | ||
25 | #include <asm/mach/map.h> | ||
26 | |||
27 | #include <mach/board.h> | ||
28 | #include <mach/at91rm9200_mc.h> | ||
29 | #include "generic.h" | ||
30 | |||
31 | static void __init eco920_map_io(void) | ||
32 | { | ||
33 | at91rm9200_initialize(18432000, AT91RM9200_PQFP); | ||
34 | |||
35 | /* Setup the LEDs */ | ||
36 | at91_init_leds(AT91_PIN_PB0, AT91_PIN_PB1); | ||
37 | |||
38 | /* DBGU on ttyS0. (Rx & Tx only */ | ||
39 | at91_register_uart(0, 0, 0); | ||
40 | |||
41 | /* set serial console to ttyS0 (ie, DBGU) */ | ||
42 | at91_set_serial_console(0); | ||
43 | } | ||
44 | |||
45 | static void __init eco920_init_irq(void) | ||
46 | { | ||
47 | at91rm9200_init_interrupts(NULL); | ||
48 | } | ||
49 | |||
50 | static struct at91_eth_data __initdata eco920_eth_data = { | ||
51 | .phy_irq_pin = AT91_PIN_PC2, | ||
52 | .is_rmii = 1, | ||
53 | }; | ||
54 | |||
55 | static struct at91_usbh_data __initdata eco920_usbh_data = { | ||
56 | .ports = 1, | ||
57 | }; | ||
58 | |||
59 | static struct at91_udc_data __initdata eco920_udc_data = { | ||
60 | .vbus_pin = AT91_PIN_PB12, | ||
61 | .pullup_pin = AT91_PIN_PB13, | ||
62 | }; | ||
63 | |||
64 | static struct at91_mmc_data __initdata eco920_mmc_data = { | ||
65 | .slot_b = 0, | ||
66 | .wire4 = 0, | ||
67 | }; | ||
68 | |||
69 | static struct physmap_flash_data eco920_flash_data = { | ||
70 | .width = 2, | ||
71 | }; | ||
72 | |||
73 | static struct resource eco920_flash_resource = { | ||
74 | .start = 0x11000000, | ||
75 | .end = 0x11ffffff, | ||
76 | .flags = IORESOURCE_MEM, | ||
77 | }; | ||
78 | |||
79 | static struct platform_device eco920_flash = { | ||
80 | .name = "physmap-flash", | ||
81 | .id = 0, | ||
82 | .dev = { | ||
83 | .platform_data = &eco920_flash_data, | ||
84 | }, | ||
85 | .resource = &eco920_flash_resource, | ||
86 | .num_resources = 1, | ||
87 | }; | ||
88 | |||
89 | static struct resource at91_beeper_resources[] = { | ||
90 | [0] = { | ||
91 | .start = AT91RM9200_BASE_TC3, | ||
92 | .end = AT91RM9200_BASE_TC3 + 0x39, | ||
93 | .flags = IORESOURCE_MEM, | ||
94 | }, | ||
95 | }; | ||
96 | |||
97 | static struct platform_device at91_beeper = { | ||
98 | .name = "at91_beeper", | ||
99 | .id = 0, | ||
100 | .resource = at91_beeper_resources, | ||
101 | .num_resources = ARRAY_SIZE(at91_beeper_resources), | ||
102 | }; | ||
103 | |||
104 | static struct spi_board_info eco920_spi_devices[] = { | ||
105 | { /* CAN controller */ | ||
106 | .modalias = "tlv5638", | ||
107 | .chip_select = 3, | ||
108 | .max_speed_hz = 20 * 1000 * 1000, | ||
109 | .mode = SPI_CPHA, | ||
110 | }, | ||
111 | }; | ||
112 | |||
113 | static void __init eco920_board_init(void) | ||
114 | { | ||
115 | at91_add_device_serial(); | ||
116 | at91_add_device_eth(&eco920_eth_data); | ||
117 | at91_add_device_usbh(&eco920_usbh_data); | ||
118 | at91_add_device_udc(&eco920_udc_data); | ||
119 | |||
120 | at91_add_device_mmc(0, &eco920_mmc_data); | ||
121 | platform_device_register(&eco920_flash); | ||
122 | |||
123 | at91_sys_write(AT91_SMC_CSR(7), AT91_SMC_RWHOLD_(1) | ||
124 | | AT91_SMC_RWSETUP_(1) | ||
125 | | AT91_SMC_DBW_8 | ||
126 | | AT91_SMC_WSEN | ||
127 | | AT91_SMC_NWS_(15)); | ||
128 | |||
129 | at91_set_A_periph(AT91_PIN_PC6, 1); | ||
130 | |||
131 | at91_set_gpio_input(AT91_PIN_PA23, 0); | ||
132 | at91_set_deglitch(AT91_PIN_PA23, 1); | ||
133 | |||
134 | /* Initialization of the Static Memory Controller for Chip Select 3 */ | ||
135 | at91_sys_write(AT91_SMC_CSR(3), | ||
136 | AT91_SMC_DBW_16 | /* 16 bit */ | ||
137 | AT91_SMC_WSEN | | ||
138 | AT91_SMC_NWS_(5) | /* wait states */ | ||
139 | AT91_SMC_TDF_(1) /* float time */ | ||
140 | ); | ||
141 | |||
142 | at91_clock_associate("tc3_clk", &at91_beeper.dev, "at91_beeper"); | ||
143 | at91_set_B_periph(AT91_PIN_PB6, 0); | ||
144 | platform_device_register(&at91_beeper); | ||
145 | |||
146 | at91_add_device_spi(eco920_spi_devices, ARRAY_SIZE(eco920_spi_devices)); | ||
147 | } | ||
148 | |||
149 | MACHINE_START(ECO920, "eco920") | ||
150 | /* Maintainer: Sascha Hauer */ | ||
151 | .phys_io = AT91_BASE_SYS, | ||
152 | .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc, | ||
153 | .boot_params = AT91_SDRAM_BASE + 0x100, | ||
154 | .timer = &at91rm9200_timer, | ||
155 | .map_io = eco920_map_io, | ||
156 | .init_irq = eco920_init_irq, | ||
157 | .init_machine = eco920_board_init, | ||
158 | MACHINE_END | ||
diff --git a/arch/arm/mach-at91/board-sam9m10g45ek.c b/arch/arm/mach-at91/board-sam9m10g45ek.c index 64c3843f323d..1cf4d8681078 100644 --- a/arch/arm/mach-at91/board-sam9m10g45ek.c +++ b/arch/arm/mach-at91/board-sam9m10g45ek.c | |||
@@ -366,6 +366,7 @@ static void __init ek_board_init(void) | |||
366 | at91_add_device_serial(); | 366 | at91_add_device_serial(); |
367 | /* USB HS Host */ | 367 | /* USB HS Host */ |
368 | at91_add_device_usbh_ohci(&ek_usbh_hs_data); | 368 | at91_add_device_usbh_ohci(&ek_usbh_hs_data); |
369 | at91_add_device_usbh_ehci(&ek_usbh_hs_data); | ||
369 | /* USB HS Device */ | 370 | /* USB HS Device */ |
370 | at91_add_device_usba(&ek_usba_udc_data); | 371 | at91_add_device_usba(&ek_usba_udc_data); |
371 | /* SPI */ | 372 | /* SPI */ |
diff --git a/arch/arm/mach-at91/cpuidle.c b/arch/arm/mach-at91/cpuidle.c new file mode 100644 index 000000000000..1cfeac1483d6 --- /dev/null +++ b/arch/arm/mach-at91/cpuidle.c | |||
@@ -0,0 +1,94 @@ | |||
1 | /* | ||
2 | * based on arch/arm/mach-kirkwood/cpuidle.c | ||
3 | * | ||
4 | * CPU idle support for AT91 SoC | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public | ||
7 | * License version 2. This program is licensed "as is" without any | ||
8 | * warranty of any kind, whether express or implied. | ||
9 | * | ||
10 | * The cpu idle uses wait-for-interrupt and RAM self refresh in order | ||
11 | * to implement two idle states - | ||
12 | * #1 wait-for-interrupt | ||
13 | * #2 wait-for-interrupt and RAM self refresh | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/cpuidle.h> | ||
20 | #include <asm/proc-fns.h> | ||
21 | #include <linux/io.h> | ||
22 | |||
23 | #include "pm.h" | ||
24 | |||
25 | #define AT91_MAX_STATES 2 | ||
26 | |||
27 | static DEFINE_PER_CPU(struct cpuidle_device, at91_cpuidle_device); | ||
28 | |||
29 | static struct cpuidle_driver at91_idle_driver = { | ||
30 | .name = "at91_idle", | ||
31 | .owner = THIS_MODULE, | ||
32 | }; | ||
33 | |||
34 | /* Actual code that puts the SoC in different idle states */ | ||
35 | static int at91_enter_idle(struct cpuidle_device *dev, | ||
36 | struct cpuidle_state *state) | ||
37 | { | ||
38 | struct timeval before, after; | ||
39 | int idle_time; | ||
40 | u32 saved_lpr; | ||
41 | |||
42 | local_irq_disable(); | ||
43 | do_gettimeofday(&before); | ||
44 | if (state == &dev->states[0]) | ||
45 | /* Wait for interrupt state */ | ||
46 | cpu_do_idle(); | ||
47 | else if (state == &dev->states[1]) { | ||
48 | asm("b 1f; .align 5; 1:"); | ||
49 | asm("mcr p15, 0, r0, c7, c10, 4"); /* drain write buffer */ | ||
50 | saved_lpr = sdram_selfrefresh_enable(); | ||
51 | cpu_do_idle(); | ||
52 | sdram_selfrefresh_disable(saved_lpr); | ||
53 | } | ||
54 | do_gettimeofday(&after); | ||
55 | local_irq_enable(); | ||
56 | idle_time = (after.tv_sec - before.tv_sec) * USEC_PER_SEC + | ||
57 | (after.tv_usec - before.tv_usec); | ||
58 | return idle_time; | ||
59 | } | ||
60 | |||
61 | /* Initialize CPU idle by registering the idle states */ | ||
62 | static int at91_init_cpuidle(void) | ||
63 | { | ||
64 | struct cpuidle_device *device; | ||
65 | |||
66 | cpuidle_register_driver(&at91_idle_driver); | ||
67 | |||
68 | device = &per_cpu(at91_cpuidle_device, smp_processor_id()); | ||
69 | device->state_count = AT91_MAX_STATES; | ||
70 | |||
71 | /* Wait for interrupt state */ | ||
72 | device->states[0].enter = at91_enter_idle; | ||
73 | device->states[0].exit_latency = 1; | ||
74 | device->states[0].target_residency = 10000; | ||
75 | device->states[0].flags = CPUIDLE_FLAG_TIME_VALID; | ||
76 | strcpy(device->states[0].name, "WFI"); | ||
77 | strcpy(device->states[0].desc, "Wait for interrupt"); | ||
78 | |||
79 | /* Wait for interrupt and RAM self refresh state */ | ||
80 | device->states[1].enter = at91_enter_idle; | ||
81 | device->states[1].exit_latency = 10; | ||
82 | device->states[1].target_residency = 10000; | ||
83 | device->states[1].flags = CPUIDLE_FLAG_TIME_VALID; | ||
84 | strcpy(device->states[1].name, "RAM_SR"); | ||
85 | strcpy(device->states[1].desc, "WFI and RAM Self Refresh"); | ||
86 | |||
87 | if (cpuidle_register_device(device)) { | ||
88 | printk(KERN_ERR "at91_init_cpuidle: Failed registering\n"); | ||
89 | return -EIO; | ||
90 | } | ||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | device_initcall(at91_init_cpuidle); | ||
diff --git a/arch/arm/mach-at91/include/mach/board.h b/arch/arm/mach-at91/include/mach/board.h index 2f4fcedc02ba..2295d80dd893 100644 --- a/arch/arm/mach-at91/include/mach/board.h +++ b/arch/arm/mach-at91/include/mach/board.h | |||
@@ -98,6 +98,7 @@ struct at91_usbh_data { | |||
98 | }; | 98 | }; |
99 | extern void __init at91_add_device_usbh(struct at91_usbh_data *data); | 99 | extern void __init at91_add_device_usbh(struct at91_usbh_data *data); |
100 | extern void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data); | 100 | extern void __init at91_add_device_usbh_ohci(struct at91_usbh_data *data); |
101 | extern void __init at91_add_device_usbh_ehci(struct at91_usbh_data *data); | ||
101 | 102 | ||
102 | /* NAND / SmartMedia */ | 103 | /* NAND / SmartMedia */ |
103 | struct atmel_nand_data { | 104 | struct atmel_nand_data { |
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 4028724d490d..615668986480 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c | |||
@@ -29,62 +29,7 @@ | |||
29 | #include <mach/cpu.h> | 29 | #include <mach/cpu.h> |
30 | 30 | ||
31 | #include "generic.h" | 31 | #include "generic.h" |
32 | 32 | #include "pm.h" | |
33 | #ifdef CONFIG_ARCH_AT91RM9200 | ||
34 | #include <mach/at91rm9200_mc.h> | ||
35 | |||
36 | /* | ||
37 | * The AT91RM9200 goes into self-refresh mode with this command, and will | ||
38 | * terminate self-refresh automatically on the next SDRAM access. | ||
39 | */ | ||
40 | #define sdram_selfrefresh_enable() at91_sys_write(AT91_SDRAMC_SRR, 1) | ||
41 | #define sdram_selfrefresh_disable() do {} while (0) | ||
42 | |||
43 | #elif defined(CONFIG_ARCH_AT91CAP9) | ||
44 | #include <mach/at91cap9_ddrsdr.h> | ||
45 | |||
46 | static u32 saved_lpr; | ||
47 | |||
48 | static inline void sdram_selfrefresh_enable(void) | ||
49 | { | ||
50 | u32 lpr; | ||
51 | |||
52 | saved_lpr = at91_sys_read(AT91_DDRSDRC_LPR); | ||
53 | |||
54 | lpr = saved_lpr & ~AT91_DDRSDRC_LPCB; | ||
55 | at91_sys_write(AT91_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH); | ||
56 | } | ||
57 | |||
58 | #define sdram_selfrefresh_disable() at91_sys_write(AT91_DDRSDRC_LPR, saved_lpr) | ||
59 | |||
60 | #else | ||
61 | #include <mach/at91sam9_sdramc.h> | ||
62 | |||
63 | #ifdef CONFIG_ARCH_AT91SAM9263 | ||
64 | /* | ||
65 | * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use; | ||
66 | * handle those cases both here and in the Suspend-To-RAM support. | ||
67 | */ | ||
68 | #define AT91_SDRAMC AT91_SDRAMC0 | ||
69 | #warning Assuming EB1 SDRAM controller is *NOT* used | ||
70 | #endif | ||
71 | |||
72 | static u32 saved_lpr; | ||
73 | |||
74 | static inline void sdram_selfrefresh_enable(void) | ||
75 | { | ||
76 | u32 lpr; | ||
77 | |||
78 | saved_lpr = at91_sys_read(AT91_SDRAMC_LPR); | ||
79 | |||
80 | lpr = saved_lpr & ~AT91_SDRAMC_LPCB; | ||
81 | at91_sys_write(AT91_SDRAMC_LPR, lpr | AT91_SDRAMC_LPCB_SELF_REFRESH); | ||
82 | } | ||
83 | |||
84 | #define sdram_selfrefresh_disable() at91_sys_write(AT91_SDRAMC_LPR, saved_lpr) | ||
85 | |||
86 | #endif | ||
87 | |||
88 | 33 | ||
89 | /* | 34 | /* |
90 | * Show the reason for the previous system reset. | 35 | * Show the reason for the previous system reset. |
@@ -260,6 +205,7 @@ extern u32 at91_slow_clock_sz; | |||
260 | 205 | ||
261 | static int at91_pm_enter(suspend_state_t state) | 206 | static int at91_pm_enter(suspend_state_t state) |
262 | { | 207 | { |
208 | u32 saved_lpr; | ||
263 | at91_gpio_suspend(); | 209 | at91_gpio_suspend(); |
264 | at91_irq_suspend(); | 210 | at91_irq_suspend(); |
265 | 211 | ||
@@ -315,9 +261,9 @@ static int at91_pm_enter(suspend_state_t state) | |||
315 | */ | 261 | */ |
316 | asm("b 1f; .align 5; 1:"); | 262 | asm("b 1f; .align 5; 1:"); |
317 | asm("mcr p15, 0, r0, c7, c10, 4"); /* drain write buffer */ | 263 | asm("mcr p15, 0, r0, c7, c10, 4"); /* drain write buffer */ |
318 | sdram_selfrefresh_enable(); | 264 | saved_lpr = sdram_selfrefresh_enable(); |
319 | asm("mcr p15, 0, r0, c7, c0, 4"); /* wait for interrupt */ | 265 | asm("mcr p15, 0, r0, c7, c0, 4"); /* wait for interrupt */ |
320 | sdram_selfrefresh_disable(); | 266 | sdram_selfrefresh_disable(saved_lpr); |
321 | break; | 267 | break; |
322 | 268 | ||
323 | case PM_SUSPEND_ON: | 269 | case PM_SUSPEND_ON: |
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h new file mode 100644 index 000000000000..08322c44df1a --- /dev/null +++ b/arch/arm/mach-at91/pm.h | |||
@@ -0,0 +1,67 @@ | |||
1 | #ifdef CONFIG_ARCH_AT91RM9200 | ||
2 | #include <mach/at91rm9200_mc.h> | ||
3 | |||
4 | /* | ||
5 | * The AT91RM9200 goes into self-refresh mode with this command, and will | ||
6 | * terminate self-refresh automatically on the next SDRAM access. | ||
7 | * | ||
8 | * Self-refresh mode is exited as soon as a memory access is made, but we don't | ||
9 | * know for sure when that happens. However, we need to restore the low-power | ||
10 | * mode if it was enabled before going idle. Restoring low-power mode while | ||
11 | * still in self-refresh is "not recommended", but seems to work. | ||
12 | */ | ||
13 | |||
14 | static inline u32 sdram_selfrefresh_enable(void) | ||
15 | { | ||
16 | u32 saved_lpr = at91_sys_read(AT91_SDRAMC_LPR); | ||
17 | |||
18 | at91_sys_write(AT91_SDRAMC_LPR, 0); | ||
19 | at91_sys_write(AT91_SDRAMC_SRR, 1); | ||
20 | return saved_lpr; | ||
21 | } | ||
22 | |||
23 | #define sdram_selfrefresh_disable(saved_lpr) at91_sys_write(AT91_SDRAMC_LPR, saved_lpr) | ||
24 | |||
25 | #elif defined(CONFIG_ARCH_AT91CAP9) | ||
26 | #include <mach/at91cap9_ddrsdr.h> | ||
27 | |||
28 | |||
29 | static inline u32 sdram_selfrefresh_enable(void) | ||
30 | { | ||
31 | u32 saved_lpr, lpr; | ||
32 | |||
33 | saved_lpr = at91_sys_read(AT91_DDRSDRC_LPR); | ||
34 | |||
35 | lpr = saved_lpr & ~AT91_DDRSDRC_LPCB; | ||
36 | at91_sys_write(AT91_DDRSDRC_LPR, lpr | AT91_DDRSDRC_LPCB_SELF_REFRESH); | ||
37 | return saved_lpr; | ||
38 | } | ||
39 | |||
40 | #define sdram_selfrefresh_disable(saved_lpr) at91_sys_write(AT91_DDRSDRC_LPR, saved_lpr) | ||
41 | |||
42 | #else | ||
43 | #include <mach/at91sam9_sdramc.h> | ||
44 | |||
45 | #ifdef CONFIG_ARCH_AT91SAM9263 | ||
46 | /* | ||
47 | * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use; | ||
48 | * handle those cases both here and in the Suspend-To-RAM support. | ||
49 | */ | ||
50 | #define AT91_SDRAMC AT91_SDRAMC0 | ||
51 | #warning Assuming EB1 SDRAM controller is *NOT* used | ||
52 | #endif | ||
53 | |||
54 | static inline u32 sdram_selfrefresh_enable(void) | ||
55 | { | ||
56 | u32 saved_lpr, lpr; | ||
57 | |||
58 | saved_lpr = at91_sys_read(AT91_SDRAMC_LPR); | ||
59 | |||
60 | lpr = saved_lpr & ~AT91_SDRAMC_LPCB; | ||
61 | at91_sys_write(AT91_SDRAMC_LPR, lpr | AT91_SDRAMC_LPCB_SELF_REFRESH); | ||
62 | return saved_lpr; | ||
63 | } | ||
64 | |||
65 | #define sdram_selfrefresh_disable(saved_lpr) at91_sys_write(AT91_SDRAMC_LPR, saved_lpr) | ||
66 | |||
67 | #endif | ||
diff --git a/arch/arm/mach-bcmring/include/mach/io.h b/arch/arm/mach-bcmring/include/mach/io.h index 4db0eff90357..dae5e9b166ea 100644 --- a/arch/arm/mach-bcmring/include/mach/io.h +++ b/arch/arm/mach-bcmring/include/mach/io.h | |||
@@ -23,34 +23,11 @@ | |||
23 | 23 | ||
24 | #define IO_SPACE_LIMIT 0xffffffff | 24 | #define IO_SPACE_LIMIT 0xffffffff |
25 | 25 | ||
26 | #define __io(a) ((void __iomem *)HW_IO_PHYS_TO_VIRT(a)) | 26 | /* |
27 | 27 | * We don't actually have real ISA nor PCI buses, but there is so many | |
28 | /* Do not enable mem_pci for a big endian arm architecture or unexpected byteswaps will */ | 28 | * drivers out there that might just work if we fake them... |
29 | /* happen in readw/writew etc. */ | 29 | */ |
30 | 30 | #define __io(a) __typesafe_io(a) | |
31 | #define readb(c) __raw_readb(c) | 31 | #define __mem_pci(a) (a) |
32 | #define readw(c) __raw_readw(c) | ||
33 | #define readl(c) __raw_readl(c) | ||
34 | #define readb_relaxed(addr) readb(addr) | ||
35 | #define readw_relaxed(addr) readw(addr) | ||
36 | #define readl_relaxed(addr) readl(addr) | ||
37 | |||
38 | #define readsb(p, d, l) __raw_readsb(p, d, l) | ||
39 | #define readsw(p, d, l) __raw_readsw(p, d, l) | ||
40 | #define readsl(p, d, l) __raw_readsl(p, d, l) | ||
41 | |||
42 | #define writeb(v, c) __raw_writeb(v, c) | ||
43 | #define writew(v, c) __raw_writew(v, c) | ||
44 | #define writel(v, c) __raw_writel(v, c) | ||
45 | |||
46 | #define writesb(p, d, l) __raw_writesb(p, d, l) | ||
47 | #define writesw(p, d, l) __raw_writesw(p, d, l) | ||
48 | #define writesl(p, d, l) __raw_writesl(p, d, l) | ||
49 | |||
50 | #define memset_io(c, v, l) _memset_io((c), (v), (l)) | ||
51 | #define memcpy_fromio(a, c, l) _memcpy_fromio((a), (c), (l)) | ||
52 | #define memcpy_toio(c, a, l) _memcpy_toio((c), (a), (l)) | ||
53 | |||
54 | #define eth_io_copy_and_sum(s, c, l, b) eth_copy_and_sum((s), (c), (l), (b)) | ||
55 | 32 | ||
56 | #endif | 33 | #endif |
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index b4357c388d2e..1f0d66561bbe 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c | |||
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | #include <mach/hardware.h> | 32 | #include <mach/hardware.h> |
33 | #include <mach/fb.h> | 33 | #include <mach/fb.h> |
34 | #include <mach/ep93xx_keypad.h> | ||
34 | 35 | ||
35 | #include <asm/mach/map.h> | 36 | #include <asm/mach/map.h> |
36 | #include <asm/mach/time.h> | 37 | #include <asm/mach/time.h> |
@@ -728,6 +729,82 @@ void __init ep93xx_register_fb(struct ep93xxfb_mach_info *data) | |||
728 | platform_device_register(&ep93xx_fb_device); | 729 | platform_device_register(&ep93xx_fb_device); |
729 | } | 730 | } |
730 | 731 | ||
732 | |||
733 | /************************************************************************* | ||
734 | * EP93xx matrix keypad peripheral handling | ||
735 | *************************************************************************/ | ||
736 | static struct resource ep93xx_keypad_resource[] = { | ||
737 | { | ||
738 | .start = EP93XX_KEY_MATRIX_PHYS_BASE, | ||
739 | .end = EP93XX_KEY_MATRIX_PHYS_BASE + 0x0c - 1, | ||
740 | .flags = IORESOURCE_MEM, | ||
741 | }, { | ||
742 | .start = IRQ_EP93XX_KEY, | ||
743 | .end = IRQ_EP93XX_KEY, | ||
744 | .flags = IORESOURCE_IRQ, | ||
745 | }, | ||
746 | }; | ||
747 | |||
748 | static struct platform_device ep93xx_keypad_device = { | ||
749 | .name = "ep93xx-keypad", | ||
750 | .id = -1, | ||
751 | .num_resources = ARRAY_SIZE(ep93xx_keypad_resource), | ||
752 | .resource = ep93xx_keypad_resource, | ||
753 | }; | ||
754 | |||
755 | void __init ep93xx_register_keypad(struct ep93xx_keypad_platform_data *data) | ||
756 | { | ||
757 | ep93xx_keypad_device.dev.platform_data = data; | ||
758 | platform_device_register(&ep93xx_keypad_device); | ||
759 | } | ||
760 | |||
761 | int ep93xx_keypad_acquire_gpio(struct platform_device *pdev) | ||
762 | { | ||
763 | int err; | ||
764 | int i; | ||
765 | |||
766 | for (i = 0; i < 8; i++) { | ||
767 | err = gpio_request(EP93XX_GPIO_LINE_C(i), dev_name(&pdev->dev)); | ||
768 | if (err) | ||
769 | goto fail_gpio_c; | ||
770 | err = gpio_request(EP93XX_GPIO_LINE_D(i), dev_name(&pdev->dev)); | ||
771 | if (err) | ||
772 | goto fail_gpio_d; | ||
773 | } | ||
774 | |||
775 | /* Enable the keypad controller; GPIO ports C and D used for keypad */ | ||
776 | ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_KEYS | | ||
777 | EP93XX_SYSCON_DEVCFG_GONK); | ||
778 | |||
779 | return 0; | ||
780 | |||
781 | fail_gpio_d: | ||
782 | gpio_free(EP93XX_GPIO_LINE_C(i)); | ||
783 | fail_gpio_c: | ||
784 | for ( ; i >= 0; --i) { | ||
785 | gpio_free(EP93XX_GPIO_LINE_C(i)); | ||
786 | gpio_free(EP93XX_GPIO_LINE_D(i)); | ||
787 | } | ||
788 | return err; | ||
789 | } | ||
790 | EXPORT_SYMBOL(ep93xx_keypad_acquire_gpio); | ||
791 | |||
792 | void ep93xx_keypad_release_gpio(struct platform_device *pdev) | ||
793 | { | ||
794 | int i; | ||
795 | |||
796 | for (i = 0; i < 8; i++) { | ||
797 | gpio_free(EP93XX_GPIO_LINE_C(i)); | ||
798 | gpio_free(EP93XX_GPIO_LINE_D(i)); | ||
799 | } | ||
800 | |||
801 | /* Disable the keypad controller; GPIO ports C and D used for GPIO */ | ||
802 | ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_KEYS | | ||
803 | EP93XX_SYSCON_DEVCFG_GONK); | ||
804 | } | ||
805 | EXPORT_SYMBOL(ep93xx_keypad_release_gpio); | ||
806 | |||
807 | |||
731 | extern void ep93xx_gpio_init(void); | 808 | extern void ep93xx_gpio_init(void); |
732 | 809 | ||
733 | void __init ep93xx_init_devices(void) | 810 | void __init ep93xx_init_devices(void) |
diff --git a/arch/arm/mach-ep93xx/include/mach/clkdev.h b/arch/arm/mach-ep93xx/include/mach/clkdev.h index 04b37a89801c..50cb991eadeb 100644 --- a/arch/arm/mach-ep93xx/include/mach/clkdev.h +++ b/arch/arm/mach-ep93xx/include/mach/clkdev.h | |||
@@ -1,3 +1,7 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-ep93xx/include/mach/clkdev.h | ||
3 | */ | ||
4 | |||
1 | #ifndef __ASM_MACH_CLKDEV_H | 5 | #ifndef __ASM_MACH_CLKDEV_H |
2 | #define __ASM_MACH_CLKDEV_H | 6 | #define __ASM_MACH_CLKDEV_H |
3 | 7 | ||
diff --git a/arch/arm/mach-ep93xx/include/mach/dma.h b/arch/arm/mach-ep93xx/include/mach/dma.h index ef6bd9d13148..3a5961d3f3b1 100644 --- a/arch/arm/mach-ep93xx/include/mach/dma.h +++ b/arch/arm/mach-ep93xx/include/mach/dma.h | |||
@@ -1,3 +1,7 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-ep93xx/include/mach/dma.h | ||
3 | */ | ||
4 | |||
1 | #ifndef __ASM_ARCH_DMA_H | 5 | #ifndef __ASM_ARCH_DMA_H |
2 | #define __ASM_ARCH_DMA_H | 6 | #define __ASM_ARCH_DMA_H |
3 | 7 | ||
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h index b1f937eda29c..d55194a4c093 100644 --- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h +++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h | |||
@@ -134,6 +134,7 @@ | |||
134 | #define EP93XX_UART3_PHYS_BASE EP93XX_APB_PHYS(0x000e0000) | 134 | #define EP93XX_UART3_PHYS_BASE EP93XX_APB_PHYS(0x000e0000) |
135 | #define EP93XX_UART3_BASE EP93XX_APB_IOMEM(0x000e0000) | 135 | #define EP93XX_UART3_BASE EP93XX_APB_IOMEM(0x000e0000) |
136 | 136 | ||
137 | #define EP93XX_KEY_MATRIX_PHYS_BASE EP93XX_APB_PHYS(0x000f0000) | ||
137 | #define EP93XX_KEY_MATRIX_BASE EP93XX_APB_IOMEM(0x000f0000) | 138 | #define EP93XX_KEY_MATRIX_BASE EP93XX_APB_IOMEM(0x000f0000) |
138 | 139 | ||
139 | #define EP93XX_ADC_BASE EP93XX_APB_IOMEM(0x00100000) | 140 | #define EP93XX_ADC_BASE EP93XX_APB_IOMEM(0x00100000) |
diff --git a/arch/arm/mach-ep93xx/include/mach/hardware.h b/arch/arm/mach-ep93xx/include/mach/hardware.h index 349fa7cb72d5..5a3ce024b593 100644 --- a/arch/arm/mach-ep93xx/include/mach/hardware.h +++ b/arch/arm/mach-ep93xx/include/mach/hardware.h | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * arch/arm/mach-ep93xx/include/mach/hardware.h | 2 | * arch/arm/mach-ep93xx/include/mach/hardware.h |
3 | */ | 3 | */ |
4 | |||
4 | #ifndef __ASM_ARCH_HARDWARE_H | 5 | #ifndef __ASM_ARCH_HARDWARE_H |
5 | #define __ASM_ARCH_HARDWARE_H | 6 | #define __ASM_ARCH_HARDWARE_H |
6 | 7 | ||
diff --git a/arch/arm/mach-ep93xx/include/mach/io.h b/arch/arm/mach-ep93xx/include/mach/io.h index cebcc1c53d63..594b77f21054 100644 --- a/arch/arm/mach-ep93xx/include/mach/io.h +++ b/arch/arm/mach-ep93xx/include/mach/io.h | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * arch/arm/mach-ep93xx/include/mach/io.h | 2 | * arch/arm/mach-ep93xx/include/mach/io.h |
3 | */ | 3 | */ |
4 | |||
4 | #ifndef __ASM_MACH_IO_H | 5 | #ifndef __ASM_MACH_IO_H |
5 | #define __ASM_MACH_IO_H | 6 | #define __ASM_MACH_IO_H |
6 | 7 | ||
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h index 469fd968d517..c6dc14dbca18 100644 --- a/arch/arm/mach-ep93xx/include/mach/platform.h +++ b/arch/arm/mach-ep93xx/include/mach/platform.h | |||
@@ -8,6 +8,7 @@ struct i2c_gpio_platform_data; | |||
8 | struct i2c_board_info; | 8 | struct i2c_board_info; |
9 | struct platform_device; | 9 | struct platform_device; |
10 | struct ep93xxfb_mach_info; | 10 | struct ep93xxfb_mach_info; |
11 | struct ep93xx_keypad_platform_data; | ||
11 | 12 | ||
12 | struct ep93xx_eth_data | 13 | struct ep93xx_eth_data |
13 | { | 14 | { |
@@ -39,6 +40,9 @@ void ep93xx_register_fb(struct ep93xxfb_mach_info *data); | |||
39 | void ep93xx_register_pwm(int pwm0, int pwm1); | 40 | void ep93xx_register_pwm(int pwm0, int pwm1); |
40 | int ep93xx_pwm_acquire_gpio(struct platform_device *pdev); | 41 | int ep93xx_pwm_acquire_gpio(struct platform_device *pdev); |
41 | void ep93xx_pwm_release_gpio(struct platform_device *pdev); | 42 | void ep93xx_pwm_release_gpio(struct platform_device *pdev); |
43 | void ep93xx_register_keypad(struct ep93xx_keypad_platform_data *data); | ||
44 | int ep93xx_keypad_acquire_gpio(struct platform_device *pdev); | ||
45 | void ep93xx_keypad_release_gpio(struct platform_device *pdev); | ||
42 | 46 | ||
43 | void ep93xx_init_devices(void); | 47 | void ep93xx_init_devices(void); |
44 | extern struct sys_timer ep93xx_timer; | 48 | extern struct sys_timer ep93xx_timer; |
diff --git a/arch/arm/mach-iop13xx/include/mach/memory.h b/arch/arm/mach-iop13xx/include/mach/memory.h index 42ae29b288a1..25b1da9a5035 100644 --- a/arch/arm/mach-iop13xx/include/mach/memory.h +++ b/arch/arm/mach-iop13xx/include/mach/memory.h | |||
@@ -64,6 +64,8 @@ static inline unsigned long __lbus_to_virt(dma_addr_t x) | |||
64 | (dma_addr_t)page_to_phys(page); \ | 64 | (dma_addr_t)page_to_phys(page); \ |
65 | }) | 65 | }) |
66 | 66 | ||
67 | #define __arch_dma_to_page(dev, addr) phys_to_page(addr) | ||
68 | |||
67 | #endif /* CONFIG_ARCH_IOP13XX */ | 69 | #endif /* CONFIG_ARCH_IOP13XX */ |
68 | #endif /* !ASSEMBLY */ | 70 | #endif /* !ASSEMBLY */ |
69 | 71 | ||
diff --git a/arch/arm/mach-ks8695/include/mach/memory.h b/arch/arm/mach-ks8695/include/mach/memory.h index 76e5308685a4..ffa19aae6e05 100644 --- a/arch/arm/mach-ks8695/include/mach/memory.h +++ b/arch/arm/mach-ks8695/include/mach/memory.h | |||
@@ -41,6 +41,13 @@ extern struct bus_type platform_bus_type; | |||
41 | __dma = __dma - PHYS_OFFSET + KS8695_PCIMEM_PA; \ | 41 | __dma = __dma - PHYS_OFFSET + KS8695_PCIMEM_PA; \ |
42 | __dma; }) | 42 | __dma; }) |
43 | 43 | ||
44 | #define __arch_dma_to_page(dev, x) \ | ||
45 | ({ dma_addr_t __dma = x; \ | ||
46 | if (!is_lbus_device(dev)) \ | ||
47 | __dma += PHYS_OFFSET - KS8695_PCIMEM_PA; \ | ||
48 | phys_to_page(__dma); \ | ||
49 | }) | ||
50 | |||
44 | #endif | 51 | #endif |
45 | 52 | ||
46 | #endif | 53 | #endif |
diff --git a/arch/arm/mach-nomadik/Kconfig b/arch/arm/mach-nomadik/Kconfig index 2a02b49c40f0..3c5e0f522e9c 100644 --- a/arch/arm/mach-nomadik/Kconfig +++ b/arch/arm/mach-nomadik/Kconfig | |||
@@ -5,13 +5,13 @@ menu "Nomadik boards" | |||
5 | config MACH_NOMADIK_8815NHK | 5 | config MACH_NOMADIK_8815NHK |
6 | bool "ST 8815 Nomadik Hardware Kit (evaluation board)" | 6 | bool "ST 8815 Nomadik Hardware Kit (evaluation board)" |
7 | select NOMADIK_8815 | 7 | select NOMADIK_8815 |
8 | select HAS_MTU | ||
8 | 9 | ||
9 | endmenu | 10 | endmenu |
10 | 11 | ||
11 | config NOMADIK_8815 | 12 | config NOMADIK_8815 |
12 | bool | 13 | bool |
13 | 14 | ||
14 | |||
15 | config I2C_BITBANG_8815NHK | 15 | config I2C_BITBANG_8815NHK |
16 | tristate "Driver for bit-bang busses found on the 8815 NHK" | 16 | tristate "Driver for bit-bang busses found on the 8815 NHK" |
17 | depends on I2C && MACH_NOMADIK_8815NHK | 17 | depends on I2C && MACH_NOMADIK_8815NHK |
diff --git a/arch/arm/mach-nomadik/Makefile b/arch/arm/mach-nomadik/Makefile index 412040982a40..36f67fb207d2 100644 --- a/arch/arm/mach-nomadik/Makefile +++ b/arch/arm/mach-nomadik/Makefile | |||
@@ -7,7 +7,7 @@ | |||
7 | 7 | ||
8 | # Object file lists. | 8 | # Object file lists. |
9 | 9 | ||
10 | obj-y += clock.o timer.o gpio.o | 10 | obj-y += clock.o gpio.o |
11 | 11 | ||
12 | # Cpu revision | 12 | # Cpu revision |
13 | obj-$(CONFIG_NOMADIK_8815) += cpu-8815.o | 13 | obj-$(CONFIG_NOMADIK_8815) += cpu-8815.o |
diff --git a/arch/arm/mach-nomadik/board-nhk8815.c b/arch/arm/mach-nomadik/board-nhk8815.c index 6bfd537d5afb..116394484e71 100644 --- a/arch/arm/mach-nomadik/board-nhk8815.c +++ b/arch/arm/mach-nomadik/board-nhk8815.c | |||
@@ -25,11 +25,18 @@ | |||
25 | #include <asm/mach/arch.h> | 25 | #include <asm/mach/arch.h> |
26 | #include <asm/mach/irq.h> | 26 | #include <asm/mach/irq.h> |
27 | #include <asm/mach/flash.h> | 27 | #include <asm/mach/flash.h> |
28 | |||
29 | #include <plat/mtu.h> | ||
30 | |||
28 | #include <mach/setup.h> | 31 | #include <mach/setup.h> |
29 | #include <mach/nand.h> | 32 | #include <mach/nand.h> |
30 | #include <mach/fsmc.h> | 33 | #include <mach/fsmc.h> |
31 | #include "clock.h" | 34 | #include "clock.h" |
32 | 35 | ||
36 | /* Initial value for SRC control register: all timers use MXTAL/8 source */ | ||
37 | #define SRC_CR_INIT_MASK 0x00007fff | ||
38 | #define SRC_CR_INIT_VAL 0x2aaa8000 | ||
39 | |||
33 | /* These adresses span 16MB, so use three individual pages */ | 40 | /* These adresses span 16MB, so use three individual pages */ |
34 | static struct resource nhk8815_nand_resources[] = { | 41 | static struct resource nhk8815_nand_resources[] = { |
35 | { | 42 | { |
@@ -239,6 +246,26 @@ static struct platform_device *nhk8815_platform_devices[] __initdata = { | |||
239 | /* will add more devices */ | 246 | /* will add more devices */ |
240 | }; | 247 | }; |
241 | 248 | ||
249 | static void __init nomadik_timer_init(void) | ||
250 | { | ||
251 | u32 src_cr; | ||
252 | |||
253 | /* Configure timer sources in "system reset controller" ctrl reg */ | ||
254 | src_cr = readl(io_p2v(NOMADIK_SRC_BASE)); | ||
255 | src_cr &= SRC_CR_INIT_MASK; | ||
256 | src_cr |= SRC_CR_INIT_VAL; | ||
257 | writel(src_cr, io_p2v(NOMADIK_SRC_BASE)); | ||
258 | |||
259 | /* Save global pointer to mtu, used by platform timer code */ | ||
260 | mtu_base = io_p2v(NOMADIK_MTU0_BASE); | ||
261 | |||
262 | nmdk_timer_init(); | ||
263 | } | ||
264 | |||
265 | static struct sys_timer nomadik_timer = { | ||
266 | .init = nomadik_timer_init, | ||
267 | }; | ||
268 | |||
242 | static void __init nhk8815_platform_init(void) | 269 | static void __init nhk8815_platform_init(void) |
243 | { | 270 | { |
244 | int i; | 271 | int i; |
diff --git a/arch/arm/mach-nomadik/include/mach/setup.h b/arch/arm/mach-nomadik/include/mach/setup.h index a4e468cf63da..b7897edf1f35 100644 --- a/arch/arm/mach-nomadik/include/mach/setup.h +++ b/arch/arm/mach-nomadik/include/mach/setup.h | |||
@@ -15,7 +15,7 @@ | |||
15 | extern void cpu8815_map_io(void); | 15 | extern void cpu8815_map_io(void); |
16 | extern void cpu8815_platform_init(void); | 16 | extern void cpu8815_platform_init(void); |
17 | extern void cpu8815_init_irq(void); | 17 | extern void cpu8815_init_irq(void); |
18 | extern struct sys_timer nomadik_timer; | 18 | extern void nmdk_timer_init(void); |
19 | 19 | ||
20 | #endif /* NOMADIK_8815 */ | 20 | #endif /* NOMADIK_8815 */ |
21 | 21 | ||
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index aad194f61a33..6f1bbbc4d15f 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig | |||
@@ -100,3 +100,11 @@ config MACH_OMAP_ZOOM2 | |||
100 | config MACH_OMAP_4430SDP | 100 | config MACH_OMAP_4430SDP |
101 | bool "OMAP 4430 SDP board" | 101 | bool "OMAP 4430 SDP board" |
102 | depends on ARCH_OMAP4 | 102 | depends on ARCH_OMAP4 |
103 | |||
104 | config OMAP3_EMU | ||
105 | bool "OMAP3 debugging peripherals" | ||
106 | depends on ARCH_OMAP3 | ||
107 | select OC_ETM | ||
108 | help | ||
109 | Say Y here to enable debugging hardware of omap3 | ||
110 | |||
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 8cb16777661a..e141cabcfcce 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile | |||
@@ -44,6 +44,9 @@ obj-$(CONFIG_ARCH_OMAP4) += cm4xxx.o | |||
44 | obj-$(CONFIG_ARCH_OMAP2) += clock24xx.o | 44 | obj-$(CONFIG_ARCH_OMAP2) += clock24xx.o |
45 | obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o | 45 | obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o |
46 | 46 | ||
47 | # EMU peripherals | ||
48 | obj-$(CONFIG_OMAP3_EMU) += emu.o | ||
49 | |||
47 | iommu-y += iommu2.o | 50 | iommu-y += iommu2.o |
48 | iommu-$(CONFIG_ARCH_OMAP3) += omap3-iommu.o | 51 | iommu-$(CONFIG_ARCH_OMAP3) += omap3-iommu.o |
49 | 52 | ||
diff --git a/arch/arm/mach-omap2/clock34xx.c b/arch/arm/mach-omap2/clock34xx.c index 7c5c00df3c70..066e88a18824 100644 --- a/arch/arm/mach-omap2/clock34xx.c +++ b/arch/arm/mach-omap2/clock34xx.c | |||
@@ -119,7 +119,7 @@ static struct omap_clk omap34xx_clks[] = { | |||
119 | CLK(NULL, "dpll3_m2x2_ck", &dpll3_m2x2_ck, CK_343X), | 119 | CLK(NULL, "dpll3_m2x2_ck", &dpll3_m2x2_ck, CK_343X), |
120 | CLK(NULL, "dpll3_m3_ck", &dpll3_m3_ck, CK_343X), | 120 | CLK(NULL, "dpll3_m3_ck", &dpll3_m3_ck, CK_343X), |
121 | CLK(NULL, "dpll3_m3x2_ck", &dpll3_m3x2_ck, CK_343X), | 121 | CLK(NULL, "dpll3_m3x2_ck", &dpll3_m3x2_ck, CK_343X), |
122 | CLK(NULL, "emu_core_alwon_ck", &emu_core_alwon_ck, CK_343X), | 122 | CLK("etb", "emu_core_alwon_ck", &emu_core_alwon_ck, CK_343X), |
123 | CLK(NULL, "dpll4_ck", &dpll4_ck, CK_343X), | 123 | CLK(NULL, "dpll4_ck", &dpll4_ck, CK_343X), |
124 | CLK(NULL, "dpll4_x2_ck", &dpll4_x2_ck, CK_343X), | 124 | CLK(NULL, "dpll4_x2_ck", &dpll4_x2_ck, CK_343X), |
125 | CLK(NULL, "omap_96m_alwon_fck", &omap_96m_alwon_fck, CK_343X), | 125 | CLK(NULL, "omap_96m_alwon_fck", &omap_96m_alwon_fck, CK_343X), |
@@ -138,7 +138,7 @@ static struct omap_clk omap34xx_clks[] = { | |||
138 | CLK(NULL, "dpll4_m5x2_ck", &dpll4_m5x2_ck, CK_343X), | 138 | CLK(NULL, "dpll4_m5x2_ck", &dpll4_m5x2_ck, CK_343X), |
139 | CLK(NULL, "dpll4_m6_ck", &dpll4_m6_ck, CK_343X), | 139 | CLK(NULL, "dpll4_m6_ck", &dpll4_m6_ck, CK_343X), |
140 | CLK(NULL, "dpll4_m6x2_ck", &dpll4_m6x2_ck, CK_343X), | 140 | CLK(NULL, "dpll4_m6x2_ck", &dpll4_m6x2_ck, CK_343X), |
141 | CLK(NULL, "emu_per_alwon_ck", &emu_per_alwon_ck, CK_343X), | 141 | CLK("etb", "emu_per_alwon_ck", &emu_per_alwon_ck, CK_343X), |
142 | CLK(NULL, "dpll5_ck", &dpll5_ck, CK_3430ES2), | 142 | CLK(NULL, "dpll5_ck", &dpll5_ck, CK_3430ES2), |
143 | CLK(NULL, "dpll5_m2_ck", &dpll5_m2_ck, CK_3430ES2), | 143 | CLK(NULL, "dpll5_m2_ck", &dpll5_m2_ck, CK_3430ES2), |
144 | CLK(NULL, "clkout2_src_ck", &clkout2_src_ck, CK_343X), | 144 | CLK(NULL, "clkout2_src_ck", &clkout2_src_ck, CK_343X), |
@@ -147,7 +147,7 @@ static struct omap_clk omap34xx_clks[] = { | |||
147 | CLK(NULL, "dpll1_fck", &dpll1_fck, CK_343X), | 147 | CLK(NULL, "dpll1_fck", &dpll1_fck, CK_343X), |
148 | CLK(NULL, "mpu_ck", &mpu_ck, CK_343X), | 148 | CLK(NULL, "mpu_ck", &mpu_ck, CK_343X), |
149 | CLK(NULL, "arm_fck", &arm_fck, CK_343X), | 149 | CLK(NULL, "arm_fck", &arm_fck, CK_343X), |
150 | CLK(NULL, "emu_mpu_alwon_ck", &emu_mpu_alwon_ck, CK_343X), | 150 | CLK("etb", "emu_mpu_alwon_ck", &emu_mpu_alwon_ck, CK_343X), |
151 | CLK(NULL, "dpll2_fck", &dpll2_fck, CK_343X), | 151 | CLK(NULL, "dpll2_fck", &dpll2_fck, CK_343X), |
152 | CLK(NULL, "iva2_ck", &iva2_ck, CK_343X), | 152 | CLK(NULL, "iva2_ck", &iva2_ck, CK_343X), |
153 | CLK(NULL, "l3_ick", &l3_ick, CK_343X), | 153 | CLK(NULL, "l3_ick", &l3_ick, CK_343X), |
@@ -302,7 +302,7 @@ static struct omap_clk omap34xx_clks[] = { | |||
302 | CLK("omap-mcbsp.2", "fck", &mcbsp2_fck, CK_343X), | 302 | CLK("omap-mcbsp.2", "fck", &mcbsp2_fck, CK_343X), |
303 | CLK("omap-mcbsp.3", "fck", &mcbsp3_fck, CK_343X), | 303 | CLK("omap-mcbsp.3", "fck", &mcbsp3_fck, CK_343X), |
304 | CLK("omap-mcbsp.4", "fck", &mcbsp4_fck, CK_343X), | 304 | CLK("omap-mcbsp.4", "fck", &mcbsp4_fck, CK_343X), |
305 | CLK(NULL, "emu_src_ck", &emu_src_ck, CK_343X), | 305 | CLK("etb", "emu_src_ck", &emu_src_ck, CK_343X), |
306 | CLK(NULL, "pclk_fck", &pclk_fck, CK_343X), | 306 | CLK(NULL, "pclk_fck", &pclk_fck, CK_343X), |
307 | CLK(NULL, "pclkx2_fck", &pclkx2_fck, CK_343X), | 307 | CLK(NULL, "pclkx2_fck", &pclkx2_fck, CK_343X), |
308 | CLK(NULL, "atclk_fck", &atclk_fck, CK_343X), | 308 | CLK(NULL, "atclk_fck", &atclk_fck, CK_343X), |
diff --git a/arch/arm/mach-omap2/emu.c b/arch/arm/mach-omap2/emu.c new file mode 100644 index 000000000000..ec0d984a26fc --- /dev/null +++ b/arch/arm/mach-omap2/emu.c | |||
@@ -0,0 +1,66 @@ | |||
1 | /* | ||
2 | * emu.c | ||
3 | * | ||
4 | * ETM and ETB CoreSight components' resources as found in OMAP3xxx. | ||
5 | * | ||
6 | * Copyright (C) 2009 Nokia Corporation. | ||
7 | * Alexander Shishkin | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/types.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/device.h> | ||
19 | #include <linux/amba/bus.h> | ||
20 | #include <linux/io.h> | ||
21 | #include <linux/clk.h> | ||
22 | #include <linux/err.h> | ||
23 | |||
24 | MODULE_LICENSE("GPL"); | ||
25 | MODULE_AUTHOR("Alexander Shishkin"); | ||
26 | |||
27 | /* Cortex CoreSight components within omap3xxx EMU */ | ||
28 | #define ETM_BASE (L4_EMU_34XX_PHYS + 0x10000) | ||
29 | #define DBG_BASE (L4_EMU_34XX_PHYS + 0x11000) | ||
30 | #define ETB_BASE (L4_EMU_34XX_PHYS + 0x1b000) | ||
31 | #define DAPCTL (L4_EMU_34XX_PHYS + 0x1d000) | ||
32 | |||
33 | static struct amba_device omap3_etb_device = { | ||
34 | .dev = { | ||
35 | .init_name = "etb", | ||
36 | }, | ||
37 | .res = { | ||
38 | .start = ETB_BASE, | ||
39 | .end = ETB_BASE + SZ_4K - 1, | ||
40 | .flags = IORESOURCE_MEM, | ||
41 | }, | ||
42 | .periphid = 0x000bb907, | ||
43 | }; | ||
44 | |||
45 | static struct amba_device omap3_etm_device = { | ||
46 | .dev = { | ||
47 | .init_name = "etm", | ||
48 | }, | ||
49 | .res = { | ||
50 | .start = ETM_BASE, | ||
51 | .end = ETM_BASE + SZ_4K - 1, | ||
52 | .flags = IORESOURCE_MEM, | ||
53 | }, | ||
54 | .periphid = 0x102bb921, | ||
55 | }; | ||
56 | |||
57 | static int __init emu_init(void) | ||
58 | { | ||
59 | amba_device_register(&omap3_etb_device, &iomem_resource); | ||
60 | amba_device_register(&omap3_etm_device, &iomem_resource); | ||
61 | |||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | subsys_initcall(emu_init); | ||
66 | |||
diff --git a/arch/arm/mach-pxa/cpufreq-pxa2xx.c b/arch/arm/mach-pxa/cpufreq-pxa2xx.c index 983cc8c20081..9e4d9816726a 100644 --- a/arch/arm/mach-pxa/cpufreq-pxa2xx.c +++ b/arch/arm/mach-pxa/cpufreq-pxa2xx.c | |||
@@ -447,6 +447,7 @@ static __init int pxa_cpufreq_init(struct cpufreq_policy *policy) | |||
447 | pxa27x_freq_table[i].frequency = freq; | 447 | pxa27x_freq_table[i].frequency = freq; |
448 | pxa27x_freq_table[i].index = i; | 448 | pxa27x_freq_table[i].index = i; |
449 | } | 449 | } |
450 | pxa27x_freq_table[i].index = i; | ||
450 | pxa27x_freq_table[i].frequency = CPUFREQ_TABLE_END; | 451 | pxa27x_freq_table[i].frequency = CPUFREQ_TABLE_END; |
451 | 452 | ||
452 | /* | 453 | /* |
diff --git a/arch/arm/mach-pxa/cpufreq-pxa3xx.c b/arch/arm/mach-pxa/cpufreq-pxa3xx.c index 67f34a8d8e60..149cdd9aee4d 100644 --- a/arch/arm/mach-pxa/cpufreq-pxa3xx.c +++ b/arch/arm/mach-pxa/cpufreq-pxa3xx.c | |||
@@ -102,7 +102,7 @@ static int setup_freqs_table(struct cpufreq_policy *policy, | |||
102 | table[i].index = i; | 102 | table[i].index = i; |
103 | table[i].frequency = freqs[i].cpufreq_mhz * 1000; | 103 | table[i].frequency = freqs[i].cpufreq_mhz * 1000; |
104 | } | 104 | } |
105 | table[num].frequency = i; | 105 | table[num].index = i; |
106 | table[num].frequency = CPUFREQ_TABLE_END; | 106 | table[num].frequency = CPUFREQ_TABLE_END; |
107 | 107 | ||
108 | pxa3xx_freqs = freqs; | 108 | pxa3xx_freqs = freqs; |
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index bbd7a855ae2d..4b50f144fa48 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c | |||
@@ -806,10 +806,12 @@ static void __init spitz_init(void) | |||
806 | { | 806 | { |
807 | spitz_ficp_platform_data.gpio_pwdown = SPITZ_GPIO_IR_ON; | 807 | spitz_ficp_platform_data.gpio_pwdown = SPITZ_GPIO_IR_ON; |
808 | 808 | ||
809 | #ifdef CONFIG_MACH_BORZOI | ||
809 | if (machine_is_borzoi()) { | 810 | if (machine_is_borzoi()) { |
810 | sharpsl_nand_platform_data.badblock_pattern = &sharpsl_akita_bbt; | 811 | sharpsl_nand_platform_data.badblock_pattern = &sharpsl_akita_bbt; |
811 | sharpsl_nand_platform_data.ecc_layout = &akita_oobinfo; | 812 | sharpsl_nand_platform_data.ecc_layout = &akita_oobinfo; |
812 | } | 813 | } |
814 | #endif | ||
813 | 815 | ||
814 | platform_scoop_config = &spitz_pcmcia_config; | 816 | platform_scoop_config = &spitz_pcmcia_config; |
815 | 817 | ||
diff --git a/arch/arm/mach-u300/Makefile b/arch/arm/mach-u300/Makefile index 885b5c027c1e..fab46fe9a71f 100644 --- a/arch/arm/mach-u300/Makefile +++ b/arch/arm/mach-u300/Makefile | |||
@@ -12,3 +12,4 @@ obj-$(CONFIG_MMC) += mmc.o | |||
12 | obj-$(CONFIG_SPI_PL022) += spi.o | 12 | obj-$(CONFIG_SPI_PL022) += spi.o |
13 | obj-$(CONFIG_MACH_U300_SPIDUMMY) += dummyspichip.o | 13 | obj-$(CONFIG_MACH_U300_SPIDUMMY) += dummyspichip.o |
14 | obj-$(CONFIG_I2C_STU300) += i2c.o | 14 | obj-$(CONFIG_I2C_STU300) += i2c.o |
15 | obj-$(CONFIG_REGULATOR_AB3100) += regulator.o | ||
diff --git a/arch/arm/mach-u300/i2c.c b/arch/arm/mach-u300/i2c.c index 10be1f888b27..c73ed06b6065 100644 --- a/arch/arm/mach-u300/i2c.c +++ b/arch/arm/mach-u300/i2c.c | |||
@@ -9,13 +9,257 @@ | |||
9 | */ | 9 | */ |
10 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
11 | #include <linux/i2c.h> | 11 | #include <linux/i2c.h> |
12 | #include <linux/mfd/ab3100.h> | ||
13 | #include <linux/regulator/machine.h> | ||
14 | #include <linux/amba/bus.h> | ||
12 | #include <mach/irqs.h> | 15 | #include <mach/irqs.h> |
13 | 16 | ||
17 | /* | ||
18 | * Initial settings of ab3100 registers. | ||
19 | * Common for below LDO regulator settings are that | ||
20 | * bit 7-5 controls voltage. Bit 4 turns regulator ON(1) or OFF(0). | ||
21 | * Bit 3-2 controls sleep enable and bit 1-0 controls sleep mode. | ||
22 | */ | ||
23 | |||
24 | /* LDO_A 0x16: 2.75V, ON, SLEEP_A, SLEEP OFF GND */ | ||
25 | #define LDO_A_SETTING 0x16 | ||
26 | /* LDO_C 0x10: 2.65V, ON, SLEEP_A or B, SLEEP full power */ | ||
27 | #define LDO_C_SETTING 0x10 | ||
28 | /* LDO_D 0x10: 2.65V, ON, sleep mode not used */ | ||
29 | #define LDO_D_SETTING 0x10 | ||
30 | /* LDO_E 0x10: 1.8V, ON, SLEEP_A or B, SLEEP full power */ | ||
31 | #define LDO_E_SETTING 0x10 | ||
32 | /* LDO_E SLEEP 0x00: 1.8V, not used, SLEEP_A or B, not used */ | ||
33 | #define LDO_E_SLEEP_SETTING 0x00 | ||
34 | /* LDO_F 0xD0: 2.5V, ON, SLEEP_A or B, SLEEP full power */ | ||
35 | #define LDO_F_SETTING 0xD0 | ||
36 | /* LDO_G 0x00: 2.85V, OFF, SLEEP_A or B, SLEEP full power */ | ||
37 | #define LDO_G_SETTING 0x00 | ||
38 | /* LDO_H 0x18: 2.75V, ON, SLEEP_B, SLEEP full power */ | ||
39 | #define LDO_H_SETTING 0x18 | ||
40 | /* LDO_K 0x00: 2.75V, OFF, SLEEP_A or B, SLEEP full power */ | ||
41 | #define LDO_K_SETTING 0x00 | ||
42 | /* LDO_EXT 0x00: Voltage not set, OFF, not used, not used */ | ||
43 | #define LDO_EXT_SETTING 0x00 | ||
44 | /* BUCK 0x7D: 1.2V, ON, SLEEP_A and B, SLEEP low power */ | ||
45 | #define BUCK_SETTING 0x7D | ||
46 | /* BUCK SLEEP 0xAC: 1.05V, Not used, SLEEP_A and B, Not used */ | ||
47 | #define BUCK_SLEEP_SETTING 0xAC | ||
48 | |||
49 | static struct regulator_consumer_supply supply_ldo_c[] = { | ||
50 | { | ||
51 | .dev_name = "ab3100-codec", | ||
52 | .supply = "vaudio", /* Powers the codec */ | ||
53 | }, | ||
54 | }; | ||
55 | |||
56 | /* | ||
57 | * This one needs to be a supply so we can turn it off | ||
58 | * in order to shut down the system. | ||
59 | */ | ||
60 | static struct regulator_consumer_supply supply_ldo_d[] = { | ||
61 | { | ||
62 | .dev = NULL, | ||
63 | .supply = "vana15", /* Powers the SoC (CPU etc) */ | ||
64 | }, | ||
65 | }; | ||
66 | |||
67 | static struct regulator_consumer_supply supply_ldo_g[] = { | ||
68 | { | ||
69 | .dev_name = "mmci", | ||
70 | .supply = "vmmc", /* Powers MMC/SD card */ | ||
71 | }, | ||
72 | }; | ||
73 | |||
74 | static struct regulator_consumer_supply supply_ldo_h[] = { | ||
75 | { | ||
76 | .dev_name = "xgam_pdi", | ||
77 | .supply = "vdisp", /* Powers camera, display etc */ | ||
78 | }, | ||
79 | }; | ||
80 | |||
81 | static struct regulator_consumer_supply supply_ldo_k[] = { | ||
82 | { | ||
83 | .dev_name = "irda", | ||
84 | .supply = "vir", /* Power IrDA */ | ||
85 | }, | ||
86 | }; | ||
87 | |||
88 | /* | ||
89 | * This is a placeholder for whoever wish to use the | ||
90 | * external power. | ||
91 | */ | ||
92 | static struct regulator_consumer_supply supply_ldo_ext[] = { | ||
93 | { | ||
94 | .dev = NULL, | ||
95 | .supply = "vext", /* External power */ | ||
96 | }, | ||
97 | }; | ||
98 | |||
99 | /* Preset (hardware defined) voltages for these regulators */ | ||
100 | #define LDO_A_VOLTAGE 2750000 | ||
101 | #define LDO_C_VOLTAGE 2650000 | ||
102 | #define LDO_D_VOLTAGE 2650000 | ||
103 | |||
104 | static struct ab3100_platform_data ab3100_plf_data = { | ||
105 | .reg_constraints = { | ||
106 | /* LDO A routing and constraints */ | ||
107 | { | ||
108 | .constraints = { | ||
109 | .name = "vrad", | ||
110 | .min_uV = LDO_A_VOLTAGE, | ||
111 | .max_uV = LDO_A_VOLTAGE, | ||
112 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
113 | .always_on = 1, | ||
114 | .boot_on = 1, | ||
115 | }, | ||
116 | }, | ||
117 | /* LDO C routing and constraints */ | ||
118 | { | ||
119 | .constraints = { | ||
120 | .min_uV = LDO_C_VOLTAGE, | ||
121 | .max_uV = LDO_C_VOLTAGE, | ||
122 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
123 | }, | ||
124 | .num_consumer_supplies = ARRAY_SIZE(supply_ldo_c), | ||
125 | .consumer_supplies = supply_ldo_c, | ||
126 | }, | ||
127 | /* LDO D routing and constraints */ | ||
128 | { | ||
129 | .constraints = { | ||
130 | .min_uV = LDO_D_VOLTAGE, | ||
131 | .max_uV = LDO_D_VOLTAGE, | ||
132 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
133 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
134 | /* | ||
135 | * Actually this is boot_on but we need | ||
136 | * to reference count it externally to | ||
137 | * be able to shut down the system. | ||
138 | */ | ||
139 | }, | ||
140 | .num_consumer_supplies = ARRAY_SIZE(supply_ldo_d), | ||
141 | .consumer_supplies = supply_ldo_d, | ||
142 | }, | ||
143 | /* LDO E routing and constraints */ | ||
144 | { | ||
145 | .constraints = { | ||
146 | .name = "vio", | ||
147 | .min_uV = 1800000, | ||
148 | .max_uV = 1800000, | ||
149 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
150 | .valid_ops_mask = | ||
151 | REGULATOR_CHANGE_VOLTAGE | | ||
152 | REGULATOR_CHANGE_STATUS, | ||
153 | .always_on = 1, | ||
154 | .boot_on = 1, | ||
155 | }, | ||
156 | }, | ||
157 | /* LDO F routing and constraints */ | ||
158 | { | ||
159 | .constraints = { | ||
160 | .name = "vana25", | ||
161 | .min_uV = 2500000, | ||
162 | .max_uV = 2500000, | ||
163 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
164 | .valid_ops_mask = | ||
165 | REGULATOR_CHANGE_VOLTAGE | | ||
166 | REGULATOR_CHANGE_STATUS, | ||
167 | .always_on = 1, | ||
168 | .boot_on = 1, | ||
169 | }, | ||
170 | }, | ||
171 | /* LDO G routing and constraints */ | ||
172 | { | ||
173 | .constraints = { | ||
174 | .min_uV = 1500000, | ||
175 | .max_uV = 2850000, | ||
176 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
177 | .valid_ops_mask = | ||
178 | REGULATOR_CHANGE_VOLTAGE | | ||
179 | REGULATOR_CHANGE_STATUS, | ||
180 | }, | ||
181 | .num_consumer_supplies = ARRAY_SIZE(supply_ldo_g), | ||
182 | .consumer_supplies = supply_ldo_g, | ||
183 | }, | ||
184 | /* LDO H routing and constraints */ | ||
185 | { | ||
186 | .constraints = { | ||
187 | .min_uV = 1200000, | ||
188 | .max_uV = 2750000, | ||
189 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
190 | .valid_ops_mask = | ||
191 | REGULATOR_CHANGE_VOLTAGE | | ||
192 | REGULATOR_CHANGE_STATUS, | ||
193 | }, | ||
194 | .num_consumer_supplies = ARRAY_SIZE(supply_ldo_h), | ||
195 | .consumer_supplies = supply_ldo_h, | ||
196 | }, | ||
197 | /* LDO K routing and constraints */ | ||
198 | { | ||
199 | .constraints = { | ||
200 | .min_uV = 1800000, | ||
201 | .max_uV = 2750000, | ||
202 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
203 | .valid_ops_mask = | ||
204 | REGULATOR_CHANGE_VOLTAGE | | ||
205 | REGULATOR_CHANGE_STATUS, | ||
206 | }, | ||
207 | .num_consumer_supplies = ARRAY_SIZE(supply_ldo_k), | ||
208 | .consumer_supplies = supply_ldo_k, | ||
209 | }, | ||
210 | /* External regulator interface. No fixed voltage specified. | ||
211 | * If we knew the voltage of the external regulator and it | ||
212 | * was connected on the board, we could add the (fixed) | ||
213 | * voltage for it here. | ||
214 | */ | ||
215 | { | ||
216 | .constraints = { | ||
217 | .min_uV = 0, | ||
218 | .max_uV = 0, | ||
219 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
220 | .valid_ops_mask = | ||
221 | REGULATOR_CHANGE_STATUS, | ||
222 | }, | ||
223 | .num_consumer_supplies = ARRAY_SIZE(supply_ldo_ext), | ||
224 | .consumer_supplies = supply_ldo_ext, | ||
225 | }, | ||
226 | /* Buck converter routing and constraints */ | ||
227 | { | ||
228 | .constraints = { | ||
229 | .name = "vcore", | ||
230 | .min_uV = 1200000, | ||
231 | .max_uV = 1800000, | ||
232 | .valid_modes_mask = REGULATOR_MODE_NORMAL, | ||
233 | .valid_ops_mask = | ||
234 | REGULATOR_CHANGE_VOLTAGE | | ||
235 | REGULATOR_CHANGE_STATUS, | ||
236 | .always_on = 1, | ||
237 | .boot_on = 1, | ||
238 | }, | ||
239 | }, | ||
240 | }, | ||
241 | .reg_initvals = { | ||
242 | LDO_A_SETTING, | ||
243 | LDO_C_SETTING, | ||
244 | LDO_E_SETTING, | ||
245 | LDO_E_SLEEP_SETTING, | ||
246 | LDO_F_SETTING, | ||
247 | LDO_G_SETTING, | ||
248 | LDO_H_SETTING, | ||
249 | LDO_K_SETTING, | ||
250 | LDO_EXT_SETTING, | ||
251 | BUCK_SETTING, | ||
252 | BUCK_SLEEP_SETTING, | ||
253 | LDO_D_SETTING, | ||
254 | }, | ||
255 | }; | ||
256 | |||
14 | static struct i2c_board_info __initdata bus0_i2c_board_info[] = { | 257 | static struct i2c_board_info __initdata bus0_i2c_board_info[] = { |
15 | { | 258 | { |
16 | .type = "ab3100", | 259 | .type = "ab3100", |
17 | .addr = 0x48, | 260 | .addr = 0x48, |
18 | .irq = IRQ_U300_IRQ0_EXT, | 261 | .irq = IRQ_U300_IRQ0_EXT, |
262 | .platform_data = &ab3100_plf_data, | ||
19 | }, | 263 | }, |
20 | }; | 264 | }; |
21 | 265 | ||
@@ -38,6 +282,11 @@ void __init u300_i2c_register_board_devices(void) | |||
38 | { | 282 | { |
39 | i2c_register_board_info(0, bus0_i2c_board_info, | 283 | i2c_register_board_info(0, bus0_i2c_board_info, |
40 | ARRAY_SIZE(bus0_i2c_board_info)); | 284 | ARRAY_SIZE(bus0_i2c_board_info)); |
285 | /* | ||
286 | * This makes the core shut down all unused regulators | ||
287 | * after all the initcalls have completed. | ||
288 | */ | ||
289 | regulator_has_full_constraints(); | ||
41 | i2c_register_board_info(1, bus1_i2c_board_info, | 290 | i2c_register_board_info(1, bus1_i2c_board_info, |
42 | ARRAY_SIZE(bus1_i2c_board_info)); | 291 | ARRAY_SIZE(bus1_i2c_board_info)); |
43 | } | 292 | } |
diff --git a/arch/arm/mach-u300/mmc.c b/arch/arm/mach-u300/mmc.c index 7b6b016786bb..109f5a6e71c7 100644 --- a/arch/arm/mach-u300/mmc.c +++ b/arch/arm/mach-u300/mmc.c | |||
@@ -40,64 +40,6 @@ static unsigned int mmc_status(struct device *dev) | |||
40 | return mmci_card->mmc_inserted; | 40 | return mmci_card->mmc_inserted; |
41 | } | 41 | } |
42 | 42 | ||
43 | /* | ||
44 | * Here follows a large chunk of code which will only be enabled if you | ||
45 | * have both the AB3100 chip mounted and the MMC subsystem activated. | ||
46 | */ | ||
47 | |||
48 | static u32 mmc_translate_vdd(struct device *dev, unsigned int voltage) | ||
49 | { | ||
50 | int v; | ||
51 | |||
52 | /* | ||
53 | * MMC Spec: | ||
54 | * bit 7: 1.70 - 1.95V | ||
55 | * bit 8 - 14: 2.0 - 2.6V | ||
56 | * bit 15 - 23: 2.7 - 3.6V | ||
57 | * | ||
58 | * ab3100 voltages: | ||
59 | * 000 - 2.85V | ||
60 | * 001 - 2.75V | ||
61 | * 010 - 1.8V | ||
62 | * 011 - 1.5V | ||
63 | */ | ||
64 | switch (voltage) { | ||
65 | case 8: | ||
66 | v = 3; | ||
67 | break; | ||
68 | case 9: | ||
69 | case 10: | ||
70 | case 11: | ||
71 | case 12: | ||
72 | case 13: | ||
73 | case 14: | ||
74 | case 15: | ||
75 | v = 1; | ||
76 | break; | ||
77 | case 16: | ||
78 | v = 1; | ||
79 | break; | ||
80 | case 17: | ||
81 | case 18: | ||
82 | case 19: | ||
83 | case 20: | ||
84 | case 21: | ||
85 | case 22: | ||
86 | case 23: | ||
87 | case 24: | ||
88 | v = 0; | ||
89 | break; | ||
90 | default: | ||
91 | v = 0; | ||
92 | break; | ||
93 | } | ||
94 | |||
95 | /* PL180 voltage register bits */ | ||
96 | return v << 2; | ||
97 | } | ||
98 | |||
99 | |||
100 | |||
101 | static int mmci_callback(void *data) | 43 | static int mmci_callback(void *data) |
102 | { | 44 | { |
103 | struct mmci_card_event *mmci_card = data; | 45 | struct mmci_card_event *mmci_card = data; |
@@ -154,9 +96,11 @@ int __devinit mmc_init(struct amba_device *adev) | |||
154 | if (!mmci_card) | 96 | if (!mmci_card) |
155 | return -ENOMEM; | 97 | return -ENOMEM; |
156 | 98 | ||
99 | /* | ||
100 | * Do not set ocr_mask or voltage translation function, | ||
101 | * we have a regulator we can control instead. | ||
102 | */ | ||
157 | /* Nominally 2.85V on our platform */ | 103 | /* Nominally 2.85V on our platform */ |
158 | mmci_card->mmc0_plat_data.ocr_mask = MMC_VDD_28_29; | ||
159 | mmci_card->mmc0_plat_data.translate_vdd = mmc_translate_vdd; | ||
160 | mmci_card->mmc0_plat_data.status = mmc_status; | 104 | mmci_card->mmc0_plat_data.status = mmc_status; |
161 | mmci_card->mmc0_plat_data.gpio_wp = -1; | 105 | mmci_card->mmc0_plat_data.gpio_wp = -1; |
162 | mmci_card->mmc0_plat_data.gpio_cd = -1; | 106 | mmci_card->mmc0_plat_data.gpio_cd = -1; |
diff --git a/arch/arm/mach-u300/regulator.c b/arch/arm/mach-u300/regulator.c new file mode 100644 index 000000000000..9c53f01c62eb --- /dev/null +++ b/arch/arm/mach-u300/regulator.c | |||
@@ -0,0 +1,88 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-u300/regulator.c | ||
3 | * | ||
4 | * Copyright (C) 2009 ST-Ericsson AB | ||
5 | * License terms: GNU General Public License (GPL) version 2 | ||
6 | * Handle board-bound regulators and board power not related | ||
7 | * to any devices. | ||
8 | * Author: Linus Walleij <linus.walleij@stericsson.com> | ||
9 | */ | ||
10 | #include <linux/device.h> | ||
11 | #include <linux/signal.h> | ||
12 | #include <linux/err.h> | ||
13 | #include <linux/regulator/consumer.h> | ||
14 | /* Those are just for writing in syscon */ | ||
15 | #include <linux/io.h> | ||
16 | #include <mach/hardware.h> | ||
17 | #include <mach/syscon.h> | ||
18 | |||
19 | /* | ||
20 | * Regulators that power the board and chip and which are | ||
21 | * not copuled to specific drivers are hogged in these | ||
22 | * instances. | ||
23 | */ | ||
24 | static struct regulator *main_power_15; | ||
25 | |||
26 | /* | ||
27 | * This function is used from pm.h to shut down the system by | ||
28 | * resetting all regulators in turn and then disable regulator | ||
29 | * LDO D (main power). | ||
30 | */ | ||
31 | void u300_pm_poweroff(void) | ||
32 | { | ||
33 | sigset_t old, all; | ||
34 | |||
35 | sigfillset(&all); | ||
36 | if (!sigprocmask(SIG_BLOCK, &all, &old)) { | ||
37 | /* Disable LDO D to shut down the system */ | ||
38 | if (main_power_15) | ||
39 | regulator_disable(main_power_15); | ||
40 | else | ||
41 | pr_err("regulator not available to shut down system\n"); | ||
42 | (void) sigprocmask(SIG_SETMASK, &old, NULL); | ||
43 | } | ||
44 | return; | ||
45 | } | ||
46 | |||
47 | /* | ||
48 | * Hog the regulators needed to power up the board. | ||
49 | */ | ||
50 | static int __init u300_init_boardpower(void) | ||
51 | { | ||
52 | int err; | ||
53 | u32 val; | ||
54 | |||
55 | pr_info("U300: setting up board power\n"); | ||
56 | main_power_15 = regulator_get(NULL, "vana15"); | ||
57 | if (IS_ERR(main_power_15)) { | ||
58 | pr_err("could not get vana15"); | ||
59 | return PTR_ERR(main_power_15); | ||
60 | } | ||
61 | err = regulator_enable(main_power_15); | ||
62 | if (err) { | ||
63 | pr_err("could not enable vana15\n"); | ||
64 | return err; | ||
65 | } | ||
66 | |||
67 | /* | ||
68 | * On U300 a special system controller register pulls up the DC | ||
69 | * until the vana15 (LDO D) regulator comes up. At this point, all | ||
70 | * regulators are set and we do not need power control via | ||
71 | * DC ON anymore. This function will likely be moved whenever | ||
72 | * the rest of the U300 power management is implemented. | ||
73 | */ | ||
74 | pr_info("U300: disable system controller pull-up\n"); | ||
75 | val = readw(U300_SYSCON_VBASE + U300_SYSCON_PMCR); | ||
76 | val &= ~U300_SYSCON_PMCR_DCON_ENABLE; | ||
77 | writew(val, U300_SYSCON_VBASE + U300_SYSCON_PMCR); | ||
78 | |||
79 | /* Register globally exported PM poweroff hook */ | ||
80 | pm_power_off = u300_pm_poweroff; | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | /* | ||
86 | * So at module init time we hog the regulator! | ||
87 | */ | ||
88 | module_init(u300_init_boardpower); | ||
diff --git a/arch/arm/mach-ux500/Kconfig b/arch/arm/mach-ux500/Kconfig new file mode 100644 index 000000000000..03625d744857 --- /dev/null +++ b/arch/arm/mach-ux500/Kconfig | |||
@@ -0,0 +1,15 @@ | |||
1 | menu "ST-Ericsson platform type" | ||
2 | depends on ARCH_U8500 | ||
3 | |||
4 | comment "ST-Ericsson Multicore Mobile Platforms" | ||
5 | |||
6 | config MACH_U8500_MOP | ||
7 | bool "U8500 Early Development platform" | ||
8 | default y | ||
9 | select ARM_GIC | ||
10 | select HAS_MTU | ||
11 | help | ||
12 | Include support for mop500 development platform | ||
13 | based on U8500 architecture. The platform is based | ||
14 | on early drop silicon version of 8500. | ||
15 | endmenu | ||
diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile new file mode 100644 index 000000000000..95e6e24c0042 --- /dev/null +++ b/arch/arm/mach-ux500/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | # | ||
2 | # Makefile for the linux kernel, U8500 machine. | ||
3 | # | ||
4 | |||
5 | obj-y := clock.o | ||
6 | obj-$(CONFIG_ARCH_U8500) += cpu-u8500.o | ||
7 | obj-$(CONFIG_MACH_U8500_MOP) += board-mop500.o | ||
8 | obj-$(CONFIG_SMP) += platsmp.o headsmp.o localtimer.o | ||
diff --git a/arch/arm/mach-ux500/Makefile.boot b/arch/arm/mach-ux500/Makefile.boot new file mode 100644 index 000000000000..c7e75acfe6c9 --- /dev/null +++ b/arch/arm/mach-ux500/Makefile.boot | |||
@@ -0,0 +1,4 @@ | |||
1 | zreladdr-y := 0x00008000 | ||
2 | params_phys-y := 0x00000100 | ||
3 | initrd_phys-y := 0x00800000 | ||
4 | |||
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c new file mode 100644 index 000000000000..aa5afbcc90f9 --- /dev/null +++ b/arch/arm/mach-ux500/board-mop500.c | |||
@@ -0,0 +1,158 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008-2009 ST-Ericsson | ||
3 | * | ||
4 | * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2, as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/amba/bus.h> | ||
17 | #include <linux/amba/pl022.h> | ||
18 | #include <linux/spi/spi.h> | ||
19 | |||
20 | #include <asm/localtimer.h> | ||
21 | #include <asm/mach-types.h> | ||
22 | #include <asm/mach/arch.h> | ||
23 | |||
24 | #include <plat/mtu.h> | ||
25 | |||
26 | #include <mach/hardware.h> | ||
27 | #include <mach/setup.h> | ||
28 | |||
29 | #define __MEM_4K_RESOURCE(x) \ | ||
30 | .res = {.start = (x), .end = (x) + SZ_4K - 1, .flags = IORESOURCE_MEM} | ||
31 | |||
32 | /* These are active devices on this board */ | ||
33 | static struct amba_device uart0_device = { | ||
34 | .dev = { .init_name = "uart0" }, | ||
35 | __MEM_4K_RESOURCE(U8500_UART0_BASE), | ||
36 | .irq = {IRQ_UART0, NO_IRQ}, | ||
37 | }; | ||
38 | |||
39 | static struct amba_device uart1_device = { | ||
40 | .dev = { .init_name = "uart1" }, | ||
41 | __MEM_4K_RESOURCE(U8500_UART1_BASE), | ||
42 | .irq = {IRQ_UART1, NO_IRQ}, | ||
43 | }; | ||
44 | |||
45 | static struct amba_device uart2_device = { | ||
46 | .dev = { .init_name = "uart2" }, | ||
47 | __MEM_4K_RESOURCE(U8500_UART2_BASE), | ||
48 | .irq = {IRQ_UART2, NO_IRQ}, | ||
49 | }; | ||
50 | |||
51 | static void ab4500_spi_cs_control(u32 command) | ||
52 | { | ||
53 | /* set the FRM signal, which is CS - TODO */ | ||
54 | } | ||
55 | |||
56 | struct pl022_config_chip ab4500_chip_info = { | ||
57 | .lbm = LOOPBACK_DISABLED, | ||
58 | .com_mode = INTERRUPT_TRANSFER, | ||
59 | .iface = SSP_INTERFACE_MOTOROLA_SPI, | ||
60 | /* we can act as master only */ | ||
61 | .hierarchy = SSP_MASTER, | ||
62 | .slave_tx_disable = 0, | ||
63 | .endian_rx = SSP_RX_MSB, | ||
64 | .endian_tx = SSP_TX_MSB, | ||
65 | .data_size = SSP_DATA_BITS_24, | ||
66 | .rx_lev_trig = SSP_RX_1_OR_MORE_ELEM, | ||
67 | .tx_lev_trig = SSP_TX_1_OR_MORE_EMPTY_LOC, | ||
68 | .clk_phase = SSP_CLK_SECOND_EDGE, | ||
69 | .clk_pol = SSP_CLK_POL_IDLE_HIGH, | ||
70 | .cs_control = ab4500_spi_cs_control, | ||
71 | }; | ||
72 | |||
73 | static struct spi_board_info u8500_spi_devices[] = { | ||
74 | { | ||
75 | .modalias = "ab4500", | ||
76 | .controller_data = &ab4500_chip_info, | ||
77 | .max_speed_hz = 12000000, | ||
78 | .bus_num = 0, | ||
79 | .chip_select = 0, | ||
80 | .mode = SPI_MODE_0, | ||
81 | .irq = IRQ_AB4500, | ||
82 | }, | ||
83 | }; | ||
84 | |||
85 | static struct pl022_ssp_controller ssp0_platform_data = { | ||
86 | .bus_id = 0, | ||
87 | /* pl022 not yet supports dma */ | ||
88 | .enable_dma = 0, | ||
89 | /* on this platform, gpio 31,142,144,214 & | ||
90 | * 224 are connected as chip selects | ||
91 | */ | ||
92 | .num_chipselect = 5, | ||
93 | }; | ||
94 | |||
95 | static struct amba_device pl022_device = { | ||
96 | .dev = { | ||
97 | .coherent_dma_mask = ~0, | ||
98 | .init_name = "pl022", | ||
99 | .platform_data = &ssp0_platform_data, | ||
100 | }, | ||
101 | .res = { | ||
102 | .start = U8500_SSP0_BASE, | ||
103 | .end = U8500_SSP0_BASE + SZ_4K - 1, | ||
104 | .flags = IORESOURCE_MEM, | ||
105 | }, | ||
106 | .irq = {IRQ_SSP0, NO_IRQ }, | ||
107 | /* ST-Ericsson modified id */ | ||
108 | .periphid = SSP_PER_ID, | ||
109 | }; | ||
110 | |||
111 | static struct amba_device *amba_devs[] __initdata = { | ||
112 | &uart0_device, | ||
113 | &uart1_device, | ||
114 | &uart2_device, | ||
115 | &pl022_device, | ||
116 | }; | ||
117 | |||
118 | static void __init u8500_timer_init(void) | ||
119 | { | ||
120 | #ifdef CONFIG_LOCAL_TIMERS | ||
121 | /* Setup the local timer base */ | ||
122 | twd_base = __io_address(U8500_TWD_BASE); | ||
123 | #endif | ||
124 | /* Setup the MTU base */ | ||
125 | mtu_base = __io_address(U8500_MTU0_BASE); | ||
126 | |||
127 | nmdk_timer_init(); | ||
128 | } | ||
129 | |||
130 | static struct sys_timer u8500_timer = { | ||
131 | .init = u8500_timer_init, | ||
132 | }; | ||
133 | |||
134 | static void __init u8500_init_machine(void) | ||
135 | { | ||
136 | int i; | ||
137 | |||
138 | /* Register the active AMBA devices on this board */ | ||
139 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) | ||
140 | amba_device_register(amba_devs[i], &iomem_resource); | ||
141 | |||
142 | spi_register_board_info(u8500_spi_devices, | ||
143 | ARRAY_SIZE(u8500_spi_devices)); | ||
144 | |||
145 | u8500_init_devices(); | ||
146 | } | ||
147 | |||
148 | MACHINE_START(U8500, "ST-Ericsson MOP500 platform") | ||
149 | /* Maintainer: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> */ | ||
150 | .phys_io = U8500_UART2_BASE, | ||
151 | .io_pg_offst = (IO_ADDRESS(U8500_UART2_BASE) >> 18) & 0xfffc, | ||
152 | .boot_params = 0x100, | ||
153 | .map_io = u8500_map_io, | ||
154 | .init_irq = u8500_init_irq, | ||
155 | /* we re-use nomadik timer here */ | ||
156 | .timer = &u8500_timer, | ||
157 | .init_machine = u8500_init_machine, | ||
158 | MACHINE_END | ||
diff --git a/arch/arm/mach-ux500/clock.c b/arch/arm/mach-ux500/clock.c new file mode 100644 index 000000000000..20b6ebb6783a --- /dev/null +++ b/arch/arm/mach-ux500/clock.c | |||
@@ -0,0 +1,95 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 ST-Ericsson | ||
3 | * heavily based on realview platform | ||
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 version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | */ | ||
9 | #include <linux/module.h> | ||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/list.h> | ||
12 | #include <linux/errno.h> | ||
13 | #include <linux/err.h> | ||
14 | #include <linux/clk.h> | ||
15 | #include <linux/mutex.h> | ||
16 | |||
17 | #include <asm/clkdev.h> | ||
18 | |||
19 | /* currently the clk structure | ||
20 | * just supports rate. This would | ||
21 | * be extended as and when new devices are | ||
22 | * added - TODO | ||
23 | */ | ||
24 | struct clk { | ||
25 | unsigned long rate; | ||
26 | }; | ||
27 | |||
28 | int clk_enable(struct clk *clk) | ||
29 | { | ||
30 | return 0; | ||
31 | } | ||
32 | EXPORT_SYMBOL(clk_enable); | ||
33 | |||
34 | void clk_disable(struct clk *clk) | ||
35 | { | ||
36 | } | ||
37 | EXPORT_SYMBOL(clk_disable); | ||
38 | |||
39 | unsigned long clk_get_rate(struct clk *clk) | ||
40 | { | ||
41 | return clk->rate; | ||
42 | } | ||
43 | EXPORT_SYMBOL(clk_get_rate); | ||
44 | |||
45 | long clk_round_rate(struct clk *clk, unsigned long rate) | ||
46 | { | ||
47 | /*TODO*/ | ||
48 | return rate; | ||
49 | } | ||
50 | EXPORT_SYMBOL(clk_round_rate); | ||
51 | |||
52 | int clk_set_rate(struct clk *clk, unsigned long rate) | ||
53 | { | ||
54 | clk->rate = rate; | ||
55 | return 0; | ||
56 | } | ||
57 | EXPORT_SYMBOL(clk_set_rate); | ||
58 | |||
59 | /* ssp clock */ | ||
60 | static struct clk ssp_clk = { | ||
61 | .rate = 48000000, | ||
62 | }; | ||
63 | |||
64 | /* fixed clock */ | ||
65 | static struct clk f38_clk = { | ||
66 | .rate = 38400000, | ||
67 | }; | ||
68 | |||
69 | static struct clk_lookup lookups[] = { | ||
70 | { | ||
71 | /* UART0 */ | ||
72 | .dev_id = "uart0", | ||
73 | .clk = &f38_clk, | ||
74 | }, { /* UART1 */ | ||
75 | .dev_id = "uart1", | ||
76 | .clk = &f38_clk, | ||
77 | }, { /* UART2 */ | ||
78 | .dev_id = "uart2", | ||
79 | .clk = &f38_clk, | ||
80 | }, { /* SSP */ | ||
81 | .dev_id = "pl022", | ||
82 | .clk = &ssp_clk, | ||
83 | } | ||
84 | }; | ||
85 | |||
86 | static int __init clk_init(void) | ||
87 | { | ||
88 | int i; | ||
89 | |||
90 | /* register the clock lookups */ | ||
91 | for (i = 0; i < ARRAY_SIZE(lookups); i++) | ||
92 | clkdev_add(&lookups[i]); | ||
93 | return 0; | ||
94 | } | ||
95 | arch_initcall(clk_init); | ||
diff --git a/arch/arm/mach-ux500/cpu-u8500.c b/arch/arm/mach-ux500/cpu-u8500.c new file mode 100644 index 000000000000..5f05e5850f71 --- /dev/null +++ b/arch/arm/mach-ux500/cpu-u8500.c | |||
@@ -0,0 +1,64 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008-2009 ST-Ericsson | ||
3 | * | ||
4 | * Author: Srinidhi KASAGAR <srinidhi.kasagar@stericsson.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2, as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | #include <linux/types.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/device.h> | ||
14 | #include <linux/amba/bus.h> | ||
15 | #include <linux/irq.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | |||
18 | #include <asm/hardware/gic.h> | ||
19 | #include <asm/mach/map.h> | ||
20 | #include <mach/hardware.h> | ||
21 | |||
22 | /* add any platform devices here - TODO */ | ||
23 | static struct platform_device *platform_devs[] __initdata = { | ||
24 | /* yet to be added, add i2c0, gpio.. */ | ||
25 | }; | ||
26 | |||
27 | #define __IO_DEV_DESC(x, sz) { \ | ||
28 | .virtual = IO_ADDRESS(x), \ | ||
29 | .pfn = __phys_to_pfn(x), \ | ||
30 | .length = sz, \ | ||
31 | .type = MT_DEVICE, \ | ||
32 | } | ||
33 | |||
34 | /* minimum static i/o mapping required to boot U8500 platforms */ | ||
35 | static struct map_desc u8500_io_desc[] __initdata = { | ||
36 | __IO_DEV_DESC(U8500_GIC_CPU_BASE, SZ_4K), | ||
37 | __IO_DEV_DESC(U8500_GIC_DIST_BASE, SZ_4K), | ||
38 | __IO_DEV_DESC(U8500_MTU0_BASE, SZ_4K), | ||
39 | __IO_DEV_DESC(U8500_TWD_BASE, SZ_4K), | ||
40 | __IO_DEV_DESC(U8500_SCU_BASE, SZ_4K), | ||
41 | __IO_DEV_DESC(U8500_BACKUPRAM0_BASE, SZ_8K), | ||
42 | }; | ||
43 | |||
44 | void __init u8500_map_io(void) | ||
45 | { | ||
46 | iotable_init(u8500_io_desc, ARRAY_SIZE(u8500_io_desc)); | ||
47 | } | ||
48 | |||
49 | void __init u8500_init_irq(void) | ||
50 | { | ||
51 | gic_dist_init(0, __io_address(U8500_GIC_DIST_BASE), 29); | ||
52 | gic_cpu_init(0, __io_address(U8500_GIC_CPU_BASE)); | ||
53 | } | ||
54 | |||
55 | /* | ||
56 | * This function is called from the board init | ||
57 | */ | ||
58 | void __init u8500_init_devices(void) | ||
59 | { | ||
60 | /* Register the platform devices */ | ||
61 | platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs)); | ||
62 | |||
63 | return ; | ||
64 | } | ||
diff --git a/arch/arm/mach-ux500/headsmp.S b/arch/arm/mach-ux500/headsmp.S new file mode 100644 index 000000000000..a6be2cdf2b2f --- /dev/null +++ b/arch/arm/mach-ux500/headsmp.S | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2009 ST-Ericsson | ||
3 | * This file is based ARM Realview platform | ||
4 | * Copyright (c) 2003 ARM Limited | ||
5 | * All Rights Reserved | ||
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 version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | */ | ||
11 | #include <linux/linkage.h> | ||
12 | #include <linux/init.h> | ||
13 | |||
14 | __INIT | ||
15 | |||
16 | /* | ||
17 | * U8500 specific entry point for secondary CPUs. | ||
18 | */ | ||
19 | ENTRY(u8500_secondary_startup) | ||
20 | mrc p15, 0, r0, c0, c0, 5 | ||
21 | and r0, r0, #15 | ||
22 | adr r4, 1f | ||
23 | ldmia r4, {r5, r6} | ||
24 | sub r4, r4, r5 | ||
25 | add r6, r6, r4 | ||
26 | dsb | ||
27 | pen: ldr r7, [r6] | ||
28 | cmp r7, r0 | ||
29 | bne pen | ||
30 | |||
31 | /* | ||
32 | * we've been released from the holding pen: secondary_stack | ||
33 | * should now contain the SVC stack for this core | ||
34 | */ | ||
35 | b secondary_startup | ||
36 | |||
37 | 1: .long . | ||
38 | .long pen_release | ||
diff --git a/arch/arm/mach-ux500/include/mach/clkdev.h b/arch/arm/mach-ux500/include/mach/clkdev.h new file mode 100644 index 000000000000..04b37a89801c --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/clkdev.h | |||
@@ -0,0 +1,7 @@ | |||
1 | #ifndef __ASM_MACH_CLKDEV_H | ||
2 | #define __ASM_MACH_CLKDEV_H | ||
3 | |||
4 | #define __clk_get(clk) ({ 1; }) | ||
5 | #define __clk_put(clk) do { } while (0) | ||
6 | |||
7 | #endif | ||
diff --git a/arch/arm/mach-ux500/include/mach/debug-macro.S b/arch/arm/mach-ux500/include/mach/debug-macro.S new file mode 100644 index 000000000000..8f21b6a95dce --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/debug-macro.S | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * Debugging macro include header | ||
3 | * | ||
4 | * Copyright (C) 2009 ST-Ericsson | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | */ | ||
11 | .macro addruart,rx | ||
12 | mrc p15, 0, \rx, c1, c0 | ||
13 | tst \rx, #1 @MMU enabled? | ||
14 | moveq \rx, #0x80000000 @MMU off, Physical address | ||
15 | movne \rx, #0xF0000000 @MMU on, Virtual address | ||
16 | orr \rx, \rx, #0x7000 | ||
17 | .endm | ||
18 | |||
19 | #include <asm/hardware/debug-pl01x.S> | ||
diff --git a/arch/arm/mach-ux500/include/mach/entry-macro.S b/arch/arm/mach-ux500/include/mach/entry-macro.S new file mode 100644 index 000000000000..eece3301fef7 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/entry-macro.S | |||
@@ -0,0 +1,89 @@ | |||
1 | /* | ||
2 | * Low-level IRQ helper macros for U8500 platforms | ||
3 | * | ||
4 | * Copyright (C) 2009 ST-Ericsson. | ||
5 | * | ||
6 | * This file is a copy of ARM Realview platform. | ||
7 | * -just satisfied checkpatch script. | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | #include <mach/hardware.h> | ||
14 | #include <asm/hardware/gic.h> | ||
15 | |||
16 | .macro disable_fiq | ||
17 | .endm | ||
18 | |||
19 | .macro get_irqnr_preamble, base, tmp | ||
20 | ldr \base, =IO_ADDRESS(U8500_GIC_CPU_BASE) | ||
21 | .endm | ||
22 | |||
23 | .macro arch_ret_to_user, tmp1, tmp2 | ||
24 | .endm | ||
25 | |||
26 | /* | ||
27 | * The interrupt numbering scheme is defined in the | ||
28 | * interrupt controller spec. To wit: | ||
29 | * | ||
30 | * Interrupts 0-15 are IPI | ||
31 | * 16-28 are reserved | ||
32 | * 29-31 are local. We allow 30 to be used for the watchdog. | ||
33 | * 32-1020 are global | ||
34 | * 1021-1022 are reserved | ||
35 | * 1023 is "spurious" (no interrupt) | ||
36 | * | ||
37 | * For now, we ignore all local interrupts so only return an | ||
38 | * interrupt if it's between 30 and 1020. The test_for_ipi | ||
39 | * routine below will pick up on IPIs. | ||
40 | * | ||
41 | * A simple read from the controller will tell us the number | ||
42 | * of the highest priority enabled interrupt. We then just | ||
43 | * need to check whether it is in the valid range for an | ||
44 | * IRQ (30-1020 inclusive). | ||
45 | */ | ||
46 | |||
47 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | ||
48 | |||
49 | /* bits 12-10 = src CPU, 9-0 = int # */ | ||
50 | ldr \irqstat, [\base, #GIC_CPU_INTACK] | ||
51 | |||
52 | ldr \tmp, =1021 | ||
53 | |||
54 | bic \irqnr, \irqstat, #0x1c00 | ||
55 | |||
56 | cmp \irqnr, #29 | ||
57 | cmpcc \irqnr, \irqnr | ||
58 | cmpne \irqnr, \tmp | ||
59 | cmpcs \irqnr, \irqnr | ||
60 | |||
61 | .endm | ||
62 | |||
63 | /* We assume that irqstat (the raw value of the IRQ | ||
64 | * acknowledge register) is preserved from the macro above. | ||
65 | * If there is an IPI, we immediately signal end of | ||
66 | * interrupt on the controller, since this requires the | ||
67 | * original irqstat value which we won't easily be able | ||
68 | * to recreate later. | ||
69 | */ | ||
70 | |||
71 | .macro test_for_ipi, irqnr, irqstat, base, tmp | ||
72 | bic \irqnr, \irqstat, #0x1c00 | ||
73 | cmp \irqnr, #16 | ||
74 | strcc \irqstat, [\base, #GIC_CPU_EOI] | ||
75 | cmpcs \irqnr, \irqnr | ||
76 | .endm | ||
77 | |||
78 | /* As above, this assumes that irqstat and base | ||
79 | * are preserved.. | ||
80 | */ | ||
81 | |||
82 | .macro test_for_ltirq, irqnr, irqstat, base, tmp | ||
83 | bic \irqnr, \irqstat, #0x1c00 | ||
84 | mov \tmp, #0 | ||
85 | cmp \irqnr, #29 | ||
86 | moveq \tmp, #1 | ||
87 | streq \irqstat, [\base, #GIC_CPU_EOI] | ||
88 | cmp \tmp, #0 | ||
89 | .endm | ||
diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h new file mode 100644 index 000000000000..6da650202dc7 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/hardware.h | |||
@@ -0,0 +1,131 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 ST-Ericsson. | ||
3 | * | ||
4 | * U8500 hardware definitions | ||
5 | * | ||
6 | * This file is licensed under the terms of the GNU General Public | ||
7 | * License version 2. This program is licensed "as is" without any | ||
8 | * warranty of any kind, whether express or implied. | ||
9 | */ | ||
10 | #ifndef __MACH_HARDWARE_H | ||
11 | #define __MACH_HARDWARE_H | ||
12 | |||
13 | /* macros to get at IO space when running virtually | ||
14 | * We dont map all the peripherals, let ioremap do | ||
15 | * this for us. We map only very basic peripherals here. | ||
16 | */ | ||
17 | #define U8500_IO_VIRTUAL 0xf0000000 | ||
18 | #define U8500_IO_PHYSICAL 0xa0000000 | ||
19 | |||
20 | /* this macro is used in assembly, so no cast */ | ||
21 | #define IO_ADDRESS(x) \ | ||
22 | (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + U8500_IO_VIRTUAL) | ||
23 | |||
24 | /* typesafe io address */ | ||
25 | #define __io_address(n) __io(IO_ADDRESS(n)) | ||
26 | |||
27 | /* | ||
28 | * Base address definitions for U8500 Onchip IPs. All the | ||
29 | * peripherals are contained in a single 1 Mbyte region, with | ||
30 | * AHB peripherals at the bottom and APB peripherals at the | ||
31 | * top of the region. PER stands for PERIPHERAL region which | ||
32 | * itself divided into sub regions. | ||
33 | */ | ||
34 | #define U8500_PER3_BASE 0x80000000 | ||
35 | #define U8500_PER2_BASE 0x80110000 | ||
36 | #define U8500_PER1_BASE 0x80120000 | ||
37 | #define U8500_PER4_BASE 0x80150000 | ||
38 | |||
39 | #define U8500_PER6_BASE 0xa03c0000 | ||
40 | #define U8500_PER5_BASE 0xa03e0000 | ||
41 | #define U8500_PER7_BASE 0xa03d0000 | ||
42 | |||
43 | #define U8500_SVA_BASE 0xa0100000 | ||
44 | #define U8500_SIA_BASE 0xa0200000 | ||
45 | |||
46 | #define U8500_SGA_BASE 0xa0300000 | ||
47 | #define U8500_MCDE_BASE 0xa0350000 | ||
48 | #define U8500_DMA_BASE 0xa0362000 | ||
49 | |||
50 | #define U8500_SCU_BASE 0xa0410000 | ||
51 | #define U8500_GIC_CPU_BASE 0xa0410100 | ||
52 | #define U8500_TWD_BASE 0xa0410600 | ||
53 | #define U8500_GIC_DIST_BASE 0xa0411000 | ||
54 | #define U8500_L2CC_BASE 0xa0412000 | ||
55 | |||
56 | #define U8500_TWD_SIZE 0x100 | ||
57 | |||
58 | /* per7 base addressess */ | ||
59 | #define U8500_CR_BASE (U8500_PER7_BASE + 0x8000) | ||
60 | #define U8500_MTU0_BASE (U8500_PER7_BASE + 0xa000) | ||
61 | #define U8500_MTU1_BASE (U8500_PER7_BASE + 0xb000) | ||
62 | #define U8500_TZPC0_BASE (U8500_PER7_BASE + 0xc000) | ||
63 | #define U8500_CLKRST7_BASE (U8500_PER7_BASE + 0xf000) | ||
64 | |||
65 | /* per6 base addressess */ | ||
66 | #define U8500_RNG_BASE (U8500_PER6_BASE + 0x0000) | ||
67 | #define U8500_PKA_BASE (U8500_PER6_BASE + 0x1000) | ||
68 | #define U8500_PKAM_BASE (U8500_PER6_BASE + 0x2000) | ||
69 | #define U8500_CRYPTO0_BASE (U8500_PER6_BASE + 0xa000) | ||
70 | #define U8500_CRYPTO1_BASE (U8500_PER6_BASE + 0xb000) | ||
71 | #define U8500_CLKRST6_BASE (U8500_PER7_BASE + 0xf000) | ||
72 | |||
73 | /* per5 base addressess */ | ||
74 | #define U8500_USBOTG_BASE (U8500_PER5_BASE + 0x00000) | ||
75 | #define U8500_GPIO5_BASE (U8500_PER5_BASE + 0x1e000) | ||
76 | #define U8500_CLKRST5_BASE (U8500_PER7_BASE + 0x1f000) | ||
77 | |||
78 | /* per4 base addressess */ | ||
79 | #define U8500_BACKUPRAM0_BASE (U8500_PER4_BASE + 0x0000) | ||
80 | #define U8500_BACKUPRAM1_BASE (U8500_PER4_BASE + 0x1000) | ||
81 | #define U8500_RTT0_BASE (U8500_PER4_BASE + 0x2000) | ||
82 | #define U8500_RTT1_BASE (U8500_PER4_BASE + 0x3000) | ||
83 | #define U8500_RTC_BASE (U8500_PER4_BASE + 0x4000) | ||
84 | #define U8500_SCR_BASE (U8500_PER4_BASE + 0x5000) | ||
85 | #define U8500_DMC_BASE (U8500_PER4_BASE + 0x6000) | ||
86 | #define U8500_PRCMU_BASE (U8500_PER4_BASE + 0x7000) | ||
87 | |||
88 | /* per3 base addressess */ | ||
89 | #define U8500_FSMC_BASE (U8500_PER3_BASE + 0x0000) | ||
90 | #define U8500_SSP0_BASE (U8500_PER3_BASE + 0x2000) | ||
91 | #define U8500_SSP1_BASE (U8500_PER3_BASE + 0x3000) | ||
92 | #define U8500_I2C0_BASE (U8500_PER3_BASE + 0x4000) | ||
93 | #define U8500_SDI2_BASE (U8500_PER3_BASE + 0x5000) | ||
94 | #define U8500_SKE_BASE (U8500_PER3_BASE + 0x6000) | ||
95 | #define U8500_UART2_BASE (U8500_PER3_BASE + 0x7000) | ||
96 | #define U8500_SDI5_BASE (U8500_PER3_BASE + 0x8000) | ||
97 | #define U8500_GPIO3_BASE (U8500_PER3_BASE + 0xe000) | ||
98 | #define U8500_CLKRST3_BASE (U8500_PER7_BASE + 0xf000) | ||
99 | |||
100 | /* per2 base addressess */ | ||
101 | #define U8500_I2C3_BASE (U8500_PER2_BASE + 0x0000) | ||
102 | #define U8500_SPI2_BASE (U8500_PER2_BASE + 0x1000) | ||
103 | #define U8500_SPI1_BASE (U8500_PER2_BASE + 0x2000) | ||
104 | #define U8500_PWL_BASE (U8500_PER2_BASE + 0x3000) | ||
105 | #define U8500_SDI4_BASE (U8500_PER2_BASE + 0x4000) | ||
106 | #define U8500_MSP2_BASE (U8500_PER2_BASE + 0x7000) | ||
107 | #define U8500_SDI1_BASE (U8500_PER2_BASE + 0x8000) | ||
108 | #define U8500_SDI3_BASE (U8500_PER2_BASE + 0x9000) | ||
109 | #define U8500_SPI0_BASE (U8500_PER2_BASE + 0xa000) | ||
110 | #define U8500_HSIR_BASE (U8500_PER2_BASE + 0xb000) | ||
111 | #define U8500_HSIT_BASE (U8500_PER2_BASE + 0xc000) | ||
112 | #define U8500_GPIO2_BASE (U8500_PER2_BASE + 0xe000) | ||
113 | #define U8500_CLKRST2_BASE (U8500_PER2_BASE + 0xf000) | ||
114 | |||
115 | /* per1 base addresses */ | ||
116 | #define U8500_UART0_BASE (U8500_PER1_BASE + 0x0000) | ||
117 | #define U8500_UART1_BASE (U8500_PER1_BASE + 0x1000) | ||
118 | #define U8500_I2C1_BASE (U8500_PER1_BASE + 0x2000) | ||
119 | #define U8500_MSP0_BASE (U8500_PER1_BASE + 0x3000) | ||
120 | #define U8500_MSP1_BASE (U8500_PER1_BASE + 0x4000) | ||
121 | #define U8500_SDI0_BASE (U8500_PER1_BASE + 0x6000) | ||
122 | #define U8500_I2C2_BASE (U8500_PER1_BASE + 0x8000) | ||
123 | #define U8500_SPI3_BASE (U8500_PER1_BASE + 0x9000) | ||
124 | #define U8500_SLIM0_BASE (U8500_PER1_BASE + 0xa000) | ||
125 | #define U8500_GPIO1_BASE (U8500_PER1_BASE + 0xe000) | ||
126 | #define U8500_CLKRST1_BASE (U8500_PER2_BASE + 0xf000) | ||
127 | |||
128 | /* ST-Ericsson modified pl022 id */ | ||
129 | #define SSP_PER_ID 0x01080022 | ||
130 | |||
131 | #endif /* __MACH_HARDWARE_H */ | ||
diff --git a/arch/arm/mach-ux500/include/mach/io.h b/arch/arm/mach-ux500/include/mach/io.h new file mode 100644 index 000000000000..1cf3f44ce5b2 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/io.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * arch/arm/mach-u8500/include/mach/io.h | ||
3 | * | ||
4 | * Copyright (C) 1997-1999 Russell King | ||
5 | * | ||
6 | * Modifications: | ||
7 | * 06-12-1997 RMK Created. | ||
8 | * 07-04-1999 RMK Major cleanup | ||
9 | */ | ||
10 | #ifndef __ASM_ARM_ARCH_IO_H | ||
11 | #define __ASM_ARM_ARCH_IO_H | ||
12 | |||
13 | #define IO_SPACE_LIMIT 0xffffffff | ||
14 | |||
15 | /* | ||
16 | * We don't actually have real ISA nor PCI buses, but there is so many | ||
17 | * drivers out there that might just work if we fake them... | ||
18 | */ | ||
19 | #define __io(a) __typesafe_io(a) | ||
20 | #define __mem_pci(a) (a) | ||
21 | |||
22 | #endif | ||
diff --git a/arch/arm/mach-ux500/include/mach/irqs.h b/arch/arm/mach-ux500/include/mach/irqs.h new file mode 100644 index 000000000000..394b5dd2200f --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/irqs.h | |||
@@ -0,0 +1,71 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008 STMicroelectronics | ||
3 | * Copyright (C) 2009 ST-Ericsson. | ||
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 | #ifndef ASM_ARCH_IRQS_H | ||
11 | #define ASM_ARCH_IRQS_H | ||
12 | |||
13 | #include <mach/hardware.h> | ||
14 | |||
15 | #define IRQ_LOCALTIMER 29 | ||
16 | #define IRQ_LOCALWDOG 30 | ||
17 | |||
18 | /* Shared Peripheral Interrupt (SHPI) */ | ||
19 | #define IRQ_SHPI_START 32 | ||
20 | |||
21 | /* Interrupt numbers generic for shared peripheral */ | ||
22 | #define IRQ_MTU0 (IRQ_SHPI_START + 4) | ||
23 | #define IRQ_SPI2 (IRQ_SHPI_START + 6) | ||
24 | #define IRQ_SPI0 (IRQ_SHPI_START + 8) | ||
25 | #define IRQ_UART0 (IRQ_SHPI_START + 11) | ||
26 | #define IRQ_I2C3 (IRQ_SHPI_START + 12) | ||
27 | #define IRQ_SSP0 (IRQ_SHPI_START + 14) | ||
28 | #define IRQ_MTU1 (IRQ_SHPI_START + 17) | ||
29 | #define IRQ_RTC_RTT (IRQ_SHPI_START + 18) | ||
30 | #define IRQ_UART1 (IRQ_SHPI_START + 19) | ||
31 | #define IRQ_I2C0 (IRQ_SHPI_START + 21) | ||
32 | #define IRQ_I2C1 (IRQ_SHPI_START + 22) | ||
33 | #define IRQ_USBOTG (IRQ_SHPI_START + 23) | ||
34 | #define IRQ_DMA (IRQ_SHPI_START + 25) | ||
35 | #define IRQ_UART2 (IRQ_SHPI_START + 26) | ||
36 | #define IRQ_HSIR_EXCEP (IRQ_SHPI_START + 29) | ||
37 | #define IRQ_MSP0 (IRQ_SHPI_START + 31) | ||
38 | #define IRQ_HSIR_CH0_OVRRUN (IRQ_SHPI_START + 32) | ||
39 | #define IRQ_HSIR_CH1_OVRRUN (IRQ_SHPI_START + 33) | ||
40 | #define IRQ_HSIR_CH2_OVRRUN (IRQ_SHPI_START + 34) | ||
41 | #define IRQ_HSIR_CH3_OVRRUN (IRQ_SHPI_START + 35) | ||
42 | #define IRQ_AB4500 (IRQ_SHPI_START + 40) | ||
43 | #define IRQ_DISP (IRQ_SHPI_START + 48) | ||
44 | #define IRQ_SiPI3 (IRQ_SHPI_START + 49) | ||
45 | #define IRQ_SSP1 (IRQ_SHPI_START + 52) | ||
46 | #define IRQ_I2C2 (IRQ_SHPI_START + 55) | ||
47 | #define IRQ_SDMMC0 (IRQ_SHPI_START + 60) | ||
48 | #define IRQ_MSP1 (IRQ_SHPI_START + 62) | ||
49 | #define IRQ_SPI1 (IRQ_SHPI_START + 96) | ||
50 | #define IRQ_MSP2 (IRQ_SHPI_START + 98) | ||
51 | #define IRQ_SDMMC4 (IRQ_SHPI_START + 99) | ||
52 | #define IRQ_HSIRD0 (IRQ_SHPI_START + 104) | ||
53 | #define IRQ_HSIRD1 (IRQ_SHPI_START + 105) | ||
54 | #define IRQ_HSITD0 (IRQ_SHPI_START + 106) | ||
55 | #define IRQ_HSITD1 (IRQ_SHPI_START + 107) | ||
56 | #define IRQ_GPIO0 (IRQ_SHPI_START + 119) | ||
57 | #define IRQ_GPIO1 (IRQ_SHPI_START + 120) | ||
58 | #define IRQ_GPIO2 (IRQ_SHPI_START + 121) | ||
59 | #define IRQ_GPIO3 (IRQ_SHPI_START + 122) | ||
60 | #define IRQ_GPIO4 (IRQ_SHPI_START + 123) | ||
61 | #define IRQ_GPIO5 (IRQ_SHPI_START + 124) | ||
62 | #define IRQ_GPIO6 (IRQ_SHPI_START + 125) | ||
63 | #define IRQ_GPIO7 (IRQ_SHPI_START + 126) | ||
64 | #define IRQ_GPIO8 (IRQ_SHPI_START + 127) | ||
65 | |||
66 | /* There are 128 shared peripheral interrupts assigned to | ||
67 | * INTID[160:32]. The first 32 interrupts are reserved. | ||
68 | */ | ||
69 | #define NR_IRQS 161 | ||
70 | |||
71 | #endif /*ASM_ARCH_IRQS_H*/ | ||
diff --git a/arch/arm/mach-ux500/include/mach/memory.h b/arch/arm/mach-ux500/include/mach/memory.h new file mode 100644 index 000000000000..510571a59e25 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/memory.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 ST-Ericsson | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | */ | ||
9 | #ifndef __ASM_ARCH_MEMORY_H | ||
10 | #define __ASM_ARCH_MEMORY_H | ||
11 | |||
12 | /* | ||
13 | * Physical DRAM offset. | ||
14 | */ | ||
15 | #define PHYS_OFFSET UL(0x00000000) | ||
16 | #define BUS_OFFSET UL(0x00000000) | ||
17 | |||
18 | #endif | ||
diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h new file mode 100644 index 000000000000..cf0ce1687f24 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/setup.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 ST-Ericsson. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License version 2 as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * These symbols are needed for board-specific files to call their | ||
9 | * own cpu-specific files | ||
10 | */ | ||
11 | #ifndef __ASM_ARCH_SETUP_H | ||
12 | #define __ASM_ARCH_SETUP_H | ||
13 | |||
14 | #include <asm/mach/time.h> | ||
15 | #include <linux/init.h> | ||
16 | |||
17 | extern void u8500_map_io(void); | ||
18 | extern void u8500_init_devices(void); | ||
19 | extern void u8500_init_irq(void); | ||
20 | /* We re-use nomadik_timer for this platform */ | ||
21 | extern void nmdk_timer_init(void); | ||
22 | |||
23 | #endif /* __ASM_ARCH_SETUP_H */ | ||
diff --git a/arch/arm/mach-ux500/include/mach/smp.h b/arch/arm/mach-ux500/include/mach/smp.h new file mode 100644 index 000000000000..b59f7bc9725d --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/smp.h | |||
@@ -0,0 +1,32 @@ | |||
1 | /* | ||
2 | * This file is based ARM realview platform. | ||
3 | * Copyright (C) ARM Limited. | ||
4 | * | ||
5 | * This file is licensed under the terms of the GNU General Public | ||
6 | * License version 2. This program is licensed "as is" without any | ||
7 | * warranty of any kind, whether express or implied. | ||
8 | */ | ||
9 | #ifndef ASMARM_ARCH_SMP_H | ||
10 | #define ASMARM_ARCH_SMP_H | ||
11 | |||
12 | #include <asm/hardware/gic.h> | ||
13 | |||
14 | /* This is required to wakeup the secondary core */ | ||
15 | extern void u8500_secondary_startup(void); | ||
16 | |||
17 | #define hard_smp_processor_id() \ | ||
18 | ({ \ | ||
19 | unsigned int cpunum; \ | ||
20 | __asm__("mrc p15, 0, %0, c0, c0, 5" \ | ||
21 | : "=r" (cpunum)); \ | ||
22 | cpunum &= 0x0F; \ | ||
23 | }) | ||
24 | |||
25 | /* | ||
26 | * We use IRQ1 as the IPI | ||
27 | */ | ||
28 | static inline void smp_cross_call(const struct cpumask *mask) | ||
29 | { | ||
30 | gic_raise_softirq(mask, 1); | ||
31 | } | ||
32 | #endif | ||
diff --git a/arch/arm/mach-ux500/include/mach/system.h b/arch/arm/mach-ux500/include/mach/system.h new file mode 100644 index 000000000000..c0cd8006f1a2 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/system.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 ST-Ericsson. | ||
3 | * | ||
4 | * This file is licensed under the terms of the GNU General Public | ||
5 | * License version 2. This program is licensed "as is" without any | ||
6 | * warranty of any kind, whether express or implied. | ||
7 | */ | ||
8 | #ifndef __ASM_ARCH_SYSTEM_H | ||
9 | #define __ASM_ARCH_SYSTEM_H | ||
10 | |||
11 | static inline void arch_idle(void) | ||
12 | { | ||
13 | /* | ||
14 | * This should do all the clock switching | ||
15 | * and wait for interrupt tricks | ||
16 | */ | ||
17 | cpu_do_idle(); | ||
18 | } | ||
19 | |||
20 | static inline void arch_reset(char mode, const char *cmd) | ||
21 | { | ||
22 | /* yet to be implemented - TODO */ | ||
23 | } | ||
24 | |||
25 | #endif | ||
diff --git a/arch/arm/mach-ux500/include/mach/timex.h b/arch/arm/mach-ux500/include/mach/timex.h new file mode 100644 index 000000000000..d0942c174018 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/timex.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef __ASM_ARCH_TIMEX_H | ||
2 | #define __ASM_ARCH_TIMEX_H | ||
3 | |||
4 | #define CLOCK_TICK_RATE 110000000 | ||
5 | |||
6 | #endif | ||
diff --git a/arch/arm/mach-ux500/include/mach/uncompress.h b/arch/arm/mach-ux500/include/mach/uncompress.h new file mode 100644 index 000000000000..8552eb188b50 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/uncompress.h | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 ST-Ericsson | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | */ | ||
18 | #ifndef __ASM_ARCH_UNCOMPRESS_H | ||
19 | #define __ASM_ARCH_UNCOMPRESS_H | ||
20 | |||
21 | #include <asm/setup.h> | ||
22 | #include <linux/io.h> | ||
23 | #include <mach/hardware.h> | ||
24 | |||
25 | #define U8500_UART_DR 0x80007000 | ||
26 | #define U8500_UART_LCRH 0x8000702c | ||
27 | #define U8500_UART_CR 0x80007030 | ||
28 | #define U8500_UART_FR 0x80007018 | ||
29 | |||
30 | static void putc(const char c) | ||
31 | { | ||
32 | /* Do nothing if the UART is not enabled. */ | ||
33 | if (!(readb(U8500_UART_CR) & 0x1)) | ||
34 | return; | ||
35 | |||
36 | if (c == '\n') | ||
37 | putc('\r'); | ||
38 | |||
39 | while (readb(U8500_UART_FR) & (1 << 5)) | ||
40 | barrier(); | ||
41 | writeb(c, U8500_UART_DR); | ||
42 | } | ||
43 | |||
44 | static void flush(void) | ||
45 | { | ||
46 | if (!(readb(U8500_UART_CR) & 0x1)) | ||
47 | return; | ||
48 | while (readb(U8500_UART_FR) & (1 << 3)) | ||
49 | barrier(); | ||
50 | } | ||
51 | |||
52 | static inline void arch_decomp_setup(void) | ||
53 | { | ||
54 | } | ||
55 | |||
56 | #define arch_decomp_wdog() /* nothing to do here */ | ||
57 | |||
58 | #endif /* __ASM_ARCH_UNCOMPRESS_H */ | ||
diff --git a/arch/arm/mach-ux500/include/mach/vmalloc.h b/arch/arm/mach-ux500/include/mach/vmalloc.h new file mode 100644 index 000000000000..86cdbbce1842 --- /dev/null +++ b/arch/arm/mach-ux500/include/mach/vmalloc.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2009 ST-Ericsson | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
17 | */ | ||
18 | #define VMALLOC_END 0xf0000000 | ||
diff --git a/arch/arm/mach-ux500/localtimer.c b/arch/arm/mach-ux500/localtimer.c new file mode 100644 index 000000000000..2288f6a7c518 --- /dev/null +++ b/arch/arm/mach-ux500/localtimer.c | |||
@@ -0,0 +1,28 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2008-2009 ST-Ericsson | ||
3 | * Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> | ||
4 | * | ||
5 | * This file is heavily based on relaview platform, almost a copy. | ||
6 | * | ||
7 | * Copyright (C) 2002 ARM Ltd. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/smp.h> | ||
15 | #include <linux/clockchips.h> | ||
16 | |||
17 | #include <asm/irq.h> | ||
18 | #include <asm/smp_twd.h> | ||
19 | #include <asm/localtimer.h> | ||
20 | |||
21 | /* | ||
22 | * Setup the local clock events for a CPU. | ||
23 | */ | ||
24 | void __cpuinit local_timer_setup(struct clock_event_device *evt) | ||
25 | { | ||
26 | evt->irq = IRQ_LOCALTIMER; | ||
27 | twd_timer_setup(evt); | ||
28 | } | ||
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c new file mode 100644 index 000000000000..8dfe7ca245d8 --- /dev/null +++ b/arch/arm/mach-ux500/platsmp.c | |||
@@ -0,0 +1,177 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2002 ARM Ltd. | ||
3 | * Copyright (C) 2008 STMicroelctronics. | ||
4 | * Copyright (C) 2009 ST-Ericsson. | ||
5 | * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> | ||
6 | * | ||
7 | * This file is based on arm realview platform | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License version 2 as | ||
11 | * published by the Free Software Foundation. | ||
12 | */ | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/errno.h> | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/device.h> | ||
17 | #include <linux/smp.h> | ||
18 | #include <linux/io.h> | ||
19 | |||
20 | #include <asm/cacheflush.h> | ||
21 | #include <asm/localtimer.h> | ||
22 | #include <asm/smp_scu.h> | ||
23 | #include <mach/hardware.h> | ||
24 | |||
25 | /* | ||
26 | * control for which core is the next to come out of the secondary | ||
27 | * boot "holding pen" | ||
28 | */ | ||
29 | volatile int __cpuinitdata pen_release = -1; | ||
30 | |||
31 | static unsigned int __init get_core_count(void) | ||
32 | { | ||
33 | return scu_get_core_count(__io_address(U8500_SCU_BASE)); | ||
34 | } | ||
35 | |||
36 | static DEFINE_SPINLOCK(boot_lock); | ||
37 | |||
38 | void __cpuinit platform_secondary_init(unsigned int cpu) | ||
39 | { | ||
40 | trace_hardirqs_off(); | ||
41 | |||
42 | /* | ||
43 | * if any interrupts are already enabled for the primary | ||
44 | * core (e.g. timer irq), then they will not have been enabled | ||
45 | * for us: do so | ||
46 | */ | ||
47 | gic_cpu_init(0, __io_address(U8500_GIC_CPU_BASE)); | ||
48 | |||
49 | /* | ||
50 | * let the primary processor know we're out of the | ||
51 | * pen, then head off into the C entry point | ||
52 | */ | ||
53 | pen_release = -1; | ||
54 | |||
55 | /* | ||
56 | * Synchronise with the boot thread. | ||
57 | */ | ||
58 | spin_lock(&boot_lock); | ||
59 | spin_unlock(&boot_lock); | ||
60 | } | ||
61 | |||
62 | int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle) | ||
63 | { | ||
64 | unsigned long timeout; | ||
65 | |||
66 | /* | ||
67 | * set synchronisation state between this boot processor | ||
68 | * and the secondary one | ||
69 | */ | ||
70 | spin_lock(&boot_lock); | ||
71 | |||
72 | /* | ||
73 | * The secondary processor is waiting to be released from | ||
74 | * the holding pen - release it, then wait for it to flag | ||
75 | * that it has been released by resetting pen_release. | ||
76 | */ | ||
77 | pen_release = cpu; | ||
78 | flush_cache_all(); | ||
79 | |||
80 | timeout = jiffies + (1 * HZ); | ||
81 | while (time_before(jiffies, timeout)) { | ||
82 | if (pen_release == -1) | ||
83 | break; | ||
84 | } | ||
85 | |||
86 | /* | ||
87 | * now the secondary core is starting up let it run its | ||
88 | * calibrations, then wait for it to finish | ||
89 | */ | ||
90 | spin_unlock(&boot_lock); | ||
91 | |||
92 | return pen_release != -1 ? -ENOSYS : 0; | ||
93 | } | ||
94 | |||
95 | static void __init wakeup_secondary(void) | ||
96 | { | ||
97 | /* nobody is to be released from the pen yet */ | ||
98 | pen_release = -1; | ||
99 | |||
100 | /* | ||
101 | * write the address of secondary startup into the backup ram register | ||
102 | * at offset 0x1FF4, then write the magic number 0xA1FEED01 to the | ||
103 | * backup ram register at offset 0x1FF0, which is what boot rom code | ||
104 | * is waiting for. This would wake up the secondary core from WFE | ||
105 | */ | ||
106 | #define U8500_CPU1_JUMPADDR_OFFSET 0x1FF4 | ||
107 | __raw_writel(virt_to_phys(u8500_secondary_startup), | ||
108 | (void __iomem *)IO_ADDRESS(U8500_BACKUPRAM0_BASE) + | ||
109 | U8500_CPU1_JUMPADDR_OFFSET); | ||
110 | |||
111 | #define U8500_CPU1_WAKEMAGIC_OFFSET 0x1FF0 | ||
112 | __raw_writel(0xA1FEED01, | ||
113 | (void __iomem *)IO_ADDRESS(U8500_BACKUPRAM0_BASE) + | ||
114 | U8500_CPU1_WAKEMAGIC_OFFSET); | ||
115 | |||
116 | /* make sure write buffer is drained */ | ||
117 | mb(); | ||
118 | } | ||
119 | |||
120 | /* | ||
121 | * Initialise the CPU possible map early - this describes the CPUs | ||
122 | * which may be present or become present in the system. | ||
123 | */ | ||
124 | void __init smp_init_cpus(void) | ||
125 | { | ||
126 | unsigned int i, ncores = get_core_count(); | ||
127 | |||
128 | for (i = 0; i < ncores; i++) | ||
129 | set_cpu_possible(i, true); | ||
130 | } | ||
131 | |||
132 | void __init smp_prepare_cpus(unsigned int max_cpus) | ||
133 | { | ||
134 | unsigned int ncores = get_core_count(); | ||
135 | unsigned int cpu = smp_processor_id(); | ||
136 | int i; | ||
137 | |||
138 | /* sanity check */ | ||
139 | if (ncores == 0) { | ||
140 | printk(KERN_ERR | ||
141 | "U8500: strange CM count of 0? Default to 1\n"); | ||
142 | ncores = 1; | ||
143 | } | ||
144 | |||
145 | if (ncores > num_possible_cpus()) { | ||
146 | printk(KERN_WARNING | ||
147 | "U8500: no. of cores (%d) greater than configured " | ||
148 | "maximum of %d - clipping\n", | ||
149 | ncores, num_possible_cpus()); | ||
150 | ncores = num_possible_cpus(); | ||
151 | } | ||
152 | |||
153 | smp_store_cpu_info(cpu); | ||
154 | |||
155 | /* | ||
156 | * are we trying to boot more cores than exist? | ||
157 | */ | ||
158 | if (max_cpus > ncores) | ||
159 | max_cpus = ncores; | ||
160 | |||
161 | /* | ||
162 | * Initialise the present map, which describes the set of CPUs | ||
163 | * actually populated at the present time. | ||
164 | */ | ||
165 | for (i = 0; i < max_cpus; i++) | ||
166 | set_cpu_present(i, true); | ||
167 | |||
168 | if (max_cpus > 1) { | ||
169 | /* | ||
170 | * Enable the local timer or broadcast device for the | ||
171 | * boot CPU, but only if we have more than one CPU. | ||
172 | */ | ||
173 | percpu_timer_setup(); | ||
174 | scu_enable(__io_address(U8500_SCU_BASE)); | ||
175 | wakeup_secondary(); | ||
176 | } | ||
177 | } | ||
diff --git a/arch/arm/mach-w90x900/dev.c b/arch/arm/mach-w90x900/dev.c index 2a6f98de48d2..51f17b753348 100644 --- a/arch/arm/mach-w90x900/dev.c +++ b/arch/arm/mach-w90x900/dev.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <asm/mach-types.h> | 32 | #include <asm/mach-types.h> |
33 | 33 | ||
34 | #include <mach/regs-serial.h> | 34 | #include <mach/regs-serial.h> |
35 | #include <mach/nuc900_spi.h> | ||
35 | #include <mach/map.h> | 36 | #include <mach/map.h> |
36 | 37 | ||
37 | #include "cpu.h" | 38 | #include "cpu.h" |
@@ -196,6 +197,18 @@ static struct platform_device nuc900_device_emc = { | |||
196 | 197 | ||
197 | /* SPI device */ | 198 | /* SPI device */ |
198 | 199 | ||
200 | static struct w90p910_spi_info nuc900_spiflash_data = { | ||
201 | .num_cs = 1, | ||
202 | .lsb = 0, | ||
203 | .txneg = 1, | ||
204 | .rxneg = 0, | ||
205 | .divider = 24, | ||
206 | .sleep = 0, | ||
207 | .txnum = 0, | ||
208 | .txbitlen = 1, | ||
209 | .bus_num = 0, | ||
210 | }; | ||
211 | |||
199 | static struct resource nuc900_spi_resource[] = { | 212 | static struct resource nuc900_spi_resource[] = { |
200 | [0] = { | 213 | [0] = { |
201 | .start = W90X900_PA_I2C + SPIOFFSET, | 214 | .start = W90X900_PA_I2C + SPIOFFSET, |
@@ -214,6 +227,9 @@ static struct platform_device nuc900_device_spi = { | |||
214 | .id = -1, | 227 | .id = -1, |
215 | .num_resources = ARRAY_SIZE(nuc900_spi_resource), | 228 | .num_resources = ARRAY_SIZE(nuc900_spi_resource), |
216 | .resource = nuc900_spi_resource, | 229 | .resource = nuc900_spi_resource, |
230 | .dev = { | ||
231 | .platform_data = &nuc900_spiflash_data, | ||
232 | } | ||
217 | }; | 233 | }; |
218 | 234 | ||
219 | /* spi device, spi flash info */ | 235 | /* spi device, spi flash info */ |
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 4958ef2c6254..dd4698c67cc3 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
@@ -783,5 +783,5 @@ config CACHE_XSC3L2 | |||
783 | 783 | ||
784 | config ARM_L1_CACHE_SHIFT | 784 | config ARM_L1_CACHE_SHIFT |
785 | int | 785 | int |
786 | default 6 if ARCH_OMAP3 | 786 | default 6 if ARCH_OMAP3 || ARCH_S5PC1XX |
787 | default 5 | 787 | default 5 |
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 06bcf2e73858..827e238e5d4a 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile | |||
@@ -6,7 +6,7 @@ obj-y := dma-mapping.o extable.o fault.o init.o \ | |||
6 | iomap.o | 6 | iomap.o |
7 | 7 | ||
8 | obj-$(CONFIG_MMU) += fault-armv.o flush.o ioremap.o mmap.o \ | 8 | obj-$(CONFIG_MMU) += fault-armv.o flush.o ioremap.o mmap.o \ |
9 | pgd.o mmu.o | 9 | pgd.o mmu.o vmregion.o |
10 | 10 | ||
11 | ifneq ($(CONFIG_MMU),y) | 11 | ifneq ($(CONFIG_MMU),y) |
12 | obj-y += nommu.o | 12 | obj-y += nommu.o |
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index b480f1d3591f..747f9a9021bb 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c | |||
@@ -99,18 +99,25 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask) | |||
99 | 99 | ||
100 | l2x0_base = base; | 100 | l2x0_base = base; |
101 | 101 | ||
102 | /* disable L2X0 */ | 102 | /* |
103 | writel(0, l2x0_base + L2X0_CTRL); | 103 | * Check if l2x0 controller is already enabled. |
104 | * If you are booting from non-secure mode | ||
105 | * accessing the below registers will fault. | ||
106 | */ | ||
107 | if (!(readl(l2x0_base + L2X0_CTRL) & 1)) { | ||
104 | 108 | ||
105 | aux = readl(l2x0_base + L2X0_AUX_CTRL); | 109 | /* l2x0 controller is disabled */ |
106 | aux &= aux_mask; | ||
107 | aux |= aux_val; | ||
108 | writel(aux, l2x0_base + L2X0_AUX_CTRL); | ||
109 | 110 | ||
110 | l2x0_inv_all(); | 111 | aux = readl(l2x0_base + L2X0_AUX_CTRL); |
112 | aux &= aux_mask; | ||
113 | aux |= aux_val; | ||
114 | writel(aux, l2x0_base + L2X0_AUX_CTRL); | ||
111 | 115 | ||
112 | /* enable L2X0 */ | 116 | l2x0_inv_all(); |
113 | writel(1, l2x0_base + L2X0_CTRL); | 117 | |
118 | /* enable L2X0 */ | ||
119 | writel(1, l2x0_base + L2X0_CTRL); | ||
120 | } | ||
114 | 121 | ||
115 | outer_cache.inv_range = l2x0_inv_range; | 122 | outer_cache.inv_range = l2x0_inv_range; |
116 | outer_cache.clean_range = l2x0_clean_range; | 123 | outer_cache.clean_range = l2x0_clean_range; |
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c index 4127a7bddfe5..841f355319bf 100644 --- a/arch/arm/mm/copypage-v6.c +++ b/arch/arm/mm/copypage-v6.c | |||
@@ -41,6 +41,14 @@ static void v6_copy_user_highpage_nonaliasing(struct page *to, | |||
41 | kfrom = kmap_atomic(from, KM_USER0); | 41 | kfrom = kmap_atomic(from, KM_USER0); |
42 | kto = kmap_atomic(to, KM_USER1); | 42 | kto = kmap_atomic(to, KM_USER1); |
43 | copy_page(kto, kfrom); | 43 | copy_page(kto, kfrom); |
44 | #ifdef CONFIG_HIGHMEM | ||
45 | /* | ||
46 | * kmap_atomic() doesn't set the page virtual address, and | ||
47 | * kunmap_atomic() takes care of cache flushing already. | ||
48 | */ | ||
49 | if (page_address(to) != NULL) | ||
50 | #endif | ||
51 | __cpuc_flush_dcache_page(kto); | ||
44 | kunmap_atomic(kto, KM_USER1); | 52 | kunmap_atomic(kto, KM_USER1); |
45 | kunmap_atomic(kfrom, KM_USER0); | 53 | kunmap_atomic(kfrom, KM_USER0); |
46 | } | 54 | } |
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index b9590a7085ca..26325cb5d368 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
@@ -63,194 +63,152 @@ static u64 get_coherent_dma_mask(struct device *dev) | |||
63 | return mask; | 63 | return mask; |
64 | } | 64 | } |
65 | 65 | ||
66 | #ifdef CONFIG_MMU | ||
67 | /* | 66 | /* |
68 | * These are the page tables (2MB each) covering uncached, DMA consistent allocations | 67 | * Allocate a DMA buffer for 'dev' of size 'size' using the |
68 | * specified gfp mask. Note that 'size' must be page aligned. | ||
69 | */ | 69 | */ |
70 | static pte_t *consistent_pte[NUM_CONSISTENT_PTES]; | 70 | static struct page *__dma_alloc_buffer(struct device *dev, size_t size, gfp_t gfp) |
71 | static DEFINE_SPINLOCK(consistent_lock); | 71 | { |
72 | unsigned long order = get_order(size); | ||
73 | struct page *page, *p, *e; | ||
74 | void *ptr; | ||
75 | u64 mask = get_coherent_dma_mask(dev); | ||
72 | 76 | ||
73 | /* | 77 | #ifdef CONFIG_DMA_API_DEBUG |
74 | * VM region handling support. | 78 | u64 limit = (mask + 1) & ~mask; |
75 | * | 79 | if (limit && size >= limit) { |
76 | * This should become something generic, handling VM region allocations for | 80 | dev_warn(dev, "coherent allocation too big (requested %#x mask %#llx)\n", |
77 | * vmalloc and similar (ioremap, module space, etc). | 81 | size, mask); |
78 | * | 82 | return NULL; |
79 | * I envisage vmalloc()'s supporting vm_struct becoming: | 83 | } |
80 | * | 84 | #endif |
81 | * struct vm_struct { | ||
82 | * struct vm_region region; | ||
83 | * unsigned long flags; | ||
84 | * struct page **pages; | ||
85 | * unsigned int nr_pages; | ||
86 | * unsigned long phys_addr; | ||
87 | * }; | ||
88 | * | ||
89 | * get_vm_area() would then call vm_region_alloc with an appropriate | ||
90 | * struct vm_region head (eg): | ||
91 | * | ||
92 | * struct vm_region vmalloc_head = { | ||
93 | * .vm_list = LIST_HEAD_INIT(vmalloc_head.vm_list), | ||
94 | * .vm_start = VMALLOC_START, | ||
95 | * .vm_end = VMALLOC_END, | ||
96 | * }; | ||
97 | * | ||
98 | * However, vmalloc_head.vm_start is variable (typically, it is dependent on | ||
99 | * the amount of RAM found at boot time.) I would imagine that get_vm_area() | ||
100 | * would have to initialise this each time prior to calling vm_region_alloc(). | ||
101 | */ | ||
102 | struct arm_vm_region { | ||
103 | struct list_head vm_list; | ||
104 | unsigned long vm_start; | ||
105 | unsigned long vm_end; | ||
106 | struct page *vm_pages; | ||
107 | int vm_active; | ||
108 | }; | ||
109 | 85 | ||
110 | static struct arm_vm_region consistent_head = { | 86 | if (!mask) |
111 | .vm_list = LIST_HEAD_INIT(consistent_head.vm_list), | 87 | return NULL; |
112 | .vm_start = CONSISTENT_BASE, | ||
113 | .vm_end = CONSISTENT_END, | ||
114 | }; | ||
115 | 88 | ||
116 | static struct arm_vm_region * | 89 | if (mask < 0xffffffffULL) |
117 | arm_vm_region_alloc(struct arm_vm_region *head, size_t size, gfp_t gfp) | 90 | gfp |= GFP_DMA; |
118 | { | 91 | |
119 | unsigned long addr = head->vm_start, end = head->vm_end - size; | 92 | page = alloc_pages(gfp, order); |
120 | unsigned long flags; | 93 | if (!page) |
121 | struct arm_vm_region *c, *new; | 94 | return NULL; |
122 | |||
123 | new = kmalloc(sizeof(struct arm_vm_region), gfp); | ||
124 | if (!new) | ||
125 | goto out; | ||
126 | |||
127 | spin_lock_irqsave(&consistent_lock, flags); | ||
128 | |||
129 | list_for_each_entry(c, &head->vm_list, vm_list) { | ||
130 | if ((addr + size) < addr) | ||
131 | goto nospc; | ||
132 | if ((addr + size) <= c->vm_start) | ||
133 | goto found; | ||
134 | addr = c->vm_end; | ||
135 | if (addr > end) | ||
136 | goto nospc; | ||
137 | } | ||
138 | 95 | ||
139 | found: | ||
140 | /* | 96 | /* |
141 | * Insert this entry _before_ the one we found. | 97 | * Now split the huge page and free the excess pages |
142 | */ | 98 | */ |
143 | list_add_tail(&new->vm_list, &c->vm_list); | 99 | split_page(page, order); |
144 | new->vm_start = addr; | 100 | for (p = page + (size >> PAGE_SHIFT), e = page + (1 << order); p < e; p++) |
145 | new->vm_end = addr + size; | 101 | __free_page(p); |
146 | new->vm_active = 1; | 102 | |
147 | 103 | /* | |
148 | spin_unlock_irqrestore(&consistent_lock, flags); | 104 | * Ensure that the allocated pages are zeroed, and that any data |
149 | return new; | 105 | * lurking in the kernel direct-mapped region is invalidated. |
150 | 106 | */ | |
151 | nospc: | 107 | ptr = page_address(page); |
152 | spin_unlock_irqrestore(&consistent_lock, flags); | 108 | memset(ptr, 0, size); |
153 | kfree(new); | 109 | dmac_flush_range(ptr, ptr + size); |
154 | out: | 110 | outer_flush_range(__pa(ptr), __pa(ptr) + size); |
155 | return NULL; | 111 | |
112 | return page; | ||
156 | } | 113 | } |
157 | 114 | ||
158 | static struct arm_vm_region *arm_vm_region_find(struct arm_vm_region *head, unsigned long addr) | 115 | /* |
116 | * Free a DMA buffer. 'size' must be page aligned. | ||
117 | */ | ||
118 | static void __dma_free_buffer(struct page *page, size_t size) | ||
159 | { | 119 | { |
160 | struct arm_vm_region *c; | 120 | struct page *e = page + (size >> PAGE_SHIFT); |
161 | 121 | ||
162 | list_for_each_entry(c, &head->vm_list, vm_list) { | 122 | while (page < e) { |
163 | if (c->vm_active && c->vm_start == addr) | 123 | __free_page(page); |
164 | goto out; | 124 | page++; |
165 | } | 125 | } |
166 | c = NULL; | ||
167 | out: | ||
168 | return c; | ||
169 | } | 126 | } |
170 | 127 | ||
128 | #ifdef CONFIG_MMU | ||
129 | /* | ||
130 | * These are the page tables (2MB each) covering uncached, DMA consistent allocations | ||
131 | */ | ||
132 | static pte_t *consistent_pte[NUM_CONSISTENT_PTES]; | ||
133 | |||
134 | #include "vmregion.h" | ||
135 | |||
136 | static struct arm_vmregion_head consistent_head = { | ||
137 | .vm_lock = __SPIN_LOCK_UNLOCKED(&consistent_head.vm_lock), | ||
138 | .vm_list = LIST_HEAD_INIT(consistent_head.vm_list), | ||
139 | .vm_start = CONSISTENT_BASE, | ||
140 | .vm_end = CONSISTENT_END, | ||
141 | }; | ||
142 | |||
171 | #ifdef CONFIG_HUGETLB_PAGE | 143 | #ifdef CONFIG_HUGETLB_PAGE |
172 | #error ARM Coherent DMA allocator does not (yet) support huge TLB | 144 | #error ARM Coherent DMA allocator does not (yet) support huge TLB |
173 | #endif | 145 | #endif |
174 | 146 | ||
175 | static void * | 147 | /* |
176 | __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, | 148 | * Initialise the consistent memory allocation. |
177 | pgprot_t prot) | 149 | */ |
150 | static int __init consistent_init(void) | ||
178 | { | 151 | { |
179 | struct page *page; | 152 | int ret = 0; |
180 | struct arm_vm_region *c; | 153 | pgd_t *pgd; |
181 | unsigned long order; | 154 | pmd_t *pmd; |
182 | u64 mask = get_coherent_dma_mask(dev); | 155 | pte_t *pte; |
183 | u64 limit; | 156 | int i = 0; |
157 | u32 base = CONSISTENT_BASE; | ||
184 | 158 | ||
185 | if (!consistent_pte[0]) { | 159 | do { |
186 | printk(KERN_ERR "%s: not initialised\n", __func__); | 160 | pgd = pgd_offset(&init_mm, base); |
187 | dump_stack(); | 161 | pmd = pmd_alloc(&init_mm, pgd, base); |
188 | return NULL; | 162 | if (!pmd) { |
189 | } | 163 | printk(KERN_ERR "%s: no pmd tables\n", __func__); |
164 | ret = -ENOMEM; | ||
165 | break; | ||
166 | } | ||
167 | WARN_ON(!pmd_none(*pmd)); | ||
190 | 168 | ||
191 | if (!mask) | 169 | pte = pte_alloc_kernel(pmd, base); |
192 | goto no_page; | 170 | if (!pte) { |
171 | printk(KERN_ERR "%s: no pte tables\n", __func__); | ||
172 | ret = -ENOMEM; | ||
173 | break; | ||
174 | } | ||
193 | 175 | ||
194 | /* | 176 | consistent_pte[i++] = pte; |
195 | * Sanity check the allocation size. | 177 | base += (1 << PGDIR_SHIFT); |
196 | */ | 178 | } while (base < CONSISTENT_END); |
197 | size = PAGE_ALIGN(size); | ||
198 | limit = (mask + 1) & ~mask; | ||
199 | if ((limit && size >= limit) || | ||
200 | size >= (CONSISTENT_END - CONSISTENT_BASE)) { | ||
201 | printk(KERN_WARNING "coherent allocation too big " | ||
202 | "(requested %#x mask %#llx)\n", size, mask); | ||
203 | goto no_page; | ||
204 | } | ||
205 | 179 | ||
206 | order = get_order(size); | 180 | return ret; |
181 | } | ||
207 | 182 | ||
208 | if (mask < 0xffffffffULL) | 183 | core_initcall(consistent_init); |
209 | gfp |= GFP_DMA; | ||
210 | 184 | ||
211 | page = alloc_pages(gfp, order); | 185 | static void * |
212 | if (!page) | 186 | __dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot) |
213 | goto no_page; | 187 | { |
188 | struct arm_vmregion *c; | ||
214 | 189 | ||
215 | /* | 190 | if (!consistent_pte[0]) { |
216 | * Invalidate any data that might be lurking in the | 191 | printk(KERN_ERR "%s: not initialised\n", __func__); |
217 | * kernel direct-mapped region for device DMA. | 192 | dump_stack(); |
218 | */ | 193 | return NULL; |
219 | { | ||
220 | void *ptr = page_address(page); | ||
221 | memset(ptr, 0, size); | ||
222 | dmac_flush_range(ptr, ptr + size); | ||
223 | outer_flush_range(__pa(ptr), __pa(ptr) + size); | ||
224 | } | 194 | } |
225 | 195 | ||
226 | /* | 196 | /* |
227 | * Allocate a virtual address in the consistent mapping region. | 197 | * Allocate a virtual address in the consistent mapping region. |
228 | */ | 198 | */ |
229 | c = arm_vm_region_alloc(&consistent_head, size, | 199 | c = arm_vmregion_alloc(&consistent_head, size, |
230 | gfp & ~(__GFP_DMA | __GFP_HIGHMEM)); | 200 | gfp & ~(__GFP_DMA | __GFP_HIGHMEM)); |
231 | if (c) { | 201 | if (c) { |
232 | pte_t *pte; | 202 | pte_t *pte; |
233 | struct page *end = page + (1 << order); | ||
234 | int idx = CONSISTENT_PTE_INDEX(c->vm_start); | 203 | int idx = CONSISTENT_PTE_INDEX(c->vm_start); |
235 | u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1); | 204 | u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1); |
236 | 205 | ||
237 | pte = consistent_pte[idx] + off; | 206 | pte = consistent_pte[idx] + off; |
238 | c->vm_pages = page; | 207 | c->vm_pages = page; |
239 | 208 | ||
240 | split_page(page, order); | ||
241 | |||
242 | /* | ||
243 | * Set the "dma handle" | ||
244 | */ | ||
245 | *handle = page_to_dma(dev, page); | ||
246 | |||
247 | do { | 209 | do { |
248 | BUG_ON(!pte_none(*pte)); | 210 | BUG_ON(!pte_none(*pte)); |
249 | 211 | ||
250 | /* | ||
251 | * x86 does not mark the pages reserved... | ||
252 | */ | ||
253 | SetPageReserved(page); | ||
254 | set_pte_ext(pte, mk_pte(page, prot), 0); | 212 | set_pte_ext(pte, mk_pte(page, prot), 0); |
255 | page++; | 213 | page++; |
256 | pte++; | 214 | pte++; |
@@ -261,48 +219,90 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, | |||
261 | } | 219 | } |
262 | } while (size -= PAGE_SIZE); | 220 | } while (size -= PAGE_SIZE); |
263 | 221 | ||
264 | /* | ||
265 | * Free the otherwise unused pages. | ||
266 | */ | ||
267 | while (page < end) { | ||
268 | __free_page(page); | ||
269 | page++; | ||
270 | } | ||
271 | |||
272 | return (void *)c->vm_start; | 222 | return (void *)c->vm_start; |
273 | } | 223 | } |
274 | |||
275 | if (page) | ||
276 | __free_pages(page, order); | ||
277 | no_page: | ||
278 | *handle = ~0; | ||
279 | return NULL; | 224 | return NULL; |
280 | } | 225 | } |
226 | |||
227 | static void __dma_free_remap(void *cpu_addr, size_t size) | ||
228 | { | ||
229 | struct arm_vmregion *c; | ||
230 | unsigned long addr; | ||
231 | pte_t *ptep; | ||
232 | int idx; | ||
233 | u32 off; | ||
234 | |||
235 | c = arm_vmregion_find_remove(&consistent_head, (unsigned long)cpu_addr); | ||
236 | if (!c) { | ||
237 | printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n", | ||
238 | __func__, cpu_addr); | ||
239 | dump_stack(); | ||
240 | return; | ||
241 | } | ||
242 | |||
243 | if ((c->vm_end - c->vm_start) != size) { | ||
244 | printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n", | ||
245 | __func__, c->vm_end - c->vm_start, size); | ||
246 | dump_stack(); | ||
247 | size = c->vm_end - c->vm_start; | ||
248 | } | ||
249 | |||
250 | idx = CONSISTENT_PTE_INDEX(c->vm_start); | ||
251 | off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1); | ||
252 | ptep = consistent_pte[idx] + off; | ||
253 | addr = c->vm_start; | ||
254 | do { | ||
255 | pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep); | ||
256 | |||
257 | ptep++; | ||
258 | addr += PAGE_SIZE; | ||
259 | off++; | ||
260 | if (off >= PTRS_PER_PTE) { | ||
261 | off = 0; | ||
262 | ptep = consistent_pte[++idx]; | ||
263 | } | ||
264 | |||
265 | if (pte_none(pte) || !pte_present(pte)) | ||
266 | printk(KERN_CRIT "%s: bad page in kernel page table\n", | ||
267 | __func__); | ||
268 | } while (size -= PAGE_SIZE); | ||
269 | |||
270 | flush_tlb_kernel_range(c->vm_start, c->vm_end); | ||
271 | |||
272 | arm_vmregion_free(&consistent_head, c); | ||
273 | } | ||
274 | |||
281 | #else /* !CONFIG_MMU */ | 275 | #else /* !CONFIG_MMU */ |
276 | |||
277 | #define __dma_alloc_remap(page, size, gfp, prot) page_address(page) | ||
278 | #define __dma_free_remap(addr, size) do { } while (0) | ||
279 | |||
280 | #endif /* CONFIG_MMU */ | ||
281 | |||
282 | static void * | 282 | static void * |
283 | __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, | 283 | __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp, |
284 | pgprot_t prot) | 284 | pgprot_t prot) |
285 | { | 285 | { |
286 | void *virt; | 286 | struct page *page; |
287 | u64 mask = get_coherent_dma_mask(dev); | 287 | void *addr; |
288 | 288 | ||
289 | if (!mask) | 289 | *handle = ~0; |
290 | goto error; | 290 | size = PAGE_ALIGN(size); |
291 | 291 | ||
292 | if (mask < 0xffffffffULL) | 292 | page = __dma_alloc_buffer(dev, size, gfp); |
293 | gfp |= GFP_DMA; | 293 | if (!page) |
294 | virt = kmalloc(size, gfp); | 294 | return NULL; |
295 | if (!virt) | ||
296 | goto error; | ||
297 | 295 | ||
298 | *handle = virt_to_dma(dev, virt); | 296 | if (!arch_is_coherent()) |
299 | return virt; | 297 | addr = __dma_alloc_remap(page, size, gfp, prot); |
298 | else | ||
299 | addr = page_address(page); | ||
300 | 300 | ||
301 | error: | 301 | if (addr) |
302 | *handle = ~0; | 302 | *handle = page_to_dma(dev, page); |
303 | return NULL; | 303 | |
304 | return addr; | ||
304 | } | 305 | } |
305 | #endif /* CONFIG_MMU */ | ||
306 | 306 | ||
307 | /* | 307 | /* |
308 | * Allocate DMA-coherent memory space and return both the kernel remapped | 308 | * Allocate DMA-coherent memory space and return both the kernel remapped |
@@ -316,19 +316,8 @@ dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gf | |||
316 | if (dma_alloc_from_coherent(dev, size, handle, &memory)) | 316 | if (dma_alloc_from_coherent(dev, size, handle, &memory)) |
317 | return memory; | 317 | return memory; |
318 | 318 | ||
319 | if (arch_is_coherent()) { | ||
320 | void *virt; | ||
321 | |||
322 | virt = kmalloc(size, gfp); | ||
323 | if (!virt) | ||
324 | return NULL; | ||
325 | *handle = virt_to_dma(dev, virt); | ||
326 | |||
327 | return virt; | ||
328 | } | ||
329 | |||
330 | return __dma_alloc(dev, size, handle, gfp, | 319 | return __dma_alloc(dev, size, handle, gfp, |
331 | pgprot_noncached(pgprot_kernel)); | 320 | pgprot_dmacoherent(pgprot_kernel)); |
332 | } | 321 | } |
333 | EXPORT_SYMBOL(dma_alloc_coherent); | 322 | EXPORT_SYMBOL(dma_alloc_coherent); |
334 | 323 | ||
@@ -349,15 +338,12 @@ static int dma_mmap(struct device *dev, struct vm_area_struct *vma, | |||
349 | { | 338 | { |
350 | int ret = -ENXIO; | 339 | int ret = -ENXIO; |
351 | #ifdef CONFIG_MMU | 340 | #ifdef CONFIG_MMU |
352 | unsigned long flags, user_size, kern_size; | 341 | unsigned long user_size, kern_size; |
353 | struct arm_vm_region *c; | 342 | struct arm_vmregion *c; |
354 | 343 | ||
355 | user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; | 344 | user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; |
356 | 345 | ||
357 | spin_lock_irqsave(&consistent_lock, flags); | 346 | c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr); |
358 | c = arm_vm_region_find(&consistent_head, (unsigned long)cpu_addr); | ||
359 | spin_unlock_irqrestore(&consistent_lock, flags); | ||
360 | |||
361 | if (c) { | 347 | if (c) { |
362 | unsigned long off = vma->vm_pgoff; | 348 | unsigned long off = vma->vm_pgoff; |
363 | 349 | ||
@@ -379,7 +365,7 @@ static int dma_mmap(struct device *dev, struct vm_area_struct *vma, | |||
379 | int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma, | 365 | int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma, |
380 | void *cpu_addr, dma_addr_t dma_addr, size_t size) | 366 | void *cpu_addr, dma_addr_t dma_addr, size_t size) |
381 | { | 367 | { |
382 | vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); | 368 | vma->vm_page_prot = pgprot_dmacoherent(vma->vm_page_prot); |
383 | return dma_mmap(dev, vma, cpu_addr, dma_addr, size); | 369 | return dma_mmap(dev, vma, cpu_addr, dma_addr, size); |
384 | } | 370 | } |
385 | EXPORT_SYMBOL(dma_mmap_coherent); | 371 | EXPORT_SYMBOL(dma_mmap_coherent); |
@@ -396,144 +382,23 @@ EXPORT_SYMBOL(dma_mmap_writecombine); | |||
396 | * free a page as defined by the above mapping. | 382 | * free a page as defined by the above mapping. |
397 | * Must not be called with IRQs disabled. | 383 | * Must not be called with IRQs disabled. |
398 | */ | 384 | */ |
399 | #ifdef CONFIG_MMU | ||
400 | void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle) | 385 | void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle) |
401 | { | 386 | { |
402 | struct arm_vm_region *c; | ||
403 | unsigned long flags, addr; | ||
404 | pte_t *ptep; | ||
405 | int idx; | ||
406 | u32 off; | ||
407 | |||
408 | WARN_ON(irqs_disabled()); | 387 | WARN_ON(irqs_disabled()); |
409 | 388 | ||
410 | if (dma_release_from_coherent(dev, get_order(size), cpu_addr)) | 389 | if (dma_release_from_coherent(dev, get_order(size), cpu_addr)) |
411 | return; | 390 | return; |
412 | 391 | ||
413 | if (arch_is_coherent()) { | ||
414 | kfree(cpu_addr); | ||
415 | return; | ||
416 | } | ||
417 | |||
418 | size = PAGE_ALIGN(size); | 392 | size = PAGE_ALIGN(size); |
419 | 393 | ||
420 | spin_lock_irqsave(&consistent_lock, flags); | 394 | if (!arch_is_coherent()) |
421 | c = arm_vm_region_find(&consistent_head, (unsigned long)cpu_addr); | 395 | __dma_free_remap(cpu_addr, size); |
422 | if (!c) | ||
423 | goto no_area; | ||
424 | |||
425 | c->vm_active = 0; | ||
426 | spin_unlock_irqrestore(&consistent_lock, flags); | ||
427 | |||
428 | if ((c->vm_end - c->vm_start) != size) { | ||
429 | printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n", | ||
430 | __func__, c->vm_end - c->vm_start, size); | ||
431 | dump_stack(); | ||
432 | size = c->vm_end - c->vm_start; | ||
433 | } | ||
434 | |||
435 | idx = CONSISTENT_PTE_INDEX(c->vm_start); | ||
436 | off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1); | ||
437 | ptep = consistent_pte[idx] + off; | ||
438 | addr = c->vm_start; | ||
439 | do { | ||
440 | pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep); | ||
441 | unsigned long pfn; | ||
442 | |||
443 | ptep++; | ||
444 | addr += PAGE_SIZE; | ||
445 | off++; | ||
446 | if (off >= PTRS_PER_PTE) { | ||
447 | off = 0; | ||
448 | ptep = consistent_pte[++idx]; | ||
449 | } | ||
450 | |||
451 | if (!pte_none(pte) && pte_present(pte)) { | ||
452 | pfn = pte_pfn(pte); | ||
453 | |||
454 | if (pfn_valid(pfn)) { | ||
455 | struct page *page = pfn_to_page(pfn); | ||
456 | |||
457 | /* | ||
458 | * x86 does not mark the pages reserved... | ||
459 | */ | ||
460 | ClearPageReserved(page); | ||
461 | |||
462 | __free_page(page); | ||
463 | continue; | ||
464 | } | ||
465 | } | ||
466 | |||
467 | printk(KERN_CRIT "%s: bad page in kernel page table\n", | ||
468 | __func__); | ||
469 | } while (size -= PAGE_SIZE); | ||
470 | |||
471 | flush_tlb_kernel_range(c->vm_start, c->vm_end); | ||
472 | |||
473 | spin_lock_irqsave(&consistent_lock, flags); | ||
474 | list_del(&c->vm_list); | ||
475 | spin_unlock_irqrestore(&consistent_lock, flags); | ||
476 | |||
477 | kfree(c); | ||
478 | return; | ||
479 | 396 | ||
480 | no_area: | 397 | __dma_free_buffer(dma_to_page(dev, handle), size); |
481 | spin_unlock_irqrestore(&consistent_lock, flags); | ||
482 | printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n", | ||
483 | __func__, cpu_addr); | ||
484 | dump_stack(); | ||
485 | } | 398 | } |
486 | #else /* !CONFIG_MMU */ | ||
487 | void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, dma_addr_t handle) | ||
488 | { | ||
489 | if (dma_release_from_coherent(dev, get_order(size), cpu_addr)) | ||
490 | return; | ||
491 | kfree(cpu_addr); | ||
492 | } | ||
493 | #endif /* CONFIG_MMU */ | ||
494 | EXPORT_SYMBOL(dma_free_coherent); | 399 | EXPORT_SYMBOL(dma_free_coherent); |
495 | 400 | ||
496 | /* | 401 | /* |
497 | * Initialise the consistent memory allocation. | ||
498 | */ | ||
499 | static int __init consistent_init(void) | ||
500 | { | ||
501 | int ret = 0; | ||
502 | #ifdef CONFIG_MMU | ||
503 | pgd_t *pgd; | ||
504 | pmd_t *pmd; | ||
505 | pte_t *pte; | ||
506 | int i = 0; | ||
507 | u32 base = CONSISTENT_BASE; | ||
508 | |||
509 | do { | ||
510 | pgd = pgd_offset(&init_mm, base); | ||
511 | pmd = pmd_alloc(&init_mm, pgd, base); | ||
512 | if (!pmd) { | ||
513 | printk(KERN_ERR "%s: no pmd tables\n", __func__); | ||
514 | ret = -ENOMEM; | ||
515 | break; | ||
516 | } | ||
517 | WARN_ON(!pmd_none(*pmd)); | ||
518 | |||
519 | pte = pte_alloc_kernel(pmd, base); | ||
520 | if (!pte) { | ||
521 | printk(KERN_ERR "%s: no pte tables\n", __func__); | ||
522 | ret = -ENOMEM; | ||
523 | break; | ||
524 | } | ||
525 | |||
526 | consistent_pte[i++] = pte; | ||
527 | base += (1 << PGDIR_SHIFT); | ||
528 | } while (base < CONSISTENT_END); | ||
529 | #endif /* !CONFIG_MMU */ | ||
530 | |||
531 | return ret; | ||
532 | } | ||
533 | |||
534 | core_initcall(consistent_init); | ||
535 | |||
536 | /* | ||
537 | * Make an area consistent for devices. | 402 | * Make an area consistent for devices. |
538 | * Note: Drivers should NOT use this function directly, as it will break | 403 | * Note: Drivers should NOT use this function directly, as it will break |
539 | * platforms with CONFIG_DMABOUNCE. | 404 | * platforms with CONFIG_DMABOUNCE. |
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c index d0d17b6a3703..729602291958 100644 --- a/arch/arm/mm/fault-armv.c +++ b/arch/arm/mm/fault-armv.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <asm/pgtable.h> | 23 | #include <asm/pgtable.h> |
24 | #include <asm/tlbflush.h> | 24 | #include <asm/tlbflush.h> |
25 | 25 | ||
26 | #include "mm.h" | ||
27 | |||
26 | static unsigned long shared_pte_mask = L_PTE_MT_BUFFERABLE; | 28 | static unsigned long shared_pte_mask = L_PTE_MT_BUFFERABLE; |
27 | 29 | ||
28 | /* | 30 | /* |
@@ -151,7 +153,14 @@ void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, pte_t pte) | |||
151 | if (!pfn_valid(pfn)) | 153 | if (!pfn_valid(pfn)) |
152 | return; | 154 | return; |
153 | 155 | ||
156 | /* | ||
157 | * The zero page is never written to, so never has any dirty | ||
158 | * cache lines, and therefore never needs to be flushed. | ||
159 | */ | ||
154 | page = pfn_to_page(pfn); | 160 | page = pfn_to_page(pfn); |
161 | if (page == ZERO_PAGE(0)) | ||
162 | return; | ||
163 | |||
155 | mapping = page_mapping(page); | 164 | mapping = page_mapping(page); |
156 | #ifndef CONFIG_SMP | 165 | #ifndef CONFIG_SMP |
157 | if (test_and_clear_bit(PG_dcache_dirty, &page->flags)) | 166 | if (test_and_clear_bit(PG_dcache_dirty, &page->flags)) |
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 7f294f307c83..329594e760cd 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c | |||
@@ -35,14 +35,12 @@ static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr) | |||
35 | : | 35 | : |
36 | : "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES), "r" (zero) | 36 | : "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES), "r" (zero) |
37 | : "cc"); | 37 | : "cc"); |
38 | __flush_icache_all(); | ||
39 | } | 38 | } |
40 | 39 | ||
41 | void flush_cache_mm(struct mm_struct *mm) | 40 | void flush_cache_mm(struct mm_struct *mm) |
42 | { | 41 | { |
43 | if (cache_is_vivt()) { | 42 | if (cache_is_vivt()) { |
44 | if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) | 43 | vivt_flush_cache_mm(mm); |
45 | __cpuc_flush_user_all(); | ||
46 | return; | 44 | return; |
47 | } | 45 | } |
48 | 46 | ||
@@ -52,16 +50,13 @@ void flush_cache_mm(struct mm_struct *mm) | |||
52 | : | 50 | : |
53 | : "r" (0) | 51 | : "r" (0) |
54 | : "cc"); | 52 | : "cc"); |
55 | __flush_icache_all(); | ||
56 | } | 53 | } |
57 | } | 54 | } |
58 | 55 | ||
59 | void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) | 56 | void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end) |
60 | { | 57 | { |
61 | if (cache_is_vivt()) { | 58 | if (cache_is_vivt()) { |
62 | if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) | 59 | vivt_flush_cache_range(vma, start, end); |
63 | __cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end), | ||
64 | vma->vm_flags); | ||
65 | return; | 60 | return; |
66 | } | 61 | } |
67 | 62 | ||
@@ -71,22 +66,26 @@ void flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned | |||
71 | : | 66 | : |
72 | : "r" (0) | 67 | : "r" (0) |
73 | : "cc"); | 68 | : "cc"); |
74 | __flush_icache_all(); | ||
75 | } | 69 | } |
70 | |||
71 | if (vma->vm_flags & VM_EXEC) | ||
72 | __flush_icache_all(); | ||
76 | } | 73 | } |
77 | 74 | ||
78 | void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn) | 75 | void flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn) |
79 | { | 76 | { |
80 | if (cache_is_vivt()) { | 77 | if (cache_is_vivt()) { |
81 | if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { | 78 | vivt_flush_cache_page(vma, user_addr, pfn); |
82 | unsigned long addr = user_addr & PAGE_MASK; | ||
83 | __cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags); | ||
84 | } | ||
85 | return; | 79 | return; |
86 | } | 80 | } |
87 | 81 | ||
88 | if (cache_is_vipt_aliasing()) | 82 | if (cache_is_vipt_aliasing()) { |
89 | flush_pfn_alias(pfn, user_addr); | 83 | flush_pfn_alias(pfn, user_addr); |
84 | __flush_icache_all(); | ||
85 | } | ||
86 | |||
87 | if (vma->vm_flags & VM_EXEC && icache_is_vivt_asid_tagged()) | ||
88 | __flush_icache_all(); | ||
90 | } | 89 | } |
91 | 90 | ||
92 | void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, | 91 | void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, |
@@ -94,15 +93,13 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, | |||
94 | unsigned long len, int write) | 93 | unsigned long len, int write) |
95 | { | 94 | { |
96 | if (cache_is_vivt()) { | 95 | if (cache_is_vivt()) { |
97 | if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) { | 96 | vivt_flush_ptrace_access(vma, page, uaddr, kaddr, len, write); |
98 | unsigned long addr = (unsigned long)kaddr; | ||
99 | __cpuc_coherent_kern_range(addr, addr + len); | ||
100 | } | ||
101 | return; | 97 | return; |
102 | } | 98 | } |
103 | 99 | ||
104 | if (cache_is_vipt_aliasing()) { | 100 | if (cache_is_vipt_aliasing()) { |
105 | flush_pfn_alias(page_to_pfn(page), uaddr); | 101 | flush_pfn_alias(page_to_pfn(page), uaddr); |
102 | __flush_icache_all(); | ||
106 | return; | 103 | return; |
107 | } | 104 | } |
108 | 105 | ||
@@ -120,6 +117,8 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page, | |||
120 | 117 | ||
121 | void __flush_dcache_page(struct address_space *mapping, struct page *page) | 118 | void __flush_dcache_page(struct address_space *mapping, struct page *page) |
122 | { | 119 | { |
120 | void *addr = page_address(page); | ||
121 | |||
123 | /* | 122 | /* |
124 | * Writeback any data associated with the kernel mapping of this | 123 | * Writeback any data associated with the kernel mapping of this |
125 | * page. This ensures that data in the physical page is mutually | 124 | * page. This ensures that data in the physical page is mutually |
@@ -130,9 +129,9 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page) | |||
130 | * kmap_atomic() doesn't set the page virtual address, and | 129 | * kmap_atomic() doesn't set the page virtual address, and |
131 | * kunmap_atomic() takes care of cache flushing already. | 130 | * kunmap_atomic() takes care of cache flushing already. |
132 | */ | 131 | */ |
133 | if (page_address(page)) | 132 | if (addr) |
134 | #endif | 133 | #endif |
135 | __cpuc_flush_dcache_page(page_address(page)); | 134 | __cpuc_flush_dcache_page(addr); |
136 | 135 | ||
137 | /* | 136 | /* |
138 | * If this is a page cache page, and we have an aliasing VIPT cache, | 137 | * If this is a page cache page, and we have an aliasing VIPT cache, |
@@ -196,7 +195,16 @@ static void __flush_dcache_aliases(struct address_space *mapping, struct page *p | |||
196 | */ | 195 | */ |
197 | void flush_dcache_page(struct page *page) | 196 | void flush_dcache_page(struct page *page) |
198 | { | 197 | { |
199 | struct address_space *mapping = page_mapping(page); | 198 | struct address_space *mapping; |
199 | |||
200 | /* | ||
201 | * The zero page is never written to, so never has any dirty | ||
202 | * cache lines, and therefore never needs to be flushed. | ||
203 | */ | ||
204 | if (page == ZERO_PAGE(0)) | ||
205 | return; | ||
206 | |||
207 | mapping = page_mapping(page); | ||
200 | 208 | ||
201 | #ifndef CONFIG_SMP | 209 | #ifndef CONFIG_SMP |
202 | if (!PageHighMem(page) && mapping && !mapping_mapped(mapping)) | 210 | if (!PageHighMem(page) && mapping && !mapping_mapped(mapping)) |
@@ -242,6 +250,7 @@ void __flush_anon_page(struct vm_area_struct *vma, struct page *page, unsigned l | |||
242 | * userspace address only. | 250 | * userspace address only. |
243 | */ | 251 | */ |
244 | flush_pfn_alias(pfn, vmaddr); | 252 | flush_pfn_alias(pfn, vmaddr); |
253 | __flush_icache_all(); | ||
245 | } | 254 | } |
246 | 255 | ||
247 | /* | 256 | /* |
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index c4f6f05198e0..a888363398f8 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h | |||
@@ -24,6 +24,8 @@ struct mem_type { | |||
24 | 24 | ||
25 | const struct mem_type *get_mem_type(unsigned int type); | 25 | const struct mem_type *get_mem_type(unsigned int type); |
26 | 26 | ||
27 | extern void __flush_dcache_page(struct address_space *mapping, struct page *page); | ||
28 | |||
27 | #endif | 29 | #endif |
28 | 30 | ||
29 | struct map_desc; | 31 | struct map_desc; |
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 3e8556b16a9f..8c7fbd19a4b3 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -1036,7 +1036,7 @@ void __init paging_init(struct machine_desc *mdesc) | |||
1036 | */ | 1036 | */ |
1037 | zero_page = alloc_bootmem_low_pages(PAGE_SIZE); | 1037 | zero_page = alloc_bootmem_low_pages(PAGE_SIZE); |
1038 | empty_zero_page = virt_to_page(zero_page); | 1038 | empty_zero_page = virt_to_page(zero_page); |
1039 | flush_dcache_page(empty_zero_page); | 1039 | __flush_dcache_page(NULL, empty_zero_page); |
1040 | } | 1040 | } |
1041 | 1041 | ||
1042 | /* | 1042 | /* |
diff --git a/arch/arm/mm/vmregion.c b/arch/arm/mm/vmregion.c new file mode 100644 index 000000000000..19e09bdb1b8a --- /dev/null +++ b/arch/arm/mm/vmregion.c | |||
@@ -0,0 +1,131 @@ | |||
1 | #include <linux/spinlock.h> | ||
2 | #include <linux/list.h> | ||
3 | #include <linux/slab.h> | ||
4 | |||
5 | #include "vmregion.h" | ||
6 | |||
7 | /* | ||
8 | * VM region handling support. | ||
9 | * | ||
10 | * This should become something generic, handling VM region allocations for | ||
11 | * vmalloc and similar (ioremap, module space, etc). | ||
12 | * | ||
13 | * I envisage vmalloc()'s supporting vm_struct becoming: | ||
14 | * | ||
15 | * struct vm_struct { | ||
16 | * struct vmregion region; | ||
17 | * unsigned long flags; | ||
18 | * struct page **pages; | ||
19 | * unsigned int nr_pages; | ||
20 | * unsigned long phys_addr; | ||
21 | * }; | ||
22 | * | ||
23 | * get_vm_area() would then call vmregion_alloc with an appropriate | ||
24 | * struct vmregion head (eg): | ||
25 | * | ||
26 | * struct vmregion vmalloc_head = { | ||
27 | * .vm_list = LIST_HEAD_INIT(vmalloc_head.vm_list), | ||
28 | * .vm_start = VMALLOC_START, | ||
29 | * .vm_end = VMALLOC_END, | ||
30 | * }; | ||
31 | * | ||
32 | * However, vmalloc_head.vm_start is variable (typically, it is dependent on | ||
33 | * the amount of RAM found at boot time.) I would imagine that get_vm_area() | ||
34 | * would have to initialise this each time prior to calling vmregion_alloc(). | ||
35 | */ | ||
36 | |||
37 | struct arm_vmregion * | ||
38 | arm_vmregion_alloc(struct arm_vmregion_head *head, size_t size, gfp_t gfp) | ||
39 | { | ||
40 | unsigned long addr = head->vm_start, end = head->vm_end - size; | ||
41 | unsigned long flags; | ||
42 | struct arm_vmregion *c, *new; | ||
43 | |||
44 | if (head->vm_end - head->vm_start < size) { | ||
45 | printk(KERN_WARNING "%s: allocation too big (requested %#x)\n", | ||
46 | __func__, size); | ||
47 | goto out; | ||
48 | } | ||
49 | |||
50 | new = kmalloc(sizeof(struct arm_vmregion), gfp); | ||
51 | if (!new) | ||
52 | goto out; | ||
53 | |||
54 | spin_lock_irqsave(&head->vm_lock, flags); | ||
55 | |||
56 | list_for_each_entry(c, &head->vm_list, vm_list) { | ||
57 | if ((addr + size) < addr) | ||
58 | goto nospc; | ||
59 | if ((addr + size) <= c->vm_start) | ||
60 | goto found; | ||
61 | addr = c->vm_end; | ||
62 | if (addr > end) | ||
63 | goto nospc; | ||
64 | } | ||
65 | |||
66 | found: | ||
67 | /* | ||
68 | * Insert this entry _before_ the one we found. | ||
69 | */ | ||
70 | list_add_tail(&new->vm_list, &c->vm_list); | ||
71 | new->vm_start = addr; | ||
72 | new->vm_end = addr + size; | ||
73 | new->vm_active = 1; | ||
74 | |||
75 | spin_unlock_irqrestore(&head->vm_lock, flags); | ||
76 | return new; | ||
77 | |||
78 | nospc: | ||
79 | spin_unlock_irqrestore(&head->vm_lock, flags); | ||
80 | kfree(new); | ||
81 | out: | ||
82 | return NULL; | ||
83 | } | ||
84 | |||
85 | static struct arm_vmregion *__arm_vmregion_find(struct arm_vmregion_head *head, unsigned long addr) | ||
86 | { | ||
87 | struct arm_vmregion *c; | ||
88 | |||
89 | list_for_each_entry(c, &head->vm_list, vm_list) { | ||
90 | if (c->vm_active && c->vm_start == addr) | ||
91 | goto out; | ||
92 | } | ||
93 | c = NULL; | ||
94 | out: | ||
95 | return c; | ||
96 | } | ||
97 | |||
98 | struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *head, unsigned long addr) | ||
99 | { | ||
100 | struct arm_vmregion *c; | ||
101 | unsigned long flags; | ||
102 | |||
103 | spin_lock_irqsave(&head->vm_lock, flags); | ||
104 | c = __arm_vmregion_find(head, addr); | ||
105 | spin_unlock_irqrestore(&head->vm_lock, flags); | ||
106 | return c; | ||
107 | } | ||
108 | |||
109 | struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *head, unsigned long addr) | ||
110 | { | ||
111 | struct arm_vmregion *c; | ||
112 | unsigned long flags; | ||
113 | |||
114 | spin_lock_irqsave(&head->vm_lock, flags); | ||
115 | c = __arm_vmregion_find(head, addr); | ||
116 | if (c) | ||
117 | c->vm_active = 0; | ||
118 | spin_unlock_irqrestore(&head->vm_lock, flags); | ||
119 | return c; | ||
120 | } | ||
121 | |||
122 | void arm_vmregion_free(struct arm_vmregion_head *head, struct arm_vmregion *c) | ||
123 | { | ||
124 | unsigned long flags; | ||
125 | |||
126 | spin_lock_irqsave(&head->vm_lock, flags); | ||
127 | list_del(&c->vm_list); | ||
128 | spin_unlock_irqrestore(&head->vm_lock, flags); | ||
129 | |||
130 | kfree(c); | ||
131 | } | ||
diff --git a/arch/arm/mm/vmregion.h b/arch/arm/mm/vmregion.h new file mode 100644 index 000000000000..6b2cdbdf3a85 --- /dev/null +++ b/arch/arm/mm/vmregion.h | |||
@@ -0,0 +1,29 @@ | |||
1 | #ifndef VMREGION_H | ||
2 | #define VMREGION_H | ||
3 | |||
4 | #include <linux/spinlock.h> | ||
5 | #include <linux/list.h> | ||
6 | |||
7 | struct page; | ||
8 | |||
9 | struct arm_vmregion_head { | ||
10 | spinlock_t vm_lock; | ||
11 | struct list_head vm_list; | ||
12 | unsigned long vm_start; | ||
13 | unsigned long vm_end; | ||
14 | }; | ||
15 | |||
16 | struct arm_vmregion { | ||
17 | struct list_head vm_list; | ||
18 | unsigned long vm_start; | ||
19 | unsigned long vm_end; | ||
20 | struct page *vm_pages; | ||
21 | int vm_active; | ||
22 | }; | ||
23 | |||
24 | struct arm_vmregion *arm_vmregion_alloc(struct arm_vmregion_head *, size_t, gfp_t); | ||
25 | struct arm_vmregion *arm_vmregion_find(struct arm_vmregion_head *, unsigned long); | ||
26 | struct arm_vmregion *arm_vmregion_find_remove(struct arm_vmregion_head *, unsigned long); | ||
27 | void arm_vmregion_free(struct arm_vmregion_head *, struct arm_vmregion *); | ||
28 | |||
29 | #endif | ||
diff --git a/arch/arm/plat-nomadik/Kconfig b/arch/arm/plat-nomadik/Kconfig new file mode 100644 index 000000000000..159daf583f85 --- /dev/null +++ b/arch/arm/plat-nomadik/Kconfig | |||
@@ -0,0 +1,22 @@ | |||
1 | # We keep common IP's here for Nomadik and other similar | ||
2 | # familiy of processors from ST-Ericsson. At the moment we have | ||
3 | # just MTU, others to follow soon. | ||
4 | |||
5 | config PLAT_NOMADIK | ||
6 | bool | ||
7 | depends on ARCH_NOMADIK || ARCH_U8500 | ||
8 | default y | ||
9 | help | ||
10 | Common platform code for Nomadik and other ST-Ericsson | ||
11 | platforms. | ||
12 | |||
13 | if PLAT_NOMADIK | ||
14 | |||
15 | config HAS_MTU | ||
16 | bool | ||
17 | help | ||
18 | Support for Multi Timer Unit. MTU provides access | ||
19 | to multiple interrupt generating programmable | ||
20 | 32-bit free running decrementing counters. | ||
21 | |||
22 | endif | ||
diff --git a/arch/arm/plat-nomadik/Makefile b/arch/arm/plat-nomadik/Makefile new file mode 100644 index 000000000000..37c7cdd0f8f0 --- /dev/null +++ b/arch/arm/plat-nomadik/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | # arch/arm/plat-nomadik/Makefile | ||
2 | # Copyright 2009 ST-Ericsson | ||
3 | # Licensed under GPLv2 | ||
4 | |||
5 | obj-$(CONFIG_HAS_MTU) += timer.o | ||
diff --git a/arch/arm/mach-nomadik/include/mach/mtu.h b/arch/arm/plat-nomadik/include/plat/mtu.h index 76da7f085330..42c907258b14 100644 --- a/arch/arm/mach-nomadik/include/mach/mtu.h +++ b/arch/arm/plat-nomadik/include/plat/mtu.h | |||
@@ -1,5 +1,8 @@ | |||
1 | #ifndef __ASM_ARCH_MTU_H | 1 | #ifndef __PLAT_MTU_H |
2 | #define __ASM_ARCH_MTU_H | 2 | #define __PLAT_MTU_H |
3 | |||
4 | /* should be set by the platform code */ | ||
5 | extern void __iomem *mtu_base; | ||
3 | 6 | ||
4 | /* | 7 | /* |
5 | * The MTU device hosts four different counters, with 4 set of | 8 | * The MTU device hosts four different counters, with 4 set of |
@@ -41,5 +44,5 @@ | |||
41 | #define MTU_PCELL2 0xff8 | 44 | #define MTU_PCELL2 0xff8 |
42 | #define MTU_PCELL3 0xffC | 45 | #define MTU_PCELL3 0xffC |
43 | 46 | ||
44 | #endif /* __ASM_ARCH_MTU_H */ | 47 | #endif /* __PLAT_MTU_H */ |
45 | 48 | ||
diff --git a/arch/arm/mach-nomadik/timer.c b/arch/arm/plat-nomadik/timer.c index d1738e7061d4..62f18ad43a28 100644 --- a/arch/arm/mach-nomadik/timer.c +++ b/arch/arm/plat-nomadik/timer.c | |||
@@ -15,19 +15,14 @@ | |||
15 | #include <linux/clockchips.h> | 15 | #include <linux/clockchips.h> |
16 | #include <linux/jiffies.h> | 16 | #include <linux/jiffies.h> |
17 | #include <asm/mach/time.h> | 17 | #include <asm/mach/time.h> |
18 | #include <mach/mtu.h> | ||
19 | 18 | ||
20 | #define TIMER_CTRL 0x80 /* No divisor */ | 19 | #include <plat/mtu.h> |
21 | #define TIMER_PERIODIC 0x40 | ||
22 | #define TIMER_SZ32BIT 0x02 | ||
23 | |||
24 | /* Initial value for SRC control register: all timers use MXTAL/8 source */ | ||
25 | #define SRC_CR_INIT_MASK 0x00007fff | ||
26 | #define SRC_CR_INIT_VAL 0x2aaa8000 | ||
27 | 20 | ||
28 | static u32 nmdk_count; /* accumulated count */ | 21 | static u32 nmdk_count; /* accumulated count */ |
29 | static u32 nmdk_cycle; /* write-once */ | 22 | static u32 nmdk_cycle; /* write-once */ |
30 | static __iomem void *mtu_base; | 23 | |
24 | /* setup by the platform code */ | ||
25 | void __iomem *mtu_base; | ||
31 | 26 | ||
32 | /* | 27 | /* |
33 | * clocksource: the MTU device is a decrementing counters, so we negate | 28 | * clocksource: the MTU device is a decrementing counters, so we negate |
@@ -93,7 +88,7 @@ static struct clock_event_device nmdk_clkevt = { | |||
93 | static irqreturn_t nmdk_timer_interrupt(int irq, void *dev_id) | 88 | static irqreturn_t nmdk_timer_interrupt(int irq, void *dev_id) |
94 | { | 89 | { |
95 | /* ack: "interrupt clear register" */ | 90 | /* ack: "interrupt clear register" */ |
96 | writel( 1 << 0, mtu_base + MTU_ICR); | 91 | writel(1 << 0, mtu_base + MTU_ICR); |
97 | 92 | ||
98 | /* we can't count lost ticks, unfortunately */ | 93 | /* we can't count lost ticks, unfortunately */ |
99 | nmdk_count += nmdk_cycle; | 94 | nmdk_count += nmdk_cycle; |
@@ -125,24 +120,14 @@ static void nmdk_timer_reset(void) | |||
125 | writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0)); | 120 | writel(cr | MTU_CRn_ENA, mtu_base + MTU_CR(0)); |
126 | } | 121 | } |
127 | 122 | ||
128 | static void __init nmdk_timer_init(void) | 123 | void __init nmdk_timer_init(void) |
129 | { | 124 | { |
130 | u32 src_cr; | ||
131 | unsigned long rate; | 125 | unsigned long rate; |
132 | int bits; | 126 | int bits; |
133 | 127 | ||
134 | rate = CLOCK_TICK_RATE; /* 2.4MHz */ | 128 | rate = CLOCK_TICK_RATE; /* 2.4MHz */ |
135 | nmdk_cycle = (rate + HZ/2) / HZ; | 129 | nmdk_cycle = (rate + HZ/2) / HZ; |
136 | 130 | ||
137 | /* Configure timer sources in "system reset controller" ctrl reg */ | ||
138 | src_cr = readl(io_p2v(NOMADIK_SRC_BASE)); | ||
139 | src_cr &= SRC_CR_INIT_MASK; | ||
140 | src_cr |= SRC_CR_INIT_VAL; | ||
141 | writel(src_cr, io_p2v(NOMADIK_SRC_BASE)); | ||
142 | |||
143 | /* Save global pointer to mtu, used by functions above */ | ||
144 | mtu_base = io_p2v(NOMADIK_MTU0_BASE); | ||
145 | |||
146 | /* Init the timer and register clocksource */ | 131 | /* Init the timer and register clocksource */ |
147 | nmdk_timer_reset(); | 132 | nmdk_timer_reset(); |
148 | 133 | ||
@@ -150,7 +135,9 @@ static void __init nmdk_timer_init(void) | |||
150 | bits = 8*sizeof(nmdk_count); | 135 | bits = 8*sizeof(nmdk_count); |
151 | nmdk_clksrc.mask = CLOCKSOURCE_MASK(bits); | 136 | nmdk_clksrc.mask = CLOCKSOURCE_MASK(bits); |
152 | 137 | ||
153 | clocksource_register(&nmdk_clksrc); | 138 | if (clocksource_register(&nmdk_clksrc)) |
139 | printk(KERN_ERR "timer: failed to initialize clock " | ||
140 | "source %s\n", nmdk_clksrc.name); | ||
154 | 141 | ||
155 | /* Register irq and clockevents */ | 142 | /* Register irq and clockevents */ |
156 | setup_irq(IRQ_MTU0, &nmdk_timer_irq); | 143 | setup_irq(IRQ_MTU0, &nmdk_timer_irq); |
@@ -158,7 +145,3 @@ static void __init nmdk_timer_init(void) | |||
158 | nmdk_clkevt.cpumask = cpumask_of(0); | 145 | nmdk_clkevt.cpumask = cpumask_of(0); |
159 | clockevents_register_device(&nmdk_clkevt); | 146 | clockevents_register_device(&nmdk_clkevt); |
160 | } | 147 | } |
161 | |||
162 | struct sys_timer nomadik_timer = { | ||
163 | .init = nmdk_timer_init, | ||
164 | }; | ||
diff --git a/arch/arm/plat-omap/include/mach/memory.h b/arch/arm/plat-omap/include/mach/memory.h index 9ad41dc484c1..3325f7b49eaa 100644 --- a/arch/arm/plat-omap/include/mach/memory.h +++ b/arch/arm/plat-omap/include/mach/memory.h | |||
@@ -68,6 +68,13 @@ | |||
68 | __dma = __dma - PHYS_OFFSET + OMAP1510_LB_OFFSET; \ | 68 | __dma = __dma - PHYS_OFFSET + OMAP1510_LB_OFFSET; \ |
69 | __dma; }) | 69 | __dma; }) |
70 | 70 | ||
71 | #define __arch_dma_to_page(dev, addr) \ | ||
72 | ({ dma_addr_t __dma = addr; \ | ||
73 | if (is_lbus_device(dev)) \ | ||
74 | __dma += PHYS_OFFSET - OMAP1510_LB_OFFSET; \ | ||
75 | phys_to_page(__dma); \ | ||
76 | }) | ||
77 | |||
71 | #define __arch_dma_to_virt(dev, addr) ({ (void *) (is_lbus_device(dev) ? \ | 78 | #define __arch_dma_to_virt(dev, addr) ({ (void *) (is_lbus_device(dev) ? \ |
72 | lbus_to_virt(addr) : \ | 79 | lbus_to_virt(addr) : \ |
73 | __phys_to_virt(addr)); }) | 80 | __phys_to_virt(addr)); }) |
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 94be7bb6cb9a..07b976da6174 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types | |||
@@ -12,7 +12,7 @@ | |||
12 | # | 12 | # |
13 | # http://www.arm.linux.org.uk/developer/machines/?action=new | 13 | # http://www.arm.linux.org.uk/developer/machines/?action=new |
14 | # | 14 | # |
15 | # Last update: Fri Sep 18 21:42:00 2009 | 15 | # Last update: Wed Nov 25 22:14:58 2009 |
16 | # | 16 | # |
17 | # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number | 17 | # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number |
18 | # | 18 | # |
@@ -928,7 +928,7 @@ palmt5 MACH_PALMT5 PALMT5 917 | |||
928 | palmtc MACH_PALMTC PALMTC 918 | 928 | palmtc MACH_PALMTC PALMTC 918 |
929 | omap_apollon MACH_OMAP_APOLLON OMAP_APOLLON 919 | 929 | omap_apollon MACH_OMAP_APOLLON OMAP_APOLLON 919 |
930 | mxc30030evb MACH_MXC30030EVB MXC30030EVB 920 | 930 | mxc30030evb MACH_MXC30030EVB MXC30030EVB 920 |
931 | rea_2d MACH_REA_2D REA_2D 921 | 931 | rea_cpu2 MACH_REA_2D REA_2D 921 |
932 | eti3e524 MACH_TI3E524 TI3E524 922 | 932 | eti3e524 MACH_TI3E524 TI3E524 922 |
933 | ateb9200 MACH_ATEB9200 ATEB9200 923 | 933 | ateb9200 MACH_ATEB9200 ATEB9200 923 |
934 | auckland MACH_AUCKLAND AUCKLAND 924 | 934 | auckland MACH_AUCKLAND AUCKLAND 924 |
@@ -2421,3 +2421,118 @@ liberty MACH_LIBERTY LIBERTY 2434 | |||
2421 | mh355 MACH_MH355 MH355 2435 | 2421 | mh355 MACH_MH355 MH355 2435 |
2422 | pc7802 MACH_PC7802 PC7802 2436 | 2422 | pc7802 MACH_PC7802 PC7802 2436 |
2423 | gnet_sgc MACH_GNET_SGC GNET_SGC 2437 | 2423 | gnet_sgc MACH_GNET_SGC GNET_SGC 2437 |
2424 | einstein15 MACH_EINSTEIN15 EINSTEIN15 2438 | ||
2425 | cmpd MACH_CMPD CMPD 2439 | ||
2426 | davinci_hase1 MACH_DAVINCI_HASE1 DAVINCI_HASE1 2440 | ||
2427 | lgeincitephone MACH_LGEINCITEPHONE LGEINCITEPHONE 2441 | ||
2428 | ea313x MACH_EA313X EA313X 2442 | ||
2429 | fwbd_39064 MACH_FWBD_39064 FWBD_39064 2443 | ||
2430 | fwbd_390128 MACH_FWBD_390128 FWBD_390128 2444 | ||
2431 | pelco_moe MACH_PELCO_MOE PELCO_MOE 2445 | ||
2432 | minimix27 MACH_MINIMIX27 MINIMIX27 2446 | ||
2433 | omap3_thunder MACH_OMAP3_THUNDER OMAP3_THUNDER 2447 | ||
2434 | passionc MACH_PASSIONC PASSIONC 2448 | ||
2435 | mx27amata MACH_MX27AMATA MX27AMATA 2449 | ||
2436 | bgat1 MACH_BGAT1 BGAT1 2450 | ||
2437 | buzz MACH_BUZZ BUZZ 2451 | ||
2438 | mb9g20 MACH_MB9G20 MB9G20 2452 | ||
2439 | yushan MACH_YUSHAN YUSHAN 2453 | ||
2440 | lizard MACH_LIZARD LIZARD 2454 | ||
2441 | omap3polycom MACH_OMAP3POLYCOM OMAP3POLYCOM 2455 | ||
2442 | smdkv210 MACH_SMDKV210 SMDKV210 2456 | ||
2443 | bravo MACH_BRAVO BRAVO 2457 | ||
2444 | siogentoo1 MACH_SIOGENTOO1 SIOGENTOO1 2458 | ||
2445 | siogentoo2 MACH_SIOGENTOO2 SIOGENTOO2 2459 | ||
2446 | sm3k MACH_SM3K SM3K 2460 | ||
2447 | acer_tempo_f900 MACH_ACER_TEMPO_F900 ACER_TEMPO_F900 2461 | ||
2448 | sst61vc010_dev MACH_SST61VC010_DEV SST61VC010_DEV 2462 | ||
2449 | glittertind MACH_GLITTERTIND GLITTERTIND 2463 | ||
2450 | omap_zoom3 MACH_OMAP_ZOOM3 OMAP_ZOOM3 2464 | ||
2451 | omap_3630sdp MACH_OMAP_3630SDP OMAP_3630SDP 2465 | ||
2452 | cybook2440 MACH_CYBOOK2440 CYBOOK2440 2466 | ||
2453 | torino_s MACH_TORINO_S TORINO_S 2467 | ||
2454 | havana MACH_HAVANA HAVANA 2468 | ||
2455 | beaumont_11 MACH_BEAUMONT_11 BEAUMONT_11 2469 | ||
2456 | vanguard MACH_VANGUARD VANGUARD 2470 | ||
2457 | s5pc110_draco MACH_S5PC110_DRACO S5PC110_DRACO 2471 | ||
2458 | cartesio_two MACH_CARTESIO_TWO CARTESIO_TWO 2472 | ||
2459 | aster MACH_ASTER ASTER 2473 | ||
2460 | voguesv210 MACH_VOGUESV210 VOGUESV210 2474 | ||
2461 | acm500x MACH_ACM500X ACM500X 2475 | ||
2462 | km9260 MACH_KM9260 KM9260 2476 | ||
2463 | nideflexg1 MACH_NIDEFLEXG1 NIDEFLEXG1 2477 | ||
2464 | ctera_plug_io MACH_CTERA_PLUG_IO CTERA_PLUG_IO 2478 | ||
2465 | smartq7 MACH_SMARTQ7 SMARTQ7 2479 | ||
2466 | at91sam9g10ek2 MACH_AT91SAM9G10EK2 AT91SAM9G10EK2 2480 | ||
2467 | asusp527 MACH_ASUSP527 ASUSP527 2481 | ||
2468 | at91sam9g20mpm2 MACH_AT91SAM9G20MPM2 AT91SAM9G20MPM2 2482 | ||
2469 | topasa900 MACH_TOPASA900 TOPASA900 2483 | ||
2470 | electrum_100 MACH_ELECTRUM_100 ELECTRUM_100 2484 | ||
2471 | mx51grb MACH_MX51GRB MX51GRB 2485 | ||
2472 | xea300 MACH_XEA300 XEA300 2486 | ||
2473 | htcstartrek MACH_HTCSTARTREK HTCSTARTREK 2487 | ||
2474 | lima MACH_LIMA LIMA 2488 | ||
2475 | csb740 MACH_CSB740 CSB740 2489 | ||
2476 | usb_s8815 MACH_USB_S8815 USB_S8815 2490 | ||
2477 | watson_efm_plugin MACH_WATSON_EFM_PLUGIN WATSON_EFM_PLUGIN 2491 | ||
2478 | milkyway MACH_MILKYWAY MILKYWAY 2492 | ||
2479 | g4evm MACH_G4EVM G4EVM 2493 | ||
2480 | picomod6 MACH_PICOMOD6 PICOMOD6 2494 | ||
2481 | omapl138_hawkboard MACH_OMAPL138_HAWKBOARD OMAPL138_HAWKBOARD 2495 | ||
2482 | ip6000 MACH_IP6000 IP6000 2496 | ||
2483 | ip6010 MACH_IP6010 IP6010 2497 | ||
2484 | utm400 MACH_UTM400 UTM400 2498 | ||
2485 | omap3_zybex MACH_OMAP3_ZYBEX OMAP3_ZYBEX 2499 | ||
2486 | wireless_space MACH_WIRELESS_SPACE WIRELESS_SPACE 2500 | ||
2487 | sx560 MACH_SX560 SX560 2501 | ||
2488 | ts41x MACH_TS41X TS41X 2502 | ||
2489 | elphel10373 MACH_ELPHEL10373 ELPHEL10373 2503 | ||
2490 | rhobot MACH_RHOBOT RHOBOT 2504 | ||
2491 | mx51_refresh MACH_MX51_REFRESH MX51_REFRESH 2505 | ||
2492 | ls9260 MACH_LS9260 LS9260 2506 | ||
2493 | shank MACH_SHANK SHANK 2507 | ||
2494 | qsd8x50_st1 MACH_QSD8X50_ST1 QSD8X50_ST1 2508 | ||
2495 | at91sam9m10ekes MACH_AT91SAM9M10EKES AT91SAM9M10EKES 2509 | ||
2496 | hiram MACH_HIRAM HIRAM 2510 | ||
2497 | phy3250 MACH_PHY3250 PHY3250 2511 | ||
2498 | ea3250 MACH_EA3250 EA3250 2512 | ||
2499 | fdi3250 MACH_FDI3250 FDI3250 2513 | ||
2500 | whitestone MACH_WHITESTONE WHITESTONE 2514 | ||
2501 | at91sam9263nit MACH_AT91SAM9263NIT AT91SAM9263NIT 2515 | ||
2502 | ccmx51 MACH_CCMX51 CCMX51 2516 | ||
2503 | ccmx51js MACH_CCMX51JS CCMX51JS 2517 | ||
2504 | ccwmx51 MACH_CCWMX51 CCWMX51 2518 | ||
2505 | ccwmx51js MACH_CCWMX51JS CCWMX51JS 2519 | ||
2506 | mini6410 MACH_MINI6410 MINI6410 2520 | ||
2507 | tiny6410 MACH_TINY6410 TINY6410 2521 | ||
2508 | nano6410 MACH_NANO6410 NANO6410 2522 | ||
2509 | at572d940hfnldb MACH_AT572D940HFNLDB AT572D940HFNLDB 2523 | ||
2510 | htcleo MACH_HTCLEO HTCLEO 2524 | ||
2511 | avp13 MACH_AVP13 AVP13 2525 | ||
2512 | xxsvideod MACH_XXSVIDEOD XXSVIDEOD 2526 | ||
2513 | vpnext MACH_VPNEXT VPNEXT 2527 | ||
2514 | swarco_itc3 MACH_SWARCO_ITC3 SWARCO_ITC3 2528 | ||
2515 | tx51 MACH_TX51 TX51 2529 | ||
2516 | dolby_cat1021 MACH_DOLBY_CAT1021 DOLBY_CAT1021 2530 | ||
2517 | mx28evk MACH_MX28EVK MX28EVK 2531 | ||
2518 | phoenix260 MACH_PHOENIX260 PHOENIX260 2532 | ||
2519 | uvaca_stork MACH_UVACA_STORK UVACA_STORK 2533 | ||
2520 | smartq5 MACH_SMARTQ5 SMARTQ5 2534 | ||
2521 | all3078 MACH_ALL3078 ALL3078 2535 | ||
2522 | ctera_2bay_ds MACH_CTERA_2BAY_DS CTERA_2BAY_DS 2536 | ||
2523 | siogentoo3 MACH_SIOGENTOO3 SIOGENTOO3 2537 | ||
2524 | epb5000 MACH_EPB5000 EPB5000 2538 | ||
2525 | hy9263 MACH_HY9263 HY9263 2539 | ||
2526 | acer_tempo_m900 MACH_ACER_TEMPO_M900 ACER_TEMPO_M900 2540 | ||
2527 | acer_tempo_dx650 MACH_ACER_TEMPO_DX900 ACER_TEMPO_DX900 2541 | ||
2528 | acer_tempo_x960 MACH_ACER_TEMPO_X960 ACER_TEMPO_X960 2542 | ||
2529 | acer_eten_v900 MACH_ACER_ETEN_V900 ACER_ETEN_V900 2543 | ||
2530 | acer_eten_x900 MACH_ACER_ETEN_X900 ACER_ETEN_X900 2544 | ||
2531 | bonnell MACH_BONNELL BONNELL 2545 | ||
2532 | oht_mx27 MACH_OHT_MX27 OHT_MX27 2546 | ||
2533 | htcquartz MACH_HTCQUARTZ HTCQUARTZ 2547 | ||
2534 | davinci_dm6467tevm MACH_DAVINCI_DM6467TEVM DAVINCI_DM6467TEVM 2548 | ||
2535 | c3ax03 MACH_C3AX03 C3AX03 2549 | ||
2536 | mxt_td60 MACH_MXT_TD60 MXT_TD60 2550 | ||
2537 | esyx MACH_ESYX ESYX 2551 | ||
2538 | bulldog MACH_BULLDOG BULLDOG 2553 | ||
diff --git a/arch/blackfin/kernel/bfin_dma_5xx.c b/arch/blackfin/kernel/bfin_dma_5xx.c index 1f170216d2f9..3946aff4f414 100644 --- a/arch/blackfin/kernel/bfin_dma_5xx.c +++ b/arch/blackfin/kernel/bfin_dma_5xx.c | |||
@@ -225,8 +225,13 @@ int blackfin_dma_suspend(void) | |||
225 | void blackfin_dma_resume(void) | 225 | void blackfin_dma_resume(void) |
226 | { | 226 | { |
227 | int i; | 227 | int i; |
228 | for (i = 0; i < MAX_DMA_SUSPEND_CHANNELS; ++i) | 228 | |
229 | dma_ch[i].regs->peripheral_map = dma_ch[i].saved_peripheral_map; | 229 | for (i = 0; i < MAX_DMA_CHANNELS; ++i) { |
230 | dma_ch[i].regs->cfg = 0; | ||
231 | |||
232 | if (i < MAX_DMA_SUSPEND_CHANNELS) | ||
233 | dma_ch[i].regs->peripheral_map = dma_ch[i].saved_peripheral_map; | ||
234 | } | ||
230 | } | 235 | } |
231 | #endif | 236 | #endif |
232 | 237 | ||
diff --git a/arch/blackfin/kernel/cplb-mpu/cplbinit.c b/arch/blackfin/kernel/cplb-mpu/cplbinit.c index f7b9cdce8239..b52c1f8c4bc0 100644 --- a/arch/blackfin/kernel/cplb-mpu/cplbinit.c +++ b/arch/blackfin/kernel/cplb-mpu/cplbinit.c | |||
@@ -38,7 +38,7 @@ void __init generate_cplb_tables_cpu(unsigned int cpu) | |||
38 | 38 | ||
39 | #ifdef CONFIG_BFIN_EXTMEM_DCACHEABLE | 39 | #ifdef CONFIG_BFIN_EXTMEM_DCACHEABLE |
40 | d_cache = CPLB_L1_CHBL; | 40 | d_cache = CPLB_L1_CHBL; |
41 | #ifdef CONFIG_BFIN_EXTMEM_WRITETROUGH | 41 | #ifdef CONFIG_BFIN_EXTMEM_WRITETHROUGH |
42 | d_cache |= CPLB_L1_AOW | CPLB_WT; | 42 | d_cache |= CPLB_L1_AOW | CPLB_WT; |
43 | #endif | 43 | #endif |
44 | #endif | 44 | #endif |
diff --git a/arch/blackfin/kernel/process.c b/arch/blackfin/kernel/process.c index 430ae39456e8..5cc7e2e9e415 100644 --- a/arch/blackfin/kernel/process.c +++ b/arch/blackfin/kernel/process.c | |||
@@ -151,7 +151,7 @@ void start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_ | |||
151 | regs->pc = new_ip; | 151 | regs->pc = new_ip; |
152 | if (current->mm) | 152 | if (current->mm) |
153 | regs->p5 = current->mm->start_data; | 153 | regs->p5 = current->mm->start_data; |
154 | #ifdef CONFIG_SMP | 154 | #ifndef CONFIG_SMP |
155 | task_thread_info(current)->l1_task_info.stack_start = | 155 | task_thread_info(current)->l1_task_info.stack_start = |
156 | (void *)current->mm->context.stack_start; | 156 | (void *)current->mm->context.stack_start; |
157 | task_thread_info(current)->l1_task_info.lowest_sp = (void *)new_sp; | 157 | task_thread_info(current)->l1_task_info.lowest_sp = (void *)new_sp; |
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c index 0982b5d5af10..56b0ba12175f 100644 --- a/arch/blackfin/kernel/ptrace.c +++ b/arch/blackfin/kernel/ptrace.c | |||
@@ -315,7 +315,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
315 | case BFIN_MEM_ACCESS_CORE: | 315 | case BFIN_MEM_ACCESS_CORE: |
316 | case BFIN_MEM_ACCESS_CORE_ONLY: | 316 | case BFIN_MEM_ACCESS_CORE_ONLY: |
317 | copied = access_process_vm(child, addr, &data, | 317 | copied = access_process_vm(child, addr, &data, |
318 | to_copy, 0); | 318 | to_copy, 1); |
319 | if (copied) | 319 | if (copied) |
320 | break; | 320 | break; |
321 | 321 | ||
diff --git a/arch/blackfin/mach-bf518/include/mach/anomaly.h b/arch/blackfin/mach-bf518/include/mach/anomaly.h index e9c65390edd1..2829dd0400f1 100644 --- a/arch/blackfin/mach-bf518/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf518/include/mach/anomaly.h | |||
@@ -1,9 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | * File: include/asm-blackfin/mach-bf518/anomaly.h | 2 | * DO NOT EDIT THIS FILE |
3 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 3 | * This file is under version control at |
4 | * svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/ | ||
5 | * and can be replaced with that version at any time | ||
6 | * DO NOT EDIT THIS FILE | ||
4 | * | 7 | * |
5 | * Copyright (C) 2004-2009 Analog Devices Inc. | 8 | * Copyright 2004-2009 Analog Devices Inc. |
6 | * Licensed under the GPL-2 or later. | 9 | * Licensed under the ADI BSD license. |
10 | * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd | ||
7 | */ | 11 | */ |
8 | 12 | ||
9 | /* This file should be up to date with: | 13 | /* This file should be up to date with: |
@@ -70,6 +74,10 @@ | |||
70 | #define ANOMALY_05000461 (1) | 74 | #define ANOMALY_05000461 (1) |
71 | /* Synchronization Problem at Startup May Cause SPORT Transmit Channels to Misalign */ | 75 | /* Synchronization Problem at Startup May Cause SPORT Transmit Channels to Misalign */ |
72 | #define ANOMALY_05000462 (1) | 76 | #define ANOMALY_05000462 (1) |
77 | /* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */ | ||
78 | #define ANOMALY_05000473 (1) | ||
79 | /* TESTSET Instruction Cannot Be Interrupted */ | ||
80 | #define ANOMALY_05000477 (1) | ||
73 | 81 | ||
74 | /* Anomalies that don't exist on this proc */ | 82 | /* Anomalies that don't exist on this proc */ |
75 | #define ANOMALY_05000099 (0) | 83 | #define ANOMALY_05000099 (0) |
@@ -133,5 +141,7 @@ | |||
133 | #define ANOMALY_05000450 (0) | 141 | #define ANOMALY_05000450 (0) |
134 | #define ANOMALY_05000465 (0) | 142 | #define ANOMALY_05000465 (0) |
135 | #define ANOMALY_05000467 (0) | 143 | #define ANOMALY_05000467 (0) |
144 | #define ANOMALY_05000474 (0) | ||
145 | #define ANOMALY_05000475 (0) | ||
136 | 146 | ||
137 | #endif | 147 | #endif |
diff --git a/arch/blackfin/mach-bf527/include/mach/anomaly.h b/arch/blackfin/mach-bf527/include/mach/anomaly.h index 3f9052687fa8..02040df8ec80 100644 --- a/arch/blackfin/mach-bf527/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf527/include/mach/anomaly.h | |||
@@ -1,14 +1,18 @@ | |||
1 | /* | 1 | /* |
2 | * File: include/asm-blackfin/mach-bf527/anomaly.h | 2 | * DO NOT EDIT THIS FILE |
3 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 3 | * This file is under version control at |
4 | * svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/ | ||
5 | * and can be replaced with that version at any time | ||
6 | * DO NOT EDIT THIS FILE | ||
4 | * | 7 | * |
5 | * Copyright (C) 2004-2009 Analog Devices Inc. | 8 | * Copyright 2004-2009 Analog Devices Inc. |
6 | * Licensed under the GPL-2 or later. | 9 | * Licensed under the ADI BSD license. |
10 | * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd | ||
7 | */ | 11 | */ |
8 | 12 | ||
9 | /* This file should be up to date with: | 13 | /* This file should be up to date with: |
10 | * - Revision D, 08/14/2009; ADSP-BF526 Blackfin Processor Anomaly List | 14 | * - Revision D, 08/14/2009; ADSP-BF526 Blackfin Processor Anomaly List |
11 | * - Revision F, 03/03/2009; ADSP-BF527 Blackfin Processor Anomaly List | 15 | * - Revision G, 08/25/2009; ADSP-BF527 Blackfin Processor Anomaly List |
12 | */ | 16 | */ |
13 | 17 | ||
14 | #ifndef _MACH_ANOMALY_H_ | 18 | #ifndef _MACH_ANOMALY_H_ |
@@ -200,6 +204,10 @@ | |||
200 | #define ANOMALY_05000467 (1) | 204 | #define ANOMALY_05000467 (1) |
201 | /* PLL Latches Incorrect Settings During Reset */ | 205 | /* PLL Latches Incorrect Settings During Reset */ |
202 | #define ANOMALY_05000469 (1) | 206 | #define ANOMALY_05000469 (1) |
207 | /* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */ | ||
208 | #define ANOMALY_05000473 (1) | ||
209 | /* TESTSET Instruction Cannot Be Interrupted */ | ||
210 | #define ANOMALY_05000477 (1) | ||
203 | 211 | ||
204 | /* Anomalies that don't exist on this proc */ | 212 | /* Anomalies that don't exist on this proc */ |
205 | #define ANOMALY_05000099 (0) | 213 | #define ANOMALY_05000099 (0) |
@@ -250,5 +258,7 @@ | |||
250 | #define ANOMALY_05000412 (0) | 258 | #define ANOMALY_05000412 (0) |
251 | #define ANOMALY_05000447 (0) | 259 | #define ANOMALY_05000447 (0) |
252 | #define ANOMALY_05000448 (0) | 260 | #define ANOMALY_05000448 (0) |
261 | #define ANOMALY_05000474 (0) | ||
262 | #define ANOMALY_05000475 (0) | ||
253 | 263 | ||
254 | #endif | 264 | #endif |
diff --git a/arch/blackfin/mach-bf533/include/mach/anomaly.h b/arch/blackfin/mach-bf533/include/mach/anomaly.h index cd83db2fb1a1..9b3f7a27714d 100644 --- a/arch/blackfin/mach-bf533/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf533/include/mach/anomaly.h | |||
@@ -1,9 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | * File: include/asm-blackfin/mach-bf533/anomaly.h | 2 | * DO NOT EDIT THIS FILE |
3 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 3 | * This file is under version control at |
4 | * svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/ | ||
5 | * and can be replaced with that version at any time | ||
6 | * DO NOT EDIT THIS FILE | ||
4 | * | 7 | * |
5 | * Copyright (C) 2004-2009 Analog Devices Inc. | 8 | * Copyright 2004-2009 Analog Devices Inc. |
6 | * Licensed under the GPL-2 or later. | 9 | * Licensed under the ADI BSD license. |
10 | * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd | ||
7 | */ | 11 | */ |
8 | 12 | ||
9 | /* This file should be up to date with: | 13 | /* This file should be up to date with: |
@@ -202,6 +206,10 @@ | |||
202 | #define ANOMALY_05000443 (1) | 206 | #define ANOMALY_05000443 (1) |
203 | /* False Hardware Error when RETI Points to Invalid Memory */ | 207 | /* False Hardware Error when RETI Points to Invalid Memory */ |
204 | #define ANOMALY_05000461 (1) | 208 | #define ANOMALY_05000461 (1) |
209 | /* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */ | ||
210 | #define ANOMALY_05000473 (1) | ||
211 | /* TESTSET Instruction Cannot Be Interrupted */ | ||
212 | #define ANOMALY_05000477 (1) | ||
205 | 213 | ||
206 | /* These anomalies have been "phased" out of analog.com anomaly sheets and are | 214 | /* These anomalies have been "phased" out of analog.com anomaly sheets and are |
207 | * here to show running on older silicon just isn't feasible. | 215 | * here to show running on older silicon just isn't feasible. |
@@ -349,5 +357,7 @@ | |||
349 | #define ANOMALY_05000450 (0) | 357 | #define ANOMALY_05000450 (0) |
350 | #define ANOMALY_05000465 (0) | 358 | #define ANOMALY_05000465 (0) |
351 | #define ANOMALY_05000467 (0) | 359 | #define ANOMALY_05000467 (0) |
360 | #define ANOMALY_05000474 (0) | ||
361 | #define ANOMALY_05000475 (0) | ||
352 | 362 | ||
353 | #endif | 363 | #endif |
diff --git a/arch/blackfin/mach-bf537/include/mach/anomaly.h b/arch/blackfin/mach-bf537/include/mach/anomaly.h index f091ad2d8ea8..d2c427bc6656 100644 --- a/arch/blackfin/mach-bf537/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf537/include/mach/anomaly.h | |||
@@ -1,9 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | * File: include/asm-blackfin/mach-bf537/anomaly.h | 2 | * DO NOT EDIT THIS FILE |
3 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 3 | * This file is under version control at |
4 | * svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/ | ||
5 | * and can be replaced with that version at any time | ||
6 | * DO NOT EDIT THIS FILE | ||
4 | * | 7 | * |
5 | * Copyright (C) 2004-2009 Analog Devices Inc. | 8 | * Copyright 2004-2009 Analog Devices Inc. |
6 | * Licensed under the GPL-2 or later. | 9 | * Licensed under the ADI BSD license. |
10 | * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd | ||
7 | */ | 11 | */ |
8 | 12 | ||
9 | /* This file should be up to date with: | 13 | /* This file should be up to date with: |
@@ -156,6 +160,10 @@ | |||
156 | #define ANOMALY_05000443 (1) | 160 | #define ANOMALY_05000443 (1) |
157 | /* False Hardware Error when RETI Points to Invalid Memory */ | 161 | /* False Hardware Error when RETI Points to Invalid Memory */ |
158 | #define ANOMALY_05000461 (1) | 162 | #define ANOMALY_05000461 (1) |
163 | /* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */ | ||
164 | #define ANOMALY_05000473 (1) | ||
165 | /* TESTSET Instruction Cannot Be Interrupted */ | ||
166 | #define ANOMALY_05000477 (1) | ||
159 | 167 | ||
160 | /* Anomalies that don't exist on this proc */ | 168 | /* Anomalies that don't exist on this proc */ |
161 | #define ANOMALY_05000099 (0) | 169 | #define ANOMALY_05000099 (0) |
@@ -202,5 +210,7 @@ | |||
202 | #define ANOMALY_05000450 (0) | 210 | #define ANOMALY_05000450 (0) |
203 | #define ANOMALY_05000465 (0) | 211 | #define ANOMALY_05000465 (0) |
204 | #define ANOMALY_05000467 (0) | 212 | #define ANOMALY_05000467 (0) |
213 | #define ANOMALY_05000474 (0) | ||
214 | #define ANOMALY_05000475 (0) | ||
205 | 215 | ||
206 | #endif | 216 | #endif |
diff --git a/arch/blackfin/mach-bf538/include/mach/anomaly.h b/arch/blackfin/mach-bf538/include/mach/anomaly.h index 26b76083e14c..d882b7e6f59b 100644 --- a/arch/blackfin/mach-bf538/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf538/include/mach/anomaly.h | |||
@@ -1,9 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | * File: include/asm-blackfin/mach-bf538/anomaly.h | 2 | * DO NOT EDIT THIS FILE |
3 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 3 | * This file is under version control at |
4 | * svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/ | ||
5 | * and can be replaced with that version at any time | ||
6 | * DO NOT EDIT THIS FILE | ||
4 | * | 7 | * |
5 | * Copyright (C) 2004-2009 Analog Devices Inc. | 8 | * Copyright 2004-2009 Analog Devices Inc. |
6 | * Licensed under the GPL-2 or later. | 9 | * Licensed under the ADI BSD license. |
10 | * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd | ||
7 | */ | 11 | */ |
8 | 12 | ||
9 | /* This file should be up to date with: | 13 | /* This file should be up to date with: |
@@ -128,6 +132,10 @@ | |||
128 | #define ANOMALY_05000443 (1) | 132 | #define ANOMALY_05000443 (1) |
129 | /* False Hardware Error when RETI Points to Invalid Memory */ | 133 | /* False Hardware Error when RETI Points to Invalid Memory */ |
130 | #define ANOMALY_05000461 (1) | 134 | #define ANOMALY_05000461 (1) |
135 | /* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */ | ||
136 | #define ANOMALY_05000473 (1) | ||
137 | /* TESTSET Instruction Cannot Be Interrupted */ | ||
138 | #define ANOMALY_05000477 (1) | ||
131 | 139 | ||
132 | /* Anomalies that don't exist on this proc */ | 140 | /* Anomalies that don't exist on this proc */ |
133 | #define ANOMALY_05000099 (0) | 141 | #define ANOMALY_05000099 (0) |
@@ -176,5 +184,7 @@ | |||
176 | #define ANOMALY_05000450 (0) | 184 | #define ANOMALY_05000450 (0) |
177 | #define ANOMALY_05000465 (0) | 185 | #define ANOMALY_05000465 (0) |
178 | #define ANOMALY_05000467 (0) | 186 | #define ANOMALY_05000467 (0) |
187 | #define ANOMALY_05000474 (0) | ||
188 | #define ANOMALY_05000475 (0) | ||
179 | 189 | ||
180 | #endif | 190 | #endif |
diff --git a/arch/blackfin/mach-bf548/include/mach/anomaly.h b/arch/blackfin/mach-bf548/include/mach/anomaly.h index 52b116ae522a..7d08c7524498 100644 --- a/arch/blackfin/mach-bf548/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf548/include/mach/anomaly.h | |||
@@ -1,9 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | * File: include/asm-blackfin/mach-bf548/anomaly.h | 2 | * DO NOT EDIT THIS FILE |
3 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 3 | * This file is under version control at |
4 | * svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/ | ||
5 | * and can be replaced with that version at any time | ||
6 | * DO NOT EDIT THIS FILE | ||
4 | * | 7 | * |
5 | * Copyright (C) 2004-2009 Analog Devices Inc. | 8 | * Copyright 2004-2009 Analog Devices Inc. |
6 | * Licensed under the GPL-2 or later. | 9 | * Licensed under the ADI BSD license. |
10 | * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd | ||
7 | */ | 11 | */ |
8 | 12 | ||
9 | /* This file should be up to date with: | 13 | /* This file should be up to date with: |
@@ -24,6 +28,8 @@ | |||
24 | #define ANOMALY_05000119 (1) | 28 | #define ANOMALY_05000119 (1) |
25 | /* Rx.H Cannot Be Used to Access 16-bit System MMR Registers */ | 29 | /* Rx.H Cannot Be Used to Access 16-bit System MMR Registers */ |
26 | #define ANOMALY_05000122 (1) | 30 | #define ANOMALY_05000122 (1) |
31 | /* Data Corruption with Cached External Memory and Non-Cached On-Chip L2 Memory */ | ||
32 | #define ANOMALY_05000220 (1) | ||
27 | /* False Hardware Error from an Access in the Shadow of a Conditional Branch */ | 33 | /* False Hardware Error from an Access in the Shadow of a Conditional Branch */ |
28 | #define ANOMALY_05000245 (1) | 34 | #define ANOMALY_05000245 (1) |
29 | /* Sensitivity To Noise with Slow Input Edge Rates on External SPORT TX and RX Clocks */ | 35 | /* Sensitivity To Noise with Slow Input Edge Rates on External SPORT TX and RX Clocks */ |
@@ -200,6 +206,14 @@ | |||
200 | #define ANOMALY_05000466 (1) | 206 | #define ANOMALY_05000466 (1) |
201 | /* Possible RX data corruption when control & data EP FIFOs are accessed via the core */ | 207 | /* Possible RX data corruption when control & data EP FIFOs are accessed via the core */ |
202 | #define ANOMALY_05000467 (1) | 208 | #define ANOMALY_05000467 (1) |
209 | /* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */ | ||
210 | #define ANOMALY_05000473 (1) | ||
211 | /* Access to DDR-SDRAM causes system hang under certain PLL/VR settings */ | ||
212 | #define ANOMALY_05000474 (1) | ||
213 | /* Core Hang With L2/L3 Configured in Writeback Cache Mode */ | ||
214 | #define ANOMALY_05000475 (1) | ||
215 | /* TESTSET Instruction Cannot Be Interrupted */ | ||
216 | #define ANOMALY_05000477 (1) | ||
203 | 217 | ||
204 | /* Anomalies that don't exist on this proc */ | 218 | /* Anomalies that don't exist on this proc */ |
205 | #define ANOMALY_05000099 (0) | 219 | #define ANOMALY_05000099 (0) |
@@ -215,7 +229,6 @@ | |||
215 | #define ANOMALY_05000198 (0) | 229 | #define ANOMALY_05000198 (0) |
216 | #define ANOMALY_05000202 (0) | 230 | #define ANOMALY_05000202 (0) |
217 | #define ANOMALY_05000215 (0) | 231 | #define ANOMALY_05000215 (0) |
218 | #define ANOMALY_05000220 (0) | ||
219 | #define ANOMALY_05000227 (0) | 232 | #define ANOMALY_05000227 (0) |
220 | #define ANOMALY_05000230 (0) | 233 | #define ANOMALY_05000230 (0) |
221 | #define ANOMALY_05000231 (0) | 234 | #define ANOMALY_05000231 (0) |
diff --git a/arch/blackfin/mach-bf561/atomic.S b/arch/blackfin/mach-bf561/atomic.S index 0261a5e751b3..f99f174b129f 100644 --- a/arch/blackfin/mach-bf561/atomic.S +++ b/arch/blackfin/mach-bf561/atomic.S | |||
@@ -19,6 +19,16 @@ | |||
19 | \reg\().h = _corelock; | 19 | \reg\().h = _corelock; |
20 | .endm | 20 | .endm |
21 | 21 | ||
22 | .macro safe_testset addr:req, scratch:req | ||
23 | #if ANOMALY_05000477 | ||
24 | cli \scratch; | ||
25 | testset (\addr); | ||
26 | sti \scratch; | ||
27 | #else | ||
28 | testset (\addr); | ||
29 | #endif | ||
30 | .endm | ||
31 | |||
22 | /* | 32 | /* |
23 | * r0 = address of atomic data to flush and invalidate (32bit). | 33 | * r0 = address of atomic data to flush and invalidate (32bit). |
24 | * | 34 | * |
@@ -33,7 +43,7 @@ ENTRY(_get_core_lock) | |||
33 | cli r0; | 43 | cli r0; |
34 | coreslot_loadaddr p0; | 44 | coreslot_loadaddr p0; |
35 | .Lretry_corelock: | 45 | .Lretry_corelock: |
36 | testset (p0); | 46 | safe_testset p0, r2; |
37 | if cc jump .Ldone_corelock; | 47 | if cc jump .Ldone_corelock; |
38 | SSYNC(r2); | 48 | SSYNC(r2); |
39 | jump .Lretry_corelock | 49 | jump .Lretry_corelock |
@@ -56,7 +66,7 @@ ENTRY(_get_core_lock_noflush) | |||
56 | cli r0; | 66 | cli r0; |
57 | coreslot_loadaddr p0; | 67 | coreslot_loadaddr p0; |
58 | .Lretry_corelock_noflush: | 68 | .Lretry_corelock_noflush: |
59 | testset (p0); | 69 | safe_testset p0, r2; |
60 | if cc jump .Ldone_corelock_noflush; | 70 | if cc jump .Ldone_corelock_noflush; |
61 | SSYNC(r2); | 71 | SSYNC(r2); |
62 | jump .Lretry_corelock_noflush | 72 | jump .Lretry_corelock_noflush |
diff --git a/arch/blackfin/mach-bf561/include/mach/anomaly.h b/arch/blackfin/mach-bf561/include/mach/anomaly.h index 70da495c9665..5ddc981e9937 100644 --- a/arch/blackfin/mach-bf561/include/mach/anomaly.h +++ b/arch/blackfin/mach-bf561/include/mach/anomaly.h | |||
@@ -1,9 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | * File: include/asm-blackfin/mach-bf561/anomaly.h | 2 | * DO NOT EDIT THIS FILE |
3 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | 3 | * This file is under version control at |
4 | * svn://sources.blackfin.uclinux.org/toolchain/trunk/proc-defs/header-frags/ | ||
5 | * and can be replaced with that version at any time | ||
6 | * DO NOT EDIT THIS FILE | ||
4 | * | 7 | * |
5 | * Copyright (C) 2004-2009 Analog Devices Inc. | 8 | * Copyright 2004-2009 Analog Devices Inc. |
6 | * Licensed under the GPL-2 or later. | 9 | * Licensed under the ADI BSD license. |
10 | * https://docs.blackfin.uclinux.org/doku.php?id=adi_bsd | ||
7 | */ | 11 | */ |
8 | 12 | ||
9 | /* This file should be up to date with: | 13 | /* This file should be up to date with: |
@@ -213,7 +217,11 @@ | |||
213 | /* Disabling Peripherals with DMA Running May Cause DMA System Instability */ | 217 | /* Disabling Peripherals with DMA Running May Cause DMA System Instability */ |
214 | #define ANOMALY_05000278 (__SILICON_REVISION__ < 5) | 218 | #define ANOMALY_05000278 (__SILICON_REVISION__ < 5) |
215 | /* False Hardware Error Exception when ISR Context Is Not Restored */ | 219 | /* False Hardware Error Exception when ISR Context Is Not Restored */ |
216 | #define ANOMALY_05000281 (__SILICON_REVISION__ < 5) | 220 | /* Temporarily walk around for bug 5423 till this issue is confirmed by |
221 | * official anomaly document. It looks 05000281 still exists on bf561 | ||
222 | * v0.5. | ||
223 | */ | ||
224 | #define ANOMALY_05000281 (__SILICON_REVISION__ <= 5) | ||
217 | /* System MMR Write Is Stalled Indefinitely when Killed in a Particular Stage */ | 225 | /* System MMR Write Is Stalled Indefinitely when Killed in a Particular Stage */ |
218 | #define ANOMALY_05000283 (1) | 226 | #define ANOMALY_05000283 (1) |
219 | /* Reads Will Receive Incorrect Data under Certain Conditions */ | 227 | /* Reads Will Receive Incorrect Data under Certain Conditions */ |
@@ -280,6 +288,12 @@ | |||
280 | #define ANOMALY_05000443 (1) | 288 | #define ANOMALY_05000443 (1) |
281 | /* False Hardware Error when RETI Points to Invalid Memory */ | 289 | /* False Hardware Error when RETI Points to Invalid Memory */ |
282 | #define ANOMALY_05000461 (1) | 290 | #define ANOMALY_05000461 (1) |
291 | /* Interrupted 32-Bit SPORT Data Register Access Results In Underflow */ | ||
292 | #define ANOMALY_05000473 (1) | ||
293 | /* Core Hang With L2/L3 Configured in Writeback Cache Mode */ | ||
294 | #define ANOMALY_05000475 (__SILICON_REVISION__ < 4) | ||
295 | /* TESTSET Instruction Cannot Be Interrupted */ | ||
296 | #define ANOMALY_05000477 (1) | ||
283 | 297 | ||
284 | /* Anomalies that don't exist on this proc */ | 298 | /* Anomalies that don't exist on this proc */ |
285 | #define ANOMALY_05000119 (0) | 299 | #define ANOMALY_05000119 (0) |
@@ -304,5 +318,6 @@ | |||
304 | #define ANOMALY_05000450 (0) | 318 | #define ANOMALY_05000450 (0) |
305 | #define ANOMALY_05000465 (0) | 319 | #define ANOMALY_05000465 (0) |
306 | #define ANOMALY_05000467 (0) | 320 | #define ANOMALY_05000467 (0) |
321 | #define ANOMALY_05000474 (0) | ||
307 | 322 | ||
308 | #endif | 323 | #endif |
diff --git a/arch/blackfin/mach-common/arch_checks.c b/arch/blackfin/mach-common/arch_checks.c index 9dbafcdcf479..f2ca211a76a0 100644 --- a/arch/blackfin/mach-common/arch_checks.c +++ b/arch/blackfin/mach-common/arch_checks.c | |||
@@ -57,3 +57,8 @@ | |||
57 | (!defined(CONFIG_BFIN_EXTMEM_DCACHEABLE) && defined(CONFIG_BFIN_L2_WRITEBACK))) | 57 | (!defined(CONFIG_BFIN_EXTMEM_DCACHEABLE) && defined(CONFIG_BFIN_L2_WRITEBACK))) |
58 | # error You are exposing Anomaly 220 in this config, either config L2 as Write Through, or make External Memory WB. | 58 | # error You are exposing Anomaly 220 in this config, either config L2 as Write Through, or make External Memory WB. |
59 | #endif | 59 | #endif |
60 | |||
61 | #if ANOMALY_05000475 && \ | ||
62 | (defined(CONFIG_BFIN_EXTMEM_WRITEBACK) || defined(CONFIG_BFIN_L2_WRITEBACK)) | ||
63 | # error "Anomaly 475 does not allow you to use Write Back cache with L2 or External Memory" | ||
64 | #endif | ||
diff --git a/arch/blackfin/mach-common/smp.c b/arch/blackfin/mach-common/smp.c index d98585f3237d..d92b168c8328 100644 --- a/arch/blackfin/mach-common/smp.c +++ b/arch/blackfin/mach-common/smp.c | |||
@@ -276,10 +276,9 @@ void smp_send_reschedule(int cpu) | |||
276 | if (cpu_is_offline(cpu)) | 276 | if (cpu_is_offline(cpu)) |
277 | return; | 277 | return; |
278 | 278 | ||
279 | msg = kmalloc(sizeof(*msg), GFP_ATOMIC); | 279 | msg = kzalloc(sizeof(*msg), GFP_ATOMIC); |
280 | if (!msg) | 280 | if (!msg) |
281 | return; | 281 | return; |
282 | memset(msg, 0, sizeof(msg)); | ||
283 | INIT_LIST_HEAD(&msg->list); | 282 | INIT_LIST_HEAD(&msg->list); |
284 | msg->type = BFIN_IPI_RESCHEDULE; | 283 | msg->type = BFIN_IPI_RESCHEDULE; |
285 | 284 | ||
@@ -305,10 +304,9 @@ void smp_send_stop(void) | |||
305 | if (cpus_empty(callmap)) | 304 | if (cpus_empty(callmap)) |
306 | return; | 305 | return; |
307 | 306 | ||
308 | msg = kmalloc(sizeof(*msg), GFP_ATOMIC); | 307 | msg = kzalloc(sizeof(*msg), GFP_ATOMIC); |
309 | if (!msg) | 308 | if (!msg) |
310 | return; | 309 | return; |
311 | memset(msg, 0, sizeof(msg)); | ||
312 | INIT_LIST_HEAD(&msg->list); | 310 | INIT_LIST_HEAD(&msg->list); |
313 | msg->type = BFIN_IPI_CPU_STOP; | 311 | msg->type = BFIN_IPI_CPU_STOP; |
314 | 312 | ||
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c index 69dad5a850a8..a36799e85693 100644 --- a/arch/parisc/kernel/unwind.c +++ b/arch/parisc/kernel/unwind.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #define dbg(x...) | 28 | #define dbg(x...) |
29 | #endif | 29 | #endif |
30 | 30 | ||
31 | #define KERNEL_START (KERNEL_BINARY_TEXT_START - 0x1000) | 31 | #define KERNEL_START (KERNEL_BINARY_TEXT_START) |
32 | 32 | ||
33 | extern struct unwind_table_entry __start___unwind[]; | 33 | extern struct unwind_table_entry __start___unwind[]; |
34 | extern struct unwind_table_entry __stop___unwind[]; | 34 | extern struct unwind_table_entry __stop___unwind[]; |
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index fda4baa059b5..9dab4a4e09f7 100644 --- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S | |||
@@ -78,9 +78,6 @@ SECTIONS | |||
78 | */ | 78 | */ |
79 | . = ALIGN(PAGE_SIZE); | 79 | . = ALIGN(PAGE_SIZE); |
80 | data_start = .; | 80 | data_start = .; |
81 | EXCEPTION_TABLE(16) | ||
82 | |||
83 | NOTES | ||
84 | 81 | ||
85 | /* unwind info */ | 82 | /* unwind info */ |
86 | .PARISC.unwind : { | 83 | .PARISC.unwind : { |
@@ -89,6 +86,9 @@ SECTIONS | |||
89 | __stop___unwind = .; | 86 | __stop___unwind = .; |
90 | } | 87 | } |
91 | 88 | ||
89 | EXCEPTION_TABLE(16) | ||
90 | NOTES | ||
91 | |||
92 | /* Data */ | 92 | /* Data */ |
93 | RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE) | 93 | RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE) |
94 | 94 | ||
diff --git a/arch/powerpc/include/asm/kmap_types.h b/arch/powerpc/include/asm/kmap_types.h index b6bac6f61c16..916369575c97 100644 --- a/arch/powerpc/include/asm/kmap_types.h +++ b/arch/powerpc/include/asm/kmap_types.h | |||
@@ -29,5 +29,16 @@ enum km_type { | |||
29 | KM_TYPE_NR | 29 | KM_TYPE_NR |
30 | }; | 30 | }; |
31 | 31 | ||
32 | /* | ||
33 | * This is a temporary build fix that (so they say on lkml....) should no longer | ||
34 | * be required after 2.6.33, because of changes planned to the kmap code. | ||
35 | * Let's try to remove this cruft then. | ||
36 | */ | ||
37 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
38 | #define KM_NMI (-1) | ||
39 | #define KM_NMI_PTE (-1) | ||
40 | #define KM_IRQ_PTE (-1) | ||
41 | #endif | ||
42 | |||
32 | #endif /* __KERNEL__ */ | 43 | #endif /* __KERNEL__ */ |
33 | #endif /* _ASM_POWERPC_KMAP_TYPES_H */ | 44 | #endif /* _ASM_POWERPC_KMAP_TYPES_H */ |
diff --git a/arch/sparc/mm/init_64.h b/arch/sparc/mm/init_64.h index c2f772dbd556..77d1b313e344 100644 --- a/arch/sparc/mm/init_64.h +++ b/arch/sparc/mm/init_64.h | |||
@@ -45,7 +45,7 @@ extern void free_initmem(void); | |||
45 | #define VMEMMAP_ALIGN(x) (((x)+VMEMMAP_CHUNK-1UL)&VMEMMAP_CHUNK_MASK) | 45 | #define VMEMMAP_ALIGN(x) (((x)+VMEMMAP_CHUNK-1UL)&VMEMMAP_CHUNK_MASK) |
46 | 46 | ||
47 | #define VMEMMAP_SIZE ((((1UL << MAX_PHYSADDR_BITS) >> PAGE_SHIFT) * \ | 47 | #define VMEMMAP_SIZE ((((1UL << MAX_PHYSADDR_BITS) >> PAGE_SHIFT) * \ |
48 | sizeof(struct page *)) >> VMEMMAP_CHUNK_SHIFT) | 48 | sizeof(struct page)) >> VMEMMAP_CHUNK_SHIFT) |
49 | extern unsigned long vmemmap_table[VMEMMAP_SIZE]; | 49 | extern unsigned long vmemmap_table[VMEMMAP_SIZE]; |
50 | #endif | 50 | #endif |
51 | 51 | ||
diff --git a/arch/x86/kernel/acpi/processor.c b/arch/x86/kernel/acpi/processor.c index d296f4a195c9..d85d1b2432ba 100644 --- a/arch/x86/kernel/acpi/processor.c +++ b/arch/x86/kernel/acpi/processor.c | |||
@@ -79,7 +79,8 @@ void arch_acpi_processor_init_pdc(struct acpi_processor *pr) | |||
79 | struct cpuinfo_x86 *c = &cpu_data(pr->id); | 79 | struct cpuinfo_x86 *c = &cpu_data(pr->id); |
80 | 80 | ||
81 | pr->pdc = NULL; | 81 | pr->pdc = NULL; |
82 | if (c->x86_vendor == X86_VENDOR_INTEL) | 82 | if (c->x86_vendor == X86_VENDOR_INTEL || |
83 | c->x86_vendor == X86_VENDOR_CENTAUR) | ||
83 | init_intel_pdc(pr, c); | 84 | init_intel_pdc(pr, c); |
84 | 85 | ||
85 | return; | 86 | return; |
diff --git a/crypto/async_tx/Kconfig b/crypto/async_tx/Kconfig index e5aeb2b79e6f..e28e276ac611 100644 --- a/crypto/async_tx/Kconfig +++ b/crypto/async_tx/Kconfig | |||
@@ -23,3 +23,8 @@ config ASYNC_RAID6_RECOV | |||
23 | select ASYNC_CORE | 23 | select ASYNC_CORE |
24 | select ASYNC_PQ | 24 | select ASYNC_PQ |
25 | 25 | ||
26 | config ASYNC_TX_DISABLE_PQ_VAL_DMA | ||
27 | bool | ||
28 | |||
29 | config ASYNC_TX_DISABLE_XOR_VAL_DMA | ||
30 | bool | ||
diff --git a/crypto/async_tx/async_pq.c b/crypto/async_tx/async_pq.c index 6b5cc4fba59f..ec87f53d5059 100644 --- a/crypto/async_tx/async_pq.c +++ b/crypto/async_tx/async_pq.c | |||
@@ -240,6 +240,16 @@ async_gen_syndrome(struct page **blocks, unsigned int offset, int disks, | |||
240 | } | 240 | } |
241 | EXPORT_SYMBOL_GPL(async_gen_syndrome); | 241 | EXPORT_SYMBOL_GPL(async_gen_syndrome); |
242 | 242 | ||
243 | static inline struct dma_chan * | ||
244 | pq_val_chan(struct async_submit_ctl *submit, struct page **blocks, int disks, size_t len) | ||
245 | { | ||
246 | #ifdef CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA | ||
247 | return NULL; | ||
248 | #endif | ||
249 | return async_tx_find_channel(submit, DMA_PQ_VAL, NULL, 0, blocks, | ||
250 | disks, len); | ||
251 | } | ||
252 | |||
243 | /** | 253 | /** |
244 | * async_syndrome_val - asynchronously validate a raid6 syndrome | 254 | * async_syndrome_val - asynchronously validate a raid6 syndrome |
245 | * @blocks: source blocks from idx 0..disks-3, P @ disks-2 and Q @ disks-1 | 255 | * @blocks: source blocks from idx 0..disks-3, P @ disks-2 and Q @ disks-1 |
@@ -260,9 +270,7 @@ async_syndrome_val(struct page **blocks, unsigned int offset, int disks, | |||
260 | size_t len, enum sum_check_flags *pqres, struct page *spare, | 270 | size_t len, enum sum_check_flags *pqres, struct page *spare, |
261 | struct async_submit_ctl *submit) | 271 | struct async_submit_ctl *submit) |
262 | { | 272 | { |
263 | struct dma_chan *chan = async_tx_find_channel(submit, DMA_PQ_VAL, | 273 | struct dma_chan *chan = pq_val_chan(submit, blocks, disks, len); |
264 | NULL, 0, blocks, disks, | ||
265 | len); | ||
266 | struct dma_device *device = chan ? chan->device : NULL; | 274 | struct dma_device *device = chan ? chan->device : NULL; |
267 | struct dma_async_tx_descriptor *tx; | 275 | struct dma_async_tx_descriptor *tx; |
268 | unsigned char coefs[disks-2]; | 276 | unsigned char coefs[disks-2]; |
diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c index 79182dcb91b7..079ae8ca590b 100644 --- a/crypto/async_tx/async_xor.c +++ b/crypto/async_tx/async_xor.c | |||
@@ -234,6 +234,17 @@ static int page_is_zero(struct page *p, unsigned int offset, size_t len) | |||
234 | memcmp(a, a + 4, len - 4) == 0); | 234 | memcmp(a, a + 4, len - 4) == 0); |
235 | } | 235 | } |
236 | 236 | ||
237 | static inline struct dma_chan * | ||
238 | xor_val_chan(struct async_submit_ctl *submit, struct page *dest, | ||
239 | struct page **src_list, int src_cnt, size_t len) | ||
240 | { | ||
241 | #ifdef CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA | ||
242 | return NULL; | ||
243 | #endif | ||
244 | return async_tx_find_channel(submit, DMA_XOR_VAL, &dest, 1, src_list, | ||
245 | src_cnt, len); | ||
246 | } | ||
247 | |||
237 | /** | 248 | /** |
238 | * async_xor_val - attempt a xor parity check with a dma engine. | 249 | * async_xor_val - attempt a xor parity check with a dma engine. |
239 | * @dest: destination page used if the xor is performed synchronously | 250 | * @dest: destination page used if the xor is performed synchronously |
@@ -255,9 +266,7 @@ async_xor_val(struct page *dest, struct page **src_list, unsigned int offset, | |||
255 | int src_cnt, size_t len, enum sum_check_flags *result, | 266 | int src_cnt, size_t len, enum sum_check_flags *result, |
256 | struct async_submit_ctl *submit) | 267 | struct async_submit_ctl *submit) |
257 | { | 268 | { |
258 | struct dma_chan *chan = async_tx_find_channel(submit, DMA_XOR_VAL, | 269 | struct dma_chan *chan = xor_val_chan(submit, dest, src_list, src_cnt, len); |
259 | &dest, 1, src_list, | ||
260 | src_cnt, len); | ||
261 | struct dma_device *device = chan ? chan->device : NULL; | 270 | struct dma_device *device = chan ? chan->device : NULL; |
262 | struct dma_async_tx_descriptor *tx = NULL; | 271 | struct dma_async_tx_descriptor *tx = NULL; |
263 | dma_addr_t *dma_src = NULL; | 272 | dma_addr_t *dma_src = NULL; |
diff --git a/crypto/gcm.c b/crypto/gcm.c index 5fc3292483ef..c6547130624c 100644 --- a/crypto/gcm.c +++ b/crypto/gcm.c | |||
@@ -40,7 +40,7 @@ struct crypto_rfc4106_ctx { | |||
40 | struct crypto_gcm_ghash_ctx { | 40 | struct crypto_gcm_ghash_ctx { |
41 | unsigned int cryptlen; | 41 | unsigned int cryptlen; |
42 | struct scatterlist *src; | 42 | struct scatterlist *src; |
43 | crypto_completion_t complete; | 43 | void (*complete)(struct aead_request *req, int err); |
44 | }; | 44 | }; |
45 | 45 | ||
46 | struct crypto_gcm_req_priv_ctx { | 46 | struct crypto_gcm_req_priv_ctx { |
@@ -267,23 +267,26 @@ static int gcm_hash_final(struct aead_request *req, | |||
267 | return crypto_ahash_final(ahreq); | 267 | return crypto_ahash_final(ahreq); |
268 | } | 268 | } |
269 | 269 | ||
270 | static void gcm_hash_final_done(struct crypto_async_request *areq, | 270 | static void __gcm_hash_final_done(struct aead_request *req, int err) |
271 | int err) | ||
272 | { | 271 | { |
273 | struct aead_request *req = areq->data; | ||
274 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); | 272 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
275 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; | 273 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; |
276 | 274 | ||
277 | if (!err) | 275 | if (!err) |
278 | crypto_xor(pctx->auth_tag, pctx->iauth_tag, 16); | 276 | crypto_xor(pctx->auth_tag, pctx->iauth_tag, 16); |
279 | 277 | ||
280 | gctx->complete(areq, err); | 278 | gctx->complete(req, err); |
281 | } | 279 | } |
282 | 280 | ||
283 | static void gcm_hash_len_done(struct crypto_async_request *areq, | 281 | static void gcm_hash_final_done(struct crypto_async_request *areq, int err) |
284 | int err) | ||
285 | { | 282 | { |
286 | struct aead_request *req = areq->data; | 283 | struct aead_request *req = areq->data; |
284 | |||
285 | __gcm_hash_final_done(req, err); | ||
286 | } | ||
287 | |||
288 | static void __gcm_hash_len_done(struct aead_request *req, int err) | ||
289 | { | ||
287 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); | 290 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
288 | 291 | ||
289 | if (!err) { | 292 | if (!err) { |
@@ -292,13 +295,18 @@ static void gcm_hash_len_done(struct crypto_async_request *areq, | |||
292 | return; | 295 | return; |
293 | } | 296 | } |
294 | 297 | ||
295 | gcm_hash_final_done(areq, err); | 298 | __gcm_hash_final_done(req, err); |
296 | } | 299 | } |
297 | 300 | ||
298 | static void gcm_hash_crypt_remain_done(struct crypto_async_request *areq, | 301 | static void gcm_hash_len_done(struct crypto_async_request *areq, int err) |
299 | int err) | ||
300 | { | 302 | { |
301 | struct aead_request *req = areq->data; | 303 | struct aead_request *req = areq->data; |
304 | |||
305 | __gcm_hash_len_done(req, err); | ||
306 | } | ||
307 | |||
308 | static void __gcm_hash_crypt_remain_done(struct aead_request *req, int err) | ||
309 | { | ||
302 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); | 310 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
303 | 311 | ||
304 | if (!err) { | 312 | if (!err) { |
@@ -307,13 +315,19 @@ static void gcm_hash_crypt_remain_done(struct crypto_async_request *areq, | |||
307 | return; | 315 | return; |
308 | } | 316 | } |
309 | 317 | ||
310 | gcm_hash_len_done(areq, err); | 318 | __gcm_hash_len_done(req, err); |
311 | } | 319 | } |
312 | 320 | ||
313 | static void gcm_hash_crypt_done(struct crypto_async_request *areq, | 321 | static void gcm_hash_crypt_remain_done(struct crypto_async_request *areq, |
314 | int err) | 322 | int err) |
315 | { | 323 | { |
316 | struct aead_request *req = areq->data; | 324 | struct aead_request *req = areq->data; |
325 | |||
326 | __gcm_hash_crypt_remain_done(req, err); | ||
327 | } | ||
328 | |||
329 | static void __gcm_hash_crypt_done(struct aead_request *req, int err) | ||
330 | { | ||
317 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); | 331 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
318 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; | 332 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; |
319 | unsigned int remain; | 333 | unsigned int remain; |
@@ -327,13 +341,18 @@ static void gcm_hash_crypt_done(struct crypto_async_request *areq, | |||
327 | return; | 341 | return; |
328 | } | 342 | } |
329 | 343 | ||
330 | gcm_hash_crypt_remain_done(areq, err); | 344 | __gcm_hash_crypt_remain_done(req, err); |
331 | } | 345 | } |
332 | 346 | ||
333 | static void gcm_hash_assoc_remain_done(struct crypto_async_request *areq, | 347 | static void gcm_hash_crypt_done(struct crypto_async_request *areq, int err) |
334 | int err) | ||
335 | { | 348 | { |
336 | struct aead_request *req = areq->data; | 349 | struct aead_request *req = areq->data; |
350 | |||
351 | __gcm_hash_crypt_done(req, err); | ||
352 | } | ||
353 | |||
354 | static void __gcm_hash_assoc_remain_done(struct aead_request *req, int err) | ||
355 | { | ||
337 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); | 356 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
338 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; | 357 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; |
339 | crypto_completion_t complete; | 358 | crypto_completion_t complete; |
@@ -350,15 +369,21 @@ static void gcm_hash_assoc_remain_done(struct crypto_async_request *areq, | |||
350 | } | 369 | } |
351 | 370 | ||
352 | if (remain) | 371 | if (remain) |
353 | gcm_hash_crypt_done(areq, err); | 372 | __gcm_hash_crypt_done(req, err); |
354 | else | 373 | else |
355 | gcm_hash_crypt_remain_done(areq, err); | 374 | __gcm_hash_crypt_remain_done(req, err); |
356 | } | 375 | } |
357 | 376 | ||
358 | static void gcm_hash_assoc_done(struct crypto_async_request *areq, | 377 | static void gcm_hash_assoc_remain_done(struct crypto_async_request *areq, |
359 | int err) | 378 | int err) |
360 | { | 379 | { |
361 | struct aead_request *req = areq->data; | 380 | struct aead_request *req = areq->data; |
381 | |||
382 | __gcm_hash_assoc_remain_done(req, err); | ||
383 | } | ||
384 | |||
385 | static void __gcm_hash_assoc_done(struct aead_request *req, int err) | ||
386 | { | ||
362 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); | 387 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
363 | unsigned int remain; | 388 | unsigned int remain; |
364 | 389 | ||
@@ -371,13 +396,18 @@ static void gcm_hash_assoc_done(struct crypto_async_request *areq, | |||
371 | return; | 396 | return; |
372 | } | 397 | } |
373 | 398 | ||
374 | gcm_hash_assoc_remain_done(areq, err); | 399 | __gcm_hash_assoc_remain_done(req, err); |
375 | } | 400 | } |
376 | 401 | ||
377 | static void gcm_hash_init_done(struct crypto_async_request *areq, | 402 | static void gcm_hash_assoc_done(struct crypto_async_request *areq, int err) |
378 | int err) | ||
379 | { | 403 | { |
380 | struct aead_request *req = areq->data; | 404 | struct aead_request *req = areq->data; |
405 | |||
406 | __gcm_hash_assoc_done(req, err); | ||
407 | } | ||
408 | |||
409 | static void __gcm_hash_init_done(struct aead_request *req, int err) | ||
410 | { | ||
381 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); | 411 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
382 | crypto_completion_t complete; | 412 | crypto_completion_t complete; |
383 | unsigned int remain = 0; | 413 | unsigned int remain = 0; |
@@ -393,9 +423,16 @@ static void gcm_hash_init_done(struct crypto_async_request *areq, | |||
393 | } | 423 | } |
394 | 424 | ||
395 | if (remain) | 425 | if (remain) |
396 | gcm_hash_assoc_done(areq, err); | 426 | __gcm_hash_assoc_done(req, err); |
397 | else | 427 | else |
398 | gcm_hash_assoc_remain_done(areq, err); | 428 | __gcm_hash_assoc_remain_done(req, err); |
429 | } | ||
430 | |||
431 | static void gcm_hash_init_done(struct crypto_async_request *areq, int err) | ||
432 | { | ||
433 | struct aead_request *req = areq->data; | ||
434 | |||
435 | __gcm_hash_init_done(req, err); | ||
399 | } | 436 | } |
400 | 437 | ||
401 | static int gcm_hash(struct aead_request *req, | 438 | static int gcm_hash(struct aead_request *req, |
@@ -457,10 +494,8 @@ static void gcm_enc_copy_hash(struct aead_request *req, | |||
457 | crypto_aead_authsize(aead), 1); | 494 | crypto_aead_authsize(aead), 1); |
458 | } | 495 | } |
459 | 496 | ||
460 | static void gcm_enc_hash_done(struct crypto_async_request *areq, | 497 | static void gcm_enc_hash_done(struct aead_request *req, int err) |
461 | int err) | ||
462 | { | 498 | { |
463 | struct aead_request *req = areq->data; | ||
464 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); | 499 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
465 | 500 | ||
466 | if (!err) | 501 | if (!err) |
@@ -469,8 +504,7 @@ static void gcm_enc_hash_done(struct crypto_async_request *areq, | |||
469 | aead_request_complete(req, err); | 504 | aead_request_complete(req, err); |
470 | } | 505 | } |
471 | 506 | ||
472 | static void gcm_encrypt_done(struct crypto_async_request *areq, | 507 | static void gcm_encrypt_done(struct crypto_async_request *areq, int err) |
473 | int err) | ||
474 | { | 508 | { |
475 | struct aead_request *req = areq->data; | 509 | struct aead_request *req = areq->data; |
476 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); | 510 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
@@ -479,9 +513,13 @@ static void gcm_encrypt_done(struct crypto_async_request *areq, | |||
479 | err = gcm_hash(req, pctx); | 513 | err = gcm_hash(req, pctx); |
480 | if (err == -EINPROGRESS || err == -EBUSY) | 514 | if (err == -EINPROGRESS || err == -EBUSY) |
481 | return; | 515 | return; |
516 | else if (!err) { | ||
517 | crypto_xor(pctx->auth_tag, pctx->iauth_tag, 16); | ||
518 | gcm_enc_copy_hash(req, pctx); | ||
519 | } | ||
482 | } | 520 | } |
483 | 521 | ||
484 | gcm_enc_hash_done(areq, err); | 522 | aead_request_complete(req, err); |
485 | } | 523 | } |
486 | 524 | ||
487 | static int crypto_gcm_encrypt(struct aead_request *req) | 525 | static int crypto_gcm_encrypt(struct aead_request *req) |
@@ -538,9 +576,8 @@ static void gcm_decrypt_done(struct crypto_async_request *areq, int err) | |||
538 | aead_request_complete(req, err); | 576 | aead_request_complete(req, err); |
539 | } | 577 | } |
540 | 578 | ||
541 | static void gcm_dec_hash_done(struct crypto_async_request *areq, int err) | 579 | static void gcm_dec_hash_done(struct aead_request *req, int err) |
542 | { | 580 | { |
543 | struct aead_request *req = areq->data; | ||
544 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); | 581 | struct crypto_gcm_req_priv_ctx *pctx = crypto_gcm_reqctx(req); |
545 | struct ablkcipher_request *abreq = &pctx->u.abreq; | 582 | struct ablkcipher_request *abreq = &pctx->u.abreq; |
546 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; | 583 | struct crypto_gcm_ghash_ctx *gctx = &pctx->ghash_ctx; |
@@ -552,9 +589,11 @@ static void gcm_dec_hash_done(struct crypto_async_request *areq, int err) | |||
552 | err = crypto_ablkcipher_decrypt(abreq); | 589 | err = crypto_ablkcipher_decrypt(abreq); |
553 | if (err == -EINPROGRESS || err == -EBUSY) | 590 | if (err == -EINPROGRESS || err == -EBUSY) |
554 | return; | 591 | return; |
592 | else if (!err) | ||
593 | err = crypto_gcm_verify(req, pctx); | ||
555 | } | 594 | } |
556 | 595 | ||
557 | gcm_decrypt_done(areq, err); | 596 | aead_request_complete(req, err); |
558 | } | 597 | } |
559 | 598 | ||
560 | static int crypto_gcm_decrypt(struct aead_request *req) | 599 | static int crypto_gcm_decrypt(struct aead_request *req) |
diff --git a/drivers/acpi/acpica/acpredef.h b/drivers/acpi/acpica/acpredef.h index cd80d1dd1950..57bdaf6ffab1 100644 --- a/drivers/acpi/acpica/acpredef.h +++ b/drivers/acpi/acpica/acpredef.h | |||
@@ -203,8 +203,9 @@ static const union acpi_predefined_info predefined_names[] = | |||
203 | {{"_BCT", 1, ACPI_RTYPE_INTEGER}}, | 203 | {{"_BCT", 1, ACPI_RTYPE_INTEGER}}, |
204 | {{"_BDN", 0, ACPI_RTYPE_INTEGER}}, | 204 | {{"_BDN", 0, ACPI_RTYPE_INTEGER}}, |
205 | {{"_BFS", 1, 0}}, | 205 | {{"_BFS", 1, 0}}, |
206 | {{"_BIF", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (9 Int),(4 Str) */ | 206 | {{"_BIF", 0, ACPI_RTYPE_PACKAGE} }, /* Fixed-length (9 Int),(4 Str/Buf) */ |
207 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 9, ACPI_RTYPE_STRING}, 4,0}}, | 207 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 9, |
208 | ACPI_RTYPE_STRING | ACPI_RTYPE_BUFFER}, 4, 0} }, | ||
208 | 209 | ||
209 | {{"_BIX", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (16 Int),(4 Str) */ | 210 | {{"_BIX", 0, ACPI_RTYPE_PACKAGE}}, /* Fixed-length (16 Int),(4 Str) */ |
210 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16, ACPI_RTYPE_STRING}, 4, | 211 | {{{ACPI_PTYPE1_FIXED, ACPI_RTYPE_INTEGER, 16, ACPI_RTYPE_STRING}, 4, |
diff --git a/drivers/acpi/blacklist.c b/drivers/acpi/blacklist.c index e56b2a7b53db..23e5a0519af5 100644 --- a/drivers/acpi/blacklist.c +++ b/drivers/acpi/blacklist.c | |||
@@ -224,6 +224,7 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
224 | * _OSI(Linux) helps sound | 224 | * _OSI(Linux) helps sound |
225 | * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad R61"), | 225 | * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad R61"), |
226 | * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T61"), | 226 | * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T61"), |
227 | * T400, T500 | ||
227 | * _OSI(Linux) has Linux specific hooks | 228 | * _OSI(Linux) has Linux specific hooks |
228 | * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"), | 229 | * DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"), |
229 | * _OSI(Linux) is a NOP: | 230 | * _OSI(Linux) is a NOP: |
@@ -254,6 +255,22 @@ static struct dmi_system_id acpi_osi_dmi_table[] __initdata = { | |||
254 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"), | 255 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad X61"), |
255 | }, | 256 | }, |
256 | }, | 257 | }, |
258 | { | ||
259 | .callback = dmi_enable_osi_linux, | ||
260 | .ident = "Lenovo ThinkPad T400", | ||
261 | .matches = { | ||
262 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
263 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T400"), | ||
264 | }, | ||
265 | }, | ||
266 | { | ||
267 | .callback = dmi_enable_osi_linux, | ||
268 | .ident = "Lenovo ThinkPad T500", | ||
269 | .matches = { | ||
270 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
271 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad T500"), | ||
272 | }, | ||
273 | }, | ||
257 | {} | 274 | {} |
258 | }; | 275 | }; |
259 | 276 | ||
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 4cc1b8116e76..5f2c379ab7bf 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -430,6 +430,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
430 | }, | 430 | }, |
431 | { | 431 | { |
432 | .callback = init_set_sci_en_on_resume, | 432 | .callback = init_set_sci_en_on_resume, |
433 | .ident = "Hewlett-Packard Compaq Presario C700 Notebook PC", | ||
434 | .matches = { | ||
435 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | ||
436 | DMI_MATCH(DMI_PRODUCT_NAME, "Compaq Presario C700 Notebook PC"), | ||
437 | }, | ||
438 | }, | ||
439 | { | ||
440 | .callback = init_set_sci_en_on_resume, | ||
433 | .ident = "Hewlett-Packard Compaq Presario CQ40 Notebook PC", | 441 | .ident = "Hewlett-Packard Compaq Presario CQ40 Notebook PC", |
434 | .matches = { | 442 | .matches = { |
435 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), | 443 | DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), |
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c index d344db42a002..172b57e6543f 100644 --- a/drivers/ata/sata_fsl.c +++ b/drivers/ata/sata_fsl.c | |||
@@ -707,34 +707,17 @@ static unsigned int sata_fsl_dev_classify(struct ata_port *ap) | |||
707 | return ata_dev_classify(&tf); | 707 | return ata_dev_classify(&tf); |
708 | } | 708 | } |
709 | 709 | ||
710 | static int sata_fsl_prereset(struct ata_link *link, unsigned long deadline) | 710 | static int sata_fsl_hardreset(struct ata_link *link, unsigned int *class, |
711 | { | ||
712 | /* FIXME: Never skip softreset, sata_fsl_softreset() is | ||
713 | * combination of soft and hard resets. sata_fsl_softreset() | ||
714 | * needs to be splitted into soft and hard resets. | ||
715 | */ | ||
716 | return 0; | ||
717 | } | ||
718 | |||
719 | static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, | ||
720 | unsigned long deadline) | 711 | unsigned long deadline) |
721 | { | 712 | { |
722 | struct ata_port *ap = link->ap; | 713 | struct ata_port *ap = link->ap; |
723 | struct sata_fsl_port_priv *pp = ap->private_data; | ||
724 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; | 714 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; |
725 | void __iomem *hcr_base = host_priv->hcr_base; | 715 | void __iomem *hcr_base = host_priv->hcr_base; |
726 | int pmp = sata_srst_pmp(link); | ||
727 | u32 temp; | 716 | u32 temp; |
728 | struct ata_taskfile tf; | ||
729 | u8 *cfis; | ||
730 | u32 Serror; | ||
731 | int i = 0; | 717 | int i = 0; |
732 | unsigned long start_jiffies; | 718 | unsigned long start_jiffies; |
733 | 719 | ||
734 | DPRINTK("in xx_softreset\n"); | 720 | DPRINTK("in xx_hardreset\n"); |
735 | |||
736 | if (pmp != SATA_PMP_CTRL_PORT) | ||
737 | goto issue_srst; | ||
738 | 721 | ||
739 | try_offline_again: | 722 | try_offline_again: |
740 | /* | 723 | /* |
@@ -749,7 +732,7 @@ try_offline_again: | |||
749 | 732 | ||
750 | if (temp & ONLINE) { | 733 | if (temp & ONLINE) { |
751 | ata_port_printk(ap, KERN_ERR, | 734 | ata_port_printk(ap, KERN_ERR, |
752 | "Softreset failed, not off-lined %d\n", i); | 735 | "Hardreset failed, not off-lined %d\n", i); |
753 | 736 | ||
754 | /* | 737 | /* |
755 | * Try to offline controller atleast twice | 738 | * Try to offline controller atleast twice |
@@ -761,7 +744,7 @@ try_offline_again: | |||
761 | goto try_offline_again; | 744 | goto try_offline_again; |
762 | } | 745 | } |
763 | 746 | ||
764 | DPRINTK("softreset, controller off-lined\n"); | 747 | DPRINTK("hardreset, controller off-lined\n"); |
765 | VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); | 748 | VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); |
766 | VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); | 749 | VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); |
767 | 750 | ||
@@ -786,11 +769,11 @@ try_offline_again: | |||
786 | 769 | ||
787 | if (!(temp & ONLINE)) { | 770 | if (!(temp & ONLINE)) { |
788 | ata_port_printk(ap, KERN_ERR, | 771 | ata_port_printk(ap, KERN_ERR, |
789 | "Softreset failed, not on-lined\n"); | 772 | "Hardreset failed, not on-lined\n"); |
790 | goto err; | 773 | goto err; |
791 | } | 774 | } |
792 | 775 | ||
793 | DPRINTK("softreset, controller off-lined & on-lined\n"); | 776 | DPRINTK("hardreset, controller off-lined & on-lined\n"); |
794 | VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); | 777 | VPRINTK("HStatus = 0x%x\n", ioread32(hcr_base + HSTATUS)); |
795 | VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); | 778 | VPRINTK("HControl = 0x%x\n", ioread32(hcr_base + HCONTROL)); |
796 | 779 | ||
@@ -806,7 +789,7 @@ try_offline_again: | |||
806 | "No Device OR PHYRDY change,Hstatus = 0x%x\n", | 789 | "No Device OR PHYRDY change,Hstatus = 0x%x\n", |
807 | ioread32(hcr_base + HSTATUS)); | 790 | ioread32(hcr_base + HSTATUS)); |
808 | *class = ATA_DEV_NONE; | 791 | *class = ATA_DEV_NONE; |
809 | goto out; | 792 | return 0; |
810 | } | 793 | } |
811 | 794 | ||
812 | /* | 795 | /* |
@@ -819,11 +802,44 @@ try_offline_again: | |||
819 | if ((temp & 0xFF) != 0x18) { | 802 | if ((temp & 0xFF) != 0x18) { |
820 | ata_port_printk(ap, KERN_WARNING, "No Signature Update\n"); | 803 | ata_port_printk(ap, KERN_WARNING, "No Signature Update\n"); |
821 | *class = ATA_DEV_NONE; | 804 | *class = ATA_DEV_NONE; |
822 | goto out; | 805 | goto do_followup_srst; |
823 | } else { | 806 | } else { |
824 | ata_port_printk(ap, KERN_INFO, | 807 | ata_port_printk(ap, KERN_INFO, |
825 | "Signature Update detected @ %d msecs\n", | 808 | "Signature Update detected @ %d msecs\n", |
826 | jiffies_to_msecs(jiffies - start_jiffies)); | 809 | jiffies_to_msecs(jiffies - start_jiffies)); |
810 | *class = sata_fsl_dev_classify(ap); | ||
811 | return 0; | ||
812 | } | ||
813 | |||
814 | do_followup_srst: | ||
815 | /* | ||
816 | * request libATA to perform follow-up softreset | ||
817 | */ | ||
818 | return -EAGAIN; | ||
819 | |||
820 | err: | ||
821 | return -EIO; | ||
822 | } | ||
823 | |||
824 | static int sata_fsl_softreset(struct ata_link *link, unsigned int *class, | ||
825 | unsigned long deadline) | ||
826 | { | ||
827 | struct ata_port *ap = link->ap; | ||
828 | struct sata_fsl_port_priv *pp = ap->private_data; | ||
829 | struct sata_fsl_host_priv *host_priv = ap->host->private_data; | ||
830 | void __iomem *hcr_base = host_priv->hcr_base; | ||
831 | int pmp = sata_srst_pmp(link); | ||
832 | u32 temp; | ||
833 | struct ata_taskfile tf; | ||
834 | u8 *cfis; | ||
835 | u32 Serror; | ||
836 | |||
837 | DPRINTK("in xx_softreset\n"); | ||
838 | |||
839 | if (ata_link_offline(link)) { | ||
840 | DPRINTK("PHY reports no device\n"); | ||
841 | *class = ATA_DEV_NONE; | ||
842 | return 0; | ||
827 | } | 843 | } |
828 | 844 | ||
829 | /* | 845 | /* |
@@ -834,7 +850,6 @@ try_offline_again: | |||
834 | * reached here, we can send a command to the target device | 850 | * reached here, we can send a command to the target device |
835 | */ | 851 | */ |
836 | 852 | ||
837 | issue_srst: | ||
838 | DPRINTK("Sending SRST/device reset\n"); | 853 | DPRINTK("Sending SRST/device reset\n"); |
839 | 854 | ||
840 | ata_tf_init(link->device, &tf); | 855 | ata_tf_init(link->device, &tf); |
@@ -860,6 +875,8 @@ issue_srst: | |||
860 | ioread32(CA + hcr_base), ioread32(CC + hcr_base)); | 875 | ioread32(CA + hcr_base), ioread32(CC + hcr_base)); |
861 | 876 | ||
862 | iowrite32(0xFFFF, CC + hcr_base); | 877 | iowrite32(0xFFFF, CC + hcr_base); |
878 | if (pmp != SATA_PMP_CTRL_PORT) | ||
879 | iowrite32(pmp, CQPMP + hcr_base); | ||
863 | iowrite32(1, CQ + hcr_base); | 880 | iowrite32(1, CQ + hcr_base); |
864 | 881 | ||
865 | temp = ata_wait_register(CQ + hcr_base, 0x1, 0x1, 1, 5000); | 882 | temp = ata_wait_register(CQ + hcr_base, 0x1, 0x1, 1, 5000); |
@@ -926,7 +943,6 @@ issue_srst: | |||
926 | VPRINTK("cereg = 0x%x\n", ioread32(hcr_base + CE)); | 943 | VPRINTK("cereg = 0x%x\n", ioread32(hcr_base + CE)); |
927 | } | 944 | } |
928 | 945 | ||
929 | out: | ||
930 | return 0; | 946 | return 0; |
931 | 947 | ||
932 | err: | 948 | err: |
@@ -988,18 +1004,6 @@ static void sata_fsl_error_intr(struct ata_port *ap) | |||
988 | ehi->err_mask |= AC_ERR_ATA_BUS; | 1004 | ehi->err_mask |= AC_ERR_ATA_BUS; |
989 | ehi->action |= ATA_EH_SOFTRESET; | 1005 | ehi->action |= ATA_EH_SOFTRESET; |
990 | 1006 | ||
991 | /* | ||
992 | * Ignore serror in case of fatal errors as we always want | ||
993 | * to do a soft-reset of the FSL SATA controller. Analyzing | ||
994 | * serror may cause libata to schedule a hard-reset action, | ||
995 | * and hard-reset currently does not do controller | ||
996 | * offline/online, causing command timeouts and leads to an | ||
997 | * un-recoverable state, hence make libATA ignore | ||
998 | * autopsy in case of fatal errors. | ||
999 | */ | ||
1000 | |||
1001 | ehi->flags |= ATA_EHI_NO_AUTOPSY; | ||
1002 | |||
1003 | freeze = 1; | 1007 | freeze = 1; |
1004 | } | 1008 | } |
1005 | 1009 | ||
@@ -1267,8 +1271,8 @@ static struct ata_port_operations sata_fsl_ops = { | |||
1267 | 1271 | ||
1268 | .freeze = sata_fsl_freeze, | 1272 | .freeze = sata_fsl_freeze, |
1269 | .thaw = sata_fsl_thaw, | 1273 | .thaw = sata_fsl_thaw, |
1270 | .prereset = sata_fsl_prereset, | ||
1271 | .softreset = sata_fsl_softreset, | 1274 | .softreset = sata_fsl_softreset, |
1275 | .hardreset = sata_fsl_hardreset, | ||
1272 | .pmp_softreset = sata_fsl_softreset, | 1276 | .pmp_softreset = sata_fsl_softreset, |
1273 | .error_handler = sata_fsl_error_handler, | 1277 | .error_handler = sata_fsl_error_handler, |
1274 | .post_internal_cmd = sata_fsl_post_internal_cmd, | 1278 | .post_internal_cmd = sata_fsl_post_internal_cmd, |
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index a770498a74ec..846d89e3d122 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c | |||
@@ -328,11 +328,11 @@ int __pm_runtime_resume(struct device *dev, bool from_wq) | |||
328 | * necessary. | 328 | * necessary. |
329 | */ | 329 | */ |
330 | parent = dev->parent; | 330 | parent = dev->parent; |
331 | spin_unlock_irq(&dev->power.lock); | 331 | spin_unlock(&dev->power.lock); |
332 | 332 | ||
333 | pm_runtime_get_noresume(parent); | 333 | pm_runtime_get_noresume(parent); |
334 | 334 | ||
335 | spin_lock_irq(&parent->power.lock); | 335 | spin_lock(&parent->power.lock); |
336 | /* | 336 | /* |
337 | * We can resume if the parent's run-time PM is disabled or it | 337 | * We can resume if the parent's run-time PM is disabled or it |
338 | * is set to ignore children. | 338 | * is set to ignore children. |
@@ -343,9 +343,9 @@ int __pm_runtime_resume(struct device *dev, bool from_wq) | |||
343 | if (parent->power.runtime_status != RPM_ACTIVE) | 343 | if (parent->power.runtime_status != RPM_ACTIVE) |
344 | retval = -EBUSY; | 344 | retval = -EBUSY; |
345 | } | 345 | } |
346 | spin_unlock_irq(&parent->power.lock); | 346 | spin_unlock(&parent->power.lock); |
347 | 347 | ||
348 | spin_lock_irq(&dev->power.lock); | 348 | spin_lock(&dev->power.lock); |
349 | if (retval) | 349 | if (retval) |
350 | goto out; | 350 | goto out; |
351 | goto repeat; | 351 | goto repeat; |
@@ -777,7 +777,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status) | |||
777 | } | 777 | } |
778 | 778 | ||
779 | if (parent) { | 779 | if (parent) { |
780 | spin_lock_irq(&parent->power.lock); | 780 | spin_lock(&parent->power.lock); |
781 | 781 | ||
782 | /* | 782 | /* |
783 | * It is invalid to put an active child under a parent that is | 783 | * It is invalid to put an active child under a parent that is |
@@ -793,7 +793,7 @@ int __pm_runtime_set_status(struct device *dev, unsigned int status) | |||
793 | atomic_inc(&parent->power.child_count); | 793 | atomic_inc(&parent->power.child_count); |
794 | } | 794 | } |
795 | 795 | ||
796 | spin_unlock_irq(&parent->power.lock); | 796 | spin_unlock(&parent->power.lock); |
797 | 797 | ||
798 | if (error) | 798 | if (error) |
799 | goto out; | 799 | goto out; |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 6399e5090df4..92b126394fa1 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -482,7 +482,7 @@ static ssize_t host_store_rescan(struct device *dev, | |||
482 | 482 | ||
483 | return count; | 483 | return count; |
484 | } | 484 | } |
485 | DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan); | 485 | static DEVICE_ATTR(rescan, S_IWUSR, NULL, host_store_rescan); |
486 | 486 | ||
487 | static ssize_t dev_show_unique_id(struct device *dev, | 487 | static ssize_t dev_show_unique_id(struct device *dev, |
488 | struct device_attribute *attr, | 488 | struct device_attribute *attr, |
@@ -512,7 +512,7 @@ static ssize_t dev_show_unique_id(struct device *dev, | |||
512 | sn[8], sn[9], sn[10], sn[11], | 512 | sn[8], sn[9], sn[10], sn[11], |
513 | sn[12], sn[13], sn[14], sn[15]); | 513 | sn[12], sn[13], sn[14], sn[15]); |
514 | } | 514 | } |
515 | DEVICE_ATTR(unique_id, S_IRUGO, dev_show_unique_id, NULL); | 515 | static DEVICE_ATTR(unique_id, S_IRUGO, dev_show_unique_id, NULL); |
516 | 516 | ||
517 | static ssize_t dev_show_vendor(struct device *dev, | 517 | static ssize_t dev_show_vendor(struct device *dev, |
518 | struct device_attribute *attr, | 518 | struct device_attribute *attr, |
@@ -536,7 +536,7 @@ static ssize_t dev_show_vendor(struct device *dev, | |||
536 | else | 536 | else |
537 | return snprintf(buf, sizeof(vendor) + 1, "%s\n", drv->vendor); | 537 | return snprintf(buf, sizeof(vendor) + 1, "%s\n", drv->vendor); |
538 | } | 538 | } |
539 | DEVICE_ATTR(vendor, S_IRUGO, dev_show_vendor, NULL); | 539 | static DEVICE_ATTR(vendor, S_IRUGO, dev_show_vendor, NULL); |
540 | 540 | ||
541 | static ssize_t dev_show_model(struct device *dev, | 541 | static ssize_t dev_show_model(struct device *dev, |
542 | struct device_attribute *attr, | 542 | struct device_attribute *attr, |
@@ -560,7 +560,7 @@ static ssize_t dev_show_model(struct device *dev, | |||
560 | else | 560 | else |
561 | return snprintf(buf, sizeof(model) + 1, "%s\n", drv->model); | 561 | return snprintf(buf, sizeof(model) + 1, "%s\n", drv->model); |
562 | } | 562 | } |
563 | DEVICE_ATTR(model, S_IRUGO, dev_show_model, NULL); | 563 | static DEVICE_ATTR(model, S_IRUGO, dev_show_model, NULL); |
564 | 564 | ||
565 | static ssize_t dev_show_rev(struct device *dev, | 565 | static ssize_t dev_show_rev(struct device *dev, |
566 | struct device_attribute *attr, | 566 | struct device_attribute *attr, |
@@ -584,7 +584,7 @@ static ssize_t dev_show_rev(struct device *dev, | |||
584 | else | 584 | else |
585 | return snprintf(buf, sizeof(rev) + 1, "%s\n", drv->rev); | 585 | return snprintf(buf, sizeof(rev) + 1, "%s\n", drv->rev); |
586 | } | 586 | } |
587 | DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL); | 587 | static DEVICE_ATTR(rev, S_IRUGO, dev_show_rev, NULL); |
588 | 588 | ||
589 | static ssize_t cciss_show_lunid(struct device *dev, | 589 | static ssize_t cciss_show_lunid(struct device *dev, |
590 | struct device_attribute *attr, char *buf) | 590 | struct device_attribute *attr, char *buf) |
@@ -609,7 +609,7 @@ static ssize_t cciss_show_lunid(struct device *dev, | |||
609 | lunid[0], lunid[1], lunid[2], lunid[3], | 609 | lunid[0], lunid[1], lunid[2], lunid[3], |
610 | lunid[4], lunid[5], lunid[6], lunid[7]); | 610 | lunid[4], lunid[5], lunid[6], lunid[7]); |
611 | } | 611 | } |
612 | DEVICE_ATTR(lunid, S_IRUGO, cciss_show_lunid, NULL); | 612 | static DEVICE_ATTR(lunid, S_IRUGO, cciss_show_lunid, NULL); |
613 | 613 | ||
614 | static ssize_t cciss_show_raid_level(struct device *dev, | 614 | static ssize_t cciss_show_raid_level(struct device *dev, |
615 | struct device_attribute *attr, char *buf) | 615 | struct device_attribute *attr, char *buf) |
@@ -632,7 +632,7 @@ static ssize_t cciss_show_raid_level(struct device *dev, | |||
632 | return snprintf(buf, strlen(raid_label[raid]) + 7, "RAID %s\n", | 632 | return snprintf(buf, strlen(raid_label[raid]) + 7, "RAID %s\n", |
633 | raid_label[raid]); | 633 | raid_label[raid]); |
634 | } | 634 | } |
635 | DEVICE_ATTR(raid_level, S_IRUGO, cciss_show_raid_level, NULL); | 635 | static DEVICE_ATTR(raid_level, S_IRUGO, cciss_show_raid_level, NULL); |
636 | 636 | ||
637 | static ssize_t cciss_show_usage_count(struct device *dev, | 637 | static ssize_t cciss_show_usage_count(struct device *dev, |
638 | struct device_attribute *attr, char *buf) | 638 | struct device_attribute *attr, char *buf) |
@@ -651,7 +651,7 @@ static ssize_t cciss_show_usage_count(struct device *dev, | |||
651 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); | 651 | spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); |
652 | return snprintf(buf, 20, "%d\n", count); | 652 | return snprintf(buf, 20, "%d\n", count); |
653 | } | 653 | } |
654 | DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL); | 654 | static DEVICE_ATTR(usage_count, S_IRUGO, cciss_show_usage_count, NULL); |
655 | 655 | ||
656 | static struct attribute *cciss_host_attrs[] = { | 656 | static struct attribute *cciss_host_attrs[] = { |
657 | &dev_attr_rescan.attr, | 657 | &dev_attr_rescan.attr, |
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 10e1f0390bbb..3cb56a049e24 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c | |||
@@ -62,6 +62,7 @@ | |||
62 | #define PCI_DEVICE_ID_INTEL_IGDNG_D_IG 0x0042 | 62 | #define PCI_DEVICE_ID_INTEL_IGDNG_D_IG 0x0042 |
63 | #define PCI_DEVICE_ID_INTEL_IGDNG_M_HB 0x0044 | 63 | #define PCI_DEVICE_ID_INTEL_IGDNG_M_HB 0x0044 |
64 | #define PCI_DEVICE_ID_INTEL_IGDNG_MA_HB 0x0062 | 64 | #define PCI_DEVICE_ID_INTEL_IGDNG_MA_HB 0x0062 |
65 | #define PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB 0x006a | ||
65 | #define PCI_DEVICE_ID_INTEL_IGDNG_M_IG 0x0046 | 66 | #define PCI_DEVICE_ID_INTEL_IGDNG_M_IG 0x0046 |
66 | 67 | ||
67 | /* cover 915 and 945 variants */ | 68 | /* cover 915 and 945 variants */ |
@@ -96,7 +97,8 @@ | |||
96 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_B43_HB || \ | 97 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_B43_HB || \ |
97 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \ | 98 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_D_HB || \ |
98 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB || \ | 99 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_M_HB || \ |
99 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB) | 100 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MA_HB || \ |
101 | agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB) | ||
100 | 102 | ||
101 | extern int agp_memory_reserved; | 103 | extern int agp_memory_reserved; |
102 | 104 | ||
@@ -1358,6 +1360,7 @@ static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size) | |||
1358 | case PCI_DEVICE_ID_INTEL_IGDNG_D_HB: | 1360 | case PCI_DEVICE_ID_INTEL_IGDNG_D_HB: |
1359 | case PCI_DEVICE_ID_INTEL_IGDNG_M_HB: | 1361 | case PCI_DEVICE_ID_INTEL_IGDNG_M_HB: |
1360 | case PCI_DEVICE_ID_INTEL_IGDNG_MA_HB: | 1362 | case PCI_DEVICE_ID_INTEL_IGDNG_MA_HB: |
1363 | case PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB: | ||
1361 | *gtt_offset = *gtt_size = MB(2); | 1364 | *gtt_offset = *gtt_size = MB(2); |
1362 | break; | 1365 | break; |
1363 | default: | 1366 | default: |
@@ -2359,6 +2362,8 @@ static const struct intel_driver_description { | |||
2359 | "IGDNG/M", NULL, &intel_i965_driver }, | 2362 | "IGDNG/M", NULL, &intel_i965_driver }, |
2360 | { PCI_DEVICE_ID_INTEL_IGDNG_MA_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0, | 2363 | { PCI_DEVICE_ID_INTEL_IGDNG_MA_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0, |
2361 | "IGDNG/MA", NULL, &intel_i965_driver }, | 2364 | "IGDNG/MA", NULL, &intel_i965_driver }, |
2365 | { PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB, PCI_DEVICE_ID_INTEL_IGDNG_M_IG, 0, | ||
2366 | "IGDNG/MC2", NULL, &intel_i965_driver }, | ||
2362 | { 0, 0, 0, NULL, NULL, NULL } | 2367 | { 0, 0, 0, NULL, NULL, NULL } |
2363 | }; | 2368 | }; |
2364 | 2369 | ||
@@ -2560,6 +2565,7 @@ static struct pci_device_id agp_intel_pci_table[] = { | |||
2560 | ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB), | 2565 | ID(PCI_DEVICE_ID_INTEL_IGDNG_D_HB), |
2561 | ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB), | 2566 | ID(PCI_DEVICE_ID_INTEL_IGDNG_M_HB), |
2562 | ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB), | 2567 | ID(PCI_DEVICE_ID_INTEL_IGDNG_MA_HB), |
2568 | ID(PCI_DEVICE_ID_INTEL_IGDNG_MC2_HB), | ||
2563 | { } | 2569 | { } |
2564 | }; | 2570 | }; |
2565 | 2571 | ||
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 737be953cc58..950837cf9e9c 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -1249,7 +1249,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) | |||
1249 | 1249 | ||
1250 | if (keycode >= NR_KEYS) | 1250 | if (keycode >= NR_KEYS) |
1251 | if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8) | 1251 | if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8) |
1252 | keysym = K(KT_BRL, keycode - KEY_BRL_DOT1 + 1); | 1252 | keysym = U(K(KT_BRL, keycode - KEY_BRL_DOT1 + 1)); |
1253 | else | 1253 | else |
1254 | return; | 1254 | return; |
1255 | else | 1255 | else |
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index a9952b1236b0..84c51e177269 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c | |||
@@ -236,7 +236,7 @@ static inline void ecb_crypt(const u8 *in, u8 *out, u32 *key, | |||
236 | /* Padlock in ECB mode fetches at least ecb_fetch_bytes of data. | 236 | /* Padlock in ECB mode fetches at least ecb_fetch_bytes of data. |
237 | * We could avoid some copying here but it's probably not worth it. | 237 | * We could avoid some copying here but it's probably not worth it. |
238 | */ | 238 | */ |
239 | if (unlikely(((unsigned long)in & PAGE_SIZE) + ecb_fetch_bytes > PAGE_SIZE)) { | 239 | if (unlikely(((unsigned long)in & ~PAGE_MASK) + ecb_fetch_bytes > PAGE_SIZE)) { |
240 | ecb_crypt_copy(in, out, key, cword, count); | 240 | ecb_crypt_copy(in, out, key, cword, count); |
241 | return; | 241 | return; |
242 | } | 242 | } |
@@ -248,7 +248,7 @@ static inline u8 *cbc_crypt(const u8 *in, u8 *out, u32 *key, | |||
248 | u8 *iv, struct cword *cword, int count) | 248 | u8 *iv, struct cword *cword, int count) |
249 | { | 249 | { |
250 | /* Padlock in CBC mode fetches at least cbc_fetch_bytes of data. */ | 250 | /* Padlock in CBC mode fetches at least cbc_fetch_bytes of data. */ |
251 | if (unlikely(((unsigned long)in & PAGE_SIZE) + cbc_fetch_bytes > PAGE_SIZE)) | 251 | if (unlikely(((unsigned long)in & ~PAGE_MASK) + cbc_fetch_bytes > PAGE_SIZE)) |
252 | return cbc_crypt_copy(in, out, key, iv, cword, count); | 252 | return cbc_crypt_copy(in, out, key, iv, cword, count); |
253 | 253 | ||
254 | return rep_xcrypt_cbc(in, out, key, iv, cword, count); | 254 | return rep_xcrypt_cbc(in, out, key, iv, cword, count); |
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 5903a88351bf..eb140ff38c27 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig | |||
@@ -26,6 +26,8 @@ config INTEL_IOATDMA | |||
26 | select DMA_ENGINE | 26 | select DMA_ENGINE |
27 | select DCA | 27 | select DCA |
28 | select ASYNC_TX_DISABLE_CHANNEL_SWITCH | 28 | select ASYNC_TX_DISABLE_CHANNEL_SWITCH |
29 | select ASYNC_TX_DISABLE_PQ_VAL_DMA | ||
30 | select ASYNC_TX_DISABLE_XOR_VAL_DMA | ||
29 | help | 31 | help |
30 | Enable support for the Intel(R) I/OAT DMA engine present | 32 | Enable support for the Intel(R) I/OAT DMA engine present |
31 | in recent Intel Xeon chipsets. | 33 | in recent Intel Xeon chipsets. |
@@ -52,7 +54,7 @@ config DW_DMAC | |||
52 | 54 | ||
53 | config AT_HDMAC | 55 | config AT_HDMAC |
54 | tristate "Atmel AHB DMA support" | 56 | tristate "Atmel AHB DMA support" |
55 | depends on ARCH_AT91SAM9RL | 57 | depends on ARCH_AT91SAM9RL || ARCH_AT91SAM9G45 |
56 | select DMA_ENGINE | 58 | select DMA_ENGINE |
57 | help | 59 | help |
58 | Support the Atmel AHB DMA controller. This can be integrated in | 60 | Support the Atmel AHB DMA controller. This can be integrated in |
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index bd0b248de2cf..8f99354082ce 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c | |||
@@ -632,11 +632,21 @@ static bool device_has_all_tx_types(struct dma_device *device) | |||
632 | #if defined(CONFIG_ASYNC_XOR) || defined(CONFIG_ASYNC_XOR_MODULE) | 632 | #if defined(CONFIG_ASYNC_XOR) || defined(CONFIG_ASYNC_XOR_MODULE) |
633 | if (!dma_has_cap(DMA_XOR, device->cap_mask)) | 633 | if (!dma_has_cap(DMA_XOR, device->cap_mask)) |
634 | return false; | 634 | return false; |
635 | |||
636 | #ifndef CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA | ||
637 | if (!dma_has_cap(DMA_XOR_VAL, device->cap_mask)) | ||
638 | return false; | ||
639 | #endif | ||
635 | #endif | 640 | #endif |
636 | 641 | ||
637 | #if defined(CONFIG_ASYNC_PQ) || defined(CONFIG_ASYNC_PQ_MODULE) | 642 | #if defined(CONFIG_ASYNC_PQ) || defined(CONFIG_ASYNC_PQ_MODULE) |
638 | if (!dma_has_cap(DMA_PQ, device->cap_mask)) | 643 | if (!dma_has_cap(DMA_PQ, device->cap_mask)) |
639 | return false; | 644 | return false; |
645 | |||
646 | #ifndef CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA | ||
647 | if (!dma_has_cap(DMA_PQ_VAL, device->cap_mask)) | ||
648 | return false; | ||
649 | #endif | ||
640 | #endif | 650 | #endif |
641 | 651 | ||
642 | return true; | 652 | return true; |
diff --git a/drivers/dma/ioat/dca.c b/drivers/dma/ioat/dca.c index 69d02615c4d6..abd9038e06b1 100644 --- a/drivers/dma/ioat/dca.c +++ b/drivers/dma/ioat/dca.c | |||
@@ -98,17 +98,17 @@ static int dca_enabled_in_bios(struct pci_dev *pdev) | |||
98 | cpuid_level_9 = cpuid_eax(9); | 98 | cpuid_level_9 = cpuid_eax(9); |
99 | res = test_bit(0, &cpuid_level_9); | 99 | res = test_bit(0, &cpuid_level_9); |
100 | if (!res) | 100 | if (!res) |
101 | dev_err(&pdev->dev, "DCA is disabled in BIOS\n"); | 101 | dev_dbg(&pdev->dev, "DCA is disabled in BIOS\n"); |
102 | 102 | ||
103 | return res; | 103 | return res; |
104 | } | 104 | } |
105 | 105 | ||
106 | static int system_has_dca_enabled(struct pci_dev *pdev) | 106 | int system_has_dca_enabled(struct pci_dev *pdev) |
107 | { | 107 | { |
108 | if (boot_cpu_has(X86_FEATURE_DCA)) | 108 | if (boot_cpu_has(X86_FEATURE_DCA)) |
109 | return dca_enabled_in_bios(pdev); | 109 | return dca_enabled_in_bios(pdev); |
110 | 110 | ||
111 | dev_err(&pdev->dev, "boot cpu doesn't have X86_FEATURE_DCA\n"); | 111 | dev_dbg(&pdev->dev, "boot cpu doesn't have X86_FEATURE_DCA\n"); |
112 | return 0; | 112 | return 0; |
113 | } | 113 | } |
114 | 114 | ||
diff --git a/drivers/dma/ioat/dma.h b/drivers/dma/ioat/dma.h index c14fdfeb7f33..45edde996480 100644 --- a/drivers/dma/ioat/dma.h +++ b/drivers/dma/ioat/dma.h | |||
@@ -297,9 +297,7 @@ static inline bool is_ioat_suspended(unsigned long status) | |||
297 | /* channel was fatally programmed */ | 297 | /* channel was fatally programmed */ |
298 | static inline bool is_ioat_bug(unsigned long err) | 298 | static inline bool is_ioat_bug(unsigned long err) |
299 | { | 299 | { |
300 | return !!(err & (IOAT_CHANERR_SRC_ADDR_ERR|IOAT_CHANERR_DEST_ADDR_ERR| | 300 | return !!err; |
301 | IOAT_CHANERR_NEXT_ADDR_ERR|IOAT_CHANERR_CONTROL_ERR| | ||
302 | IOAT_CHANERR_LENGTH_ERR)); | ||
303 | } | 301 | } |
304 | 302 | ||
305 | static inline void ioat_unmap(struct pci_dev *pdev, dma_addr_t addr, size_t len, | 303 | static inline void ioat_unmap(struct pci_dev *pdev, dma_addr_t addr, size_t len, |
diff --git a/drivers/dma/ioat/dma_v2.c b/drivers/dma/ioat/dma_v2.c index 96ffab7d37a7..8f1f7f05deaa 100644 --- a/drivers/dma/ioat/dma_v2.c +++ b/drivers/dma/ioat/dma_v2.c | |||
@@ -279,6 +279,8 @@ void ioat2_timer_event(unsigned long data) | |||
279 | u32 chanerr; | 279 | u32 chanerr; |
280 | 280 | ||
281 | chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); | 281 | chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); |
282 | dev_err(to_dev(chan), "%s: Channel halted (%x)\n", | ||
283 | __func__, chanerr); | ||
282 | BUG_ON(is_ioat_bug(chanerr)); | 284 | BUG_ON(is_ioat_bug(chanerr)); |
283 | } | 285 | } |
284 | 286 | ||
diff --git a/drivers/dma/ioat/dma_v3.c b/drivers/dma/ioat/dma_v3.c index 35d1e33afd5b..42f6f10fb0cc 100644 --- a/drivers/dma/ioat/dma_v3.c +++ b/drivers/dma/ioat/dma_v3.c | |||
@@ -378,6 +378,8 @@ static void ioat3_timer_event(unsigned long data) | |||
378 | u32 chanerr; | 378 | u32 chanerr; |
379 | 379 | ||
380 | chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); | 380 | chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET); |
381 | dev_err(to_dev(chan), "%s: Channel halted (%x)\n", | ||
382 | __func__, chanerr); | ||
381 | BUG_ON(is_ioat_bug(chanerr)); | 383 | BUG_ON(is_ioat_bug(chanerr)); |
382 | } | 384 | } |
383 | 385 | ||
@@ -569,7 +571,7 @@ __ioat3_prep_xor_lock(struct dma_chan *c, enum sum_check_flags *result, | |||
569 | dump_desc_dbg(ioat, compl_desc); | 571 | dump_desc_dbg(ioat, compl_desc); |
570 | 572 | ||
571 | /* we leave the channel locked to ensure in order submission */ | 573 | /* we leave the channel locked to ensure in order submission */ |
572 | return &desc->txd; | 574 | return &compl_desc->txd; |
573 | } | 575 | } |
574 | 576 | ||
575 | static struct dma_async_tx_descriptor * | 577 | static struct dma_async_tx_descriptor * |
@@ -728,7 +730,7 @@ __ioat3_prep_pq_lock(struct dma_chan *c, enum sum_check_flags *result, | |||
728 | dump_desc_dbg(ioat, compl_desc); | 730 | dump_desc_dbg(ioat, compl_desc); |
729 | 731 | ||
730 | /* we leave the channel locked to ensure in order submission */ | 732 | /* we leave the channel locked to ensure in order submission */ |
731 | return &desc->txd; | 733 | return &compl_desc->txd; |
732 | } | 734 | } |
733 | 735 | ||
734 | static struct dma_async_tx_descriptor * | 736 | static struct dma_async_tx_descriptor * |
@@ -736,10 +738,16 @@ ioat3_prep_pq(struct dma_chan *chan, dma_addr_t *dst, dma_addr_t *src, | |||
736 | unsigned int src_cnt, const unsigned char *scf, size_t len, | 738 | unsigned int src_cnt, const unsigned char *scf, size_t len, |
737 | unsigned long flags) | 739 | unsigned long flags) |
738 | { | 740 | { |
741 | /* specify valid address for disabled result */ | ||
742 | if (flags & DMA_PREP_PQ_DISABLE_P) | ||
743 | dst[0] = dst[1]; | ||
744 | if (flags & DMA_PREP_PQ_DISABLE_Q) | ||
745 | dst[1] = dst[0]; | ||
746 | |||
739 | /* handle the single source multiply case from the raid6 | 747 | /* handle the single source multiply case from the raid6 |
740 | * recovery path | 748 | * recovery path |
741 | */ | 749 | */ |
742 | if (unlikely((flags & DMA_PREP_PQ_DISABLE_P) && src_cnt == 1)) { | 750 | if ((flags & DMA_PREP_PQ_DISABLE_P) && src_cnt == 1) { |
743 | dma_addr_t single_source[2]; | 751 | dma_addr_t single_source[2]; |
744 | unsigned char single_source_coef[2]; | 752 | unsigned char single_source_coef[2]; |
745 | 753 | ||
@@ -761,6 +769,12 @@ ioat3_prep_pq_val(struct dma_chan *chan, dma_addr_t *pq, dma_addr_t *src, | |||
761 | unsigned int src_cnt, const unsigned char *scf, size_t len, | 769 | unsigned int src_cnt, const unsigned char *scf, size_t len, |
762 | enum sum_check_flags *pqres, unsigned long flags) | 770 | enum sum_check_flags *pqres, unsigned long flags) |
763 | { | 771 | { |
772 | /* specify valid address for disabled result */ | ||
773 | if (flags & DMA_PREP_PQ_DISABLE_P) | ||
774 | pq[0] = pq[1]; | ||
775 | if (flags & DMA_PREP_PQ_DISABLE_Q) | ||
776 | pq[1] = pq[0]; | ||
777 | |||
764 | /* the cleanup routine only sets bits on validate failure, it | 778 | /* the cleanup routine only sets bits on validate failure, it |
765 | * does not clear bits on validate success... so clear it here | 779 | * does not clear bits on validate success... so clear it here |
766 | */ | 780 | */ |
@@ -778,9 +792,9 @@ ioat3_prep_pqxor(struct dma_chan *chan, dma_addr_t dst, dma_addr_t *src, | |||
778 | dma_addr_t pq[2]; | 792 | dma_addr_t pq[2]; |
779 | 793 | ||
780 | memset(scf, 0, src_cnt); | 794 | memset(scf, 0, src_cnt); |
781 | flags |= DMA_PREP_PQ_DISABLE_Q; | ||
782 | pq[0] = dst; | 795 | pq[0] = dst; |
783 | pq[1] = ~0; | 796 | flags |= DMA_PREP_PQ_DISABLE_Q; |
797 | pq[1] = dst; /* specify valid address for disabled result */ | ||
784 | 798 | ||
785 | return __ioat3_prep_pq_lock(chan, NULL, pq, src, src_cnt, scf, len, | 799 | return __ioat3_prep_pq_lock(chan, NULL, pq, src, src_cnt, scf, len, |
786 | flags); | 800 | flags); |
@@ -800,9 +814,9 @@ ioat3_prep_pqxor_val(struct dma_chan *chan, dma_addr_t *src, | |||
800 | *result = 0; | 814 | *result = 0; |
801 | 815 | ||
802 | memset(scf, 0, src_cnt); | 816 | memset(scf, 0, src_cnt); |
803 | flags |= DMA_PREP_PQ_DISABLE_Q; | ||
804 | pq[0] = src[0]; | 817 | pq[0] = src[0]; |
805 | pq[1] = ~0; | 818 | flags |= DMA_PREP_PQ_DISABLE_Q; |
819 | pq[1] = pq[0]; /* specify valid address for disabled result */ | ||
806 | 820 | ||
807 | return __ioat3_prep_pq_lock(chan, result, pq, &src[1], src_cnt - 1, scf, | 821 | return __ioat3_prep_pq_lock(chan, result, pq, &src[1], src_cnt - 1, scf, |
808 | len, flags); | 822 | len, flags); |
@@ -1117,6 +1131,7 @@ static int __devinit ioat3_dma_self_test(struct ioatdma_device *device) | |||
1117 | int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) | 1131 | int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) |
1118 | { | 1132 | { |
1119 | struct pci_dev *pdev = device->pdev; | 1133 | struct pci_dev *pdev = device->pdev; |
1134 | int dca_en = system_has_dca_enabled(pdev); | ||
1120 | struct dma_device *dma; | 1135 | struct dma_device *dma; |
1121 | struct dma_chan *c; | 1136 | struct dma_chan *c; |
1122 | struct ioat_chan_common *chan; | 1137 | struct ioat_chan_common *chan; |
@@ -1137,6 +1152,11 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) | |||
1137 | dma->device_prep_dma_interrupt = ioat3_prep_interrupt_lock; | 1152 | dma->device_prep_dma_interrupt = ioat3_prep_interrupt_lock; |
1138 | 1153 | ||
1139 | cap = readl(device->reg_base + IOAT_DMA_CAP_OFFSET); | 1154 | cap = readl(device->reg_base + IOAT_DMA_CAP_OFFSET); |
1155 | |||
1156 | /* dca is incompatible with raid operations */ | ||
1157 | if (dca_en && (cap & (IOAT_CAP_XOR|IOAT_CAP_PQ))) | ||
1158 | cap &= ~(IOAT_CAP_XOR|IOAT_CAP_PQ); | ||
1159 | |||
1140 | if (cap & IOAT_CAP_XOR) { | 1160 | if (cap & IOAT_CAP_XOR) { |
1141 | is_raid_device = true; | 1161 | is_raid_device = true; |
1142 | dma->max_xor = 8; | 1162 | dma->max_xor = 8; |
@@ -1186,6 +1206,16 @@ int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca) | |||
1186 | device->timer_fn = ioat2_timer_event; | 1206 | device->timer_fn = ioat2_timer_event; |
1187 | } | 1207 | } |
1188 | 1208 | ||
1209 | #ifdef CONFIG_ASYNC_TX_DISABLE_PQ_VAL_DMA | ||
1210 | dma_cap_clear(DMA_PQ_VAL, dma->cap_mask); | ||
1211 | dma->device_prep_dma_pq_val = NULL; | ||
1212 | #endif | ||
1213 | |||
1214 | #ifdef CONFIG_ASYNC_TX_DISABLE_XOR_VAL_DMA | ||
1215 | dma_cap_clear(DMA_XOR_VAL, dma->cap_mask); | ||
1216 | dma->device_prep_dma_xor_val = NULL; | ||
1217 | #endif | ||
1218 | |||
1189 | /* -= IOAT ver.3 workarounds =- */ | 1219 | /* -= IOAT ver.3 workarounds =- */ |
1190 | /* Write CHANERRMSK_INT with 3E07h to mask out the errors | 1220 | /* Write CHANERRMSK_INT with 3E07h to mask out the errors |
1191 | * that can cause stability issues for IOAT ver.3 | 1221 | * that can cause stability issues for IOAT ver.3 |
diff --git a/drivers/dma/ioat/hw.h b/drivers/dma/ioat/hw.h index 99afb12bd409..60e675455b6a 100644 --- a/drivers/dma/ioat/hw.h +++ b/drivers/dma/ioat/hw.h | |||
@@ -39,6 +39,8 @@ | |||
39 | #define IOAT_VER_3_0 0x30 /* Version 3.0 */ | 39 | #define IOAT_VER_3_0 0x30 /* Version 3.0 */ |
40 | #define IOAT_VER_3_2 0x32 /* Version 3.2 */ | 40 | #define IOAT_VER_3_2 0x32 /* Version 3.2 */ |
41 | 41 | ||
42 | int system_has_dca_enabled(struct pci_dev *pdev); | ||
43 | |||
42 | struct ioat_dma_descriptor { | 44 | struct ioat_dma_descriptor { |
43 | uint32_t size; | 45 | uint32_t size; |
44 | union { | 46 | union { |
diff --git a/drivers/dma/ioat/registers.h b/drivers/dma/ioat/registers.h index 63038e18ab03..f015ec196700 100644 --- a/drivers/dma/ioat/registers.h +++ b/drivers/dma/ioat/registers.h | |||
@@ -92,9 +92,7 @@ | |||
92 | #define IOAT_CHANCTRL_ERR_COMPLETION_EN 0x0004 | 92 | #define IOAT_CHANCTRL_ERR_COMPLETION_EN 0x0004 |
93 | #define IOAT_CHANCTRL_INT_REARM 0x0001 | 93 | #define IOAT_CHANCTRL_INT_REARM 0x0001 |
94 | #define IOAT_CHANCTRL_RUN (IOAT_CHANCTRL_INT_REARM |\ | 94 | #define IOAT_CHANCTRL_RUN (IOAT_CHANCTRL_INT_REARM |\ |
95 | IOAT_CHANCTRL_ERR_COMPLETION_EN |\ | 95 | IOAT_CHANCTRL_ANY_ERR_ABORT_EN) |
96 | IOAT_CHANCTRL_ANY_ERR_ABORT_EN |\ | ||
97 | IOAT_CHANCTRL_ERR_INT_EN) | ||
98 | 96 | ||
99 | #define IOAT_DMA_COMP_OFFSET 0x02 /* 16-bit DMA channel compatibility */ | 97 | #define IOAT_DMA_COMP_OFFSET 0x02 /* 16-bit DMA channel compatibility */ |
100 | #define IOAT_DMA_COMP_V1 0x0001 /* Compatibility with DMA version 1 */ | 98 | #define IOAT_DMA_COMP_V1 0x0001 /* Compatibility with DMA version 1 */ |
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c index b3b065c4e5c1..034ecf0ace03 100644 --- a/drivers/dma/shdma.c +++ b/drivers/dma/shdma.c | |||
@@ -640,17 +640,16 @@ static int __init sh_dmae_probe(struct platform_device *pdev) | |||
640 | #endif | 640 | #endif |
641 | struct sh_dmae_device *shdev; | 641 | struct sh_dmae_device *shdev; |
642 | 642 | ||
643 | /* get platform data */ | ||
644 | if (!pdev->dev.platform_data) | ||
645 | return -ENODEV; | ||
646 | |||
643 | shdev = kzalloc(sizeof(struct sh_dmae_device), GFP_KERNEL); | 647 | shdev = kzalloc(sizeof(struct sh_dmae_device), GFP_KERNEL); |
644 | if (!shdev) { | 648 | if (!shdev) { |
645 | dev_err(&pdev->dev, "No enough memory\n"); | 649 | dev_err(&pdev->dev, "No enough memory\n"); |
646 | err = -ENOMEM; | 650 | return -ENOMEM; |
647 | goto shdev_err; | ||
648 | } | 651 | } |
649 | 652 | ||
650 | /* get platform data */ | ||
651 | if (!pdev->dev.platform_data) | ||
652 | goto shdev_err; | ||
653 | |||
654 | /* platform data */ | 653 | /* platform data */ |
655 | memcpy(&shdev->pdata, pdev->dev.platform_data, | 654 | memcpy(&shdev->pdata, pdev->dev.platform_data, |
656 | sizeof(struct sh_dmae_pdata)); | 655 | sizeof(struct sh_dmae_pdata)); |
@@ -722,7 +721,6 @@ eirq_err: | |||
722 | rst_err: | 721 | rst_err: |
723 | kfree(shdev); | 722 | kfree(shdev); |
724 | 723 | ||
725 | shdev_err: | ||
726 | return err; | 724 | return err; |
727 | } | 725 | } |
728 | 726 | ||
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 5d524254499e..94260aa76aa3 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -275,7 +275,7 @@ static void log_irqs(u32 evt) | |||
275 | !(evt & OHCI1394_busReset)) | 275 | !(evt & OHCI1394_busReset)) |
276 | return; | 276 | return; |
277 | 277 | ||
278 | fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt, | 278 | fw_notify("IRQ %08x%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", evt, |
279 | evt & OHCI1394_selfIDComplete ? " selfID" : "", | 279 | evt & OHCI1394_selfIDComplete ? " selfID" : "", |
280 | evt & OHCI1394_RQPkt ? " AR_req" : "", | 280 | evt & OHCI1394_RQPkt ? " AR_req" : "", |
281 | evt & OHCI1394_RSPkt ? " AR_resp" : "", | 281 | evt & OHCI1394_RSPkt ? " AR_resp" : "", |
@@ -286,6 +286,7 @@ static void log_irqs(u32 evt) | |||
286 | evt & OHCI1394_postedWriteErr ? " postedWriteErr" : "", | 286 | evt & OHCI1394_postedWriteErr ? " postedWriteErr" : "", |
287 | evt & OHCI1394_cycleTooLong ? " cycleTooLong" : "", | 287 | evt & OHCI1394_cycleTooLong ? " cycleTooLong" : "", |
288 | evt & OHCI1394_cycle64Seconds ? " cycle64Seconds" : "", | 288 | evt & OHCI1394_cycle64Seconds ? " cycle64Seconds" : "", |
289 | evt & OHCI1394_cycleInconsistent ? " cycleInconsistent" : "", | ||
289 | evt & OHCI1394_regAccessFail ? " regAccessFail" : "", | 290 | evt & OHCI1394_regAccessFail ? " regAccessFail" : "", |
290 | evt & OHCI1394_busReset ? " busReset" : "", | 291 | evt & OHCI1394_busReset ? " busReset" : "", |
291 | evt & ~(OHCI1394_selfIDComplete | OHCI1394_RQPkt | | 292 | evt & ~(OHCI1394_selfIDComplete | OHCI1394_RQPkt | |
@@ -293,6 +294,7 @@ static void log_irqs(u32 evt) | |||
293 | OHCI1394_respTxComplete | OHCI1394_isochRx | | 294 | OHCI1394_respTxComplete | OHCI1394_isochRx | |
294 | OHCI1394_isochTx | OHCI1394_postedWriteErr | | 295 | OHCI1394_isochTx | OHCI1394_postedWriteErr | |
295 | OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds | | 296 | OHCI1394_cycleTooLong | OHCI1394_cycle64Seconds | |
297 | OHCI1394_cycleInconsistent | | ||
296 | OHCI1394_regAccessFail | OHCI1394_busReset) | 298 | OHCI1394_regAccessFail | OHCI1394_busReset) |
297 | ? " ?" : ""); | 299 | ? " ?" : ""); |
298 | } | 300 | } |
@@ -1439,6 +1441,17 @@ static irqreturn_t irq_handler(int irq, void *data) | |||
1439 | OHCI1394_LinkControl_cycleMaster); | 1441 | OHCI1394_LinkControl_cycleMaster); |
1440 | } | 1442 | } |
1441 | 1443 | ||
1444 | if (unlikely(event & OHCI1394_cycleInconsistent)) { | ||
1445 | /* | ||
1446 | * We need to clear this event bit in order to make | ||
1447 | * cycleMatch isochronous I/O work. In theory we should | ||
1448 | * stop active cycleMatch iso contexts now and restart | ||
1449 | * them at least two cycles later. (FIXME?) | ||
1450 | */ | ||
1451 | if (printk_ratelimit()) | ||
1452 | fw_notify("isochronous cycle inconsistent\n"); | ||
1453 | } | ||
1454 | |||
1442 | if (event & OHCI1394_cycle64Seconds) { | 1455 | if (event & OHCI1394_cycle64Seconds) { |
1443 | cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer); | 1456 | cycle_time = reg_read(ohci, OHCI1394_IsochronousCycleTimer); |
1444 | if ((cycle_time & 0x80000000) == 0) | 1457 | if ((cycle_time & 0x80000000) == 0) |
@@ -1528,6 +1541,7 @@ static int ohci_enable(struct fw_card *card, u32 *config_rom, size_t length) | |||
1528 | OHCI1394_reqTxComplete | OHCI1394_respTxComplete | | 1541 | OHCI1394_reqTxComplete | OHCI1394_respTxComplete | |
1529 | OHCI1394_isochRx | OHCI1394_isochTx | | 1542 | OHCI1394_isochRx | OHCI1394_isochTx | |
1530 | OHCI1394_postedWriteErr | OHCI1394_cycleTooLong | | 1543 | OHCI1394_postedWriteErr | OHCI1394_cycleTooLong | |
1544 | OHCI1394_cycleInconsistent | | ||
1531 | OHCI1394_cycle64Seconds | OHCI1394_regAccessFail | | 1545 | OHCI1394_cycle64Seconds | OHCI1394_regAccessFail | |
1532 | OHCI1394_masterIntEnable); | 1546 | OHCI1394_masterIntEnable); |
1533 | if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) | 1547 | if (param_debug & OHCI_PARAM_DEBUG_BUSRESETS) |
@@ -1890,15 +1904,30 @@ static int handle_it_packet(struct context *context, | |||
1890 | { | 1904 | { |
1891 | struct iso_context *ctx = | 1905 | struct iso_context *ctx = |
1892 | container_of(context, struct iso_context, context); | 1906 | container_of(context, struct iso_context, context); |
1907 | int i; | ||
1908 | struct descriptor *pd; | ||
1893 | 1909 | ||
1894 | if (last->transfer_status == 0) | 1910 | for (pd = d; pd <= last; pd++) |
1895 | /* This descriptor isn't done yet, stop iteration. */ | 1911 | if (pd->transfer_status) |
1912 | break; | ||
1913 | if (pd > last) | ||
1914 | /* Descriptor(s) not done yet, stop iteration */ | ||
1896 | return 0; | 1915 | return 0; |
1897 | 1916 | ||
1898 | if (le16_to_cpu(last->control) & DESCRIPTOR_IRQ_ALWAYS) | 1917 | i = ctx->header_length; |
1918 | if (i + 4 < PAGE_SIZE) { | ||
1919 | /* Present this value as big-endian to match the receive code */ | ||
1920 | *(__be32 *)(ctx->header + i) = cpu_to_be32( | ||
1921 | ((u32)le16_to_cpu(pd->transfer_status) << 16) | | ||
1922 | le16_to_cpu(pd->res_count)); | ||
1923 | ctx->header_length += 4; | ||
1924 | } | ||
1925 | if (le16_to_cpu(last->control) & DESCRIPTOR_IRQ_ALWAYS) { | ||
1899 | ctx->base.callback(&ctx->base, le16_to_cpu(last->res_count), | 1926 | ctx->base.callback(&ctx->base, le16_to_cpu(last->res_count), |
1900 | 0, NULL, ctx->base.callback_data); | 1927 | ctx->header_length, ctx->header, |
1901 | 1928 | ctx->base.callback_data); | |
1929 | ctx->header_length = 0; | ||
1930 | } | ||
1902 | return 1; | 1931 | return 1; |
1903 | } | 1932 | } |
1904 | 1933 | ||
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index f831ea159291..96eddd17e050 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig | |||
@@ -92,6 +92,7 @@ config DRM_I830 | |||
92 | config DRM_I915 | 92 | config DRM_I915 |
93 | tristate "i915 driver" | 93 | tristate "i915 driver" |
94 | depends on AGP_INTEL | 94 | depends on AGP_INTEL |
95 | select SHMEM | ||
95 | select DRM_KMS_HELPER | 96 | select DRM_KMS_HELPER |
96 | select FB_CFB_FILLRECT | 97 | select FB_CFB_FILLRECT |
97 | select FB_CFB_COPYAREA | 98 | select FB_CFB_COPYAREA |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index cea665d86dd3..b54ba63d506e 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -662,6 +662,12 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, | |||
662 | return NULL; | 662 | return NULL; |
663 | } | 663 | } |
664 | 664 | ||
665 | /* Some EDIDs have bogus h/vtotal values */ | ||
666 | if (mode->hsync_end > mode->htotal) | ||
667 | mode->htotal = mode->hsync_end + 1; | ||
668 | if (mode->vsync_end > mode->vtotal) | ||
669 | mode->vtotal = mode->vsync_end + 1; | ||
670 | |||
665 | drm_mode_set_name(mode); | 671 | drm_mode_set_name(mode); |
666 | 672 | ||
667 | if (pt->misc & DRM_EDID_PT_INTERLACED) | 673 | if (pt->misc & DRM_EDID_PT_INTERLACED) |
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index dc8e374a0b55..65ef011fa8ba 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -599,7 +599,7 @@ int drm_fb_helper_check_var(struct fb_var_screeninfo *var, | |||
599 | struct drm_framebuffer *fb = fb_helper->fb; | 599 | struct drm_framebuffer *fb = fb_helper->fb; |
600 | int depth; | 600 | int depth; |
601 | 601 | ||
602 | if (var->pixclock == -1 || !var->pixclock) | 602 | if (var->pixclock != 0) |
603 | return -EINVAL; | 603 | return -EINVAL; |
604 | 604 | ||
605 | /* Need to resize the fb object !!! */ | 605 | /* Need to resize the fb object !!! */ |
@@ -691,7 +691,7 @@ int drm_fb_helper_set_par(struct fb_info *info) | |||
691 | int ret; | 691 | int ret; |
692 | int i; | 692 | int i; |
693 | 693 | ||
694 | if (var->pixclock != -1) { | 694 | if (var->pixclock != 0) { |
695 | DRM_ERROR("PIXEL CLCOK SET\n"); | 695 | DRM_ERROR("PIXEL CLCOK SET\n"); |
696 | return -EINVAL; | 696 | return -EINVAL; |
697 | } | 697 | } |
@@ -904,7 +904,7 @@ int drm_fb_helper_single_fb_probe(struct drm_device *dev, | |||
904 | fb_helper->fb = fb; | 904 | fb_helper->fb = fb; |
905 | 905 | ||
906 | if (new_fb) { | 906 | if (new_fb) { |
907 | info->var.pixclock = -1; | 907 | info->var.pixclock = 0; |
908 | if (register_framebuffer(info) < 0) | 908 | if (register_framebuffer(info) < 0) |
909 | return -EINVAL; | 909 | return -EINVAL; |
910 | } else { | 910 | } else { |
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c index 80391995bdec..e9dbb481c469 100644 --- a/drivers/gpu/drm/drm_gem.c +++ b/drivers/gpu/drm/drm_gem.c | |||
@@ -552,7 +552,7 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) | |||
552 | vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND; | 552 | vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND; |
553 | vma->vm_ops = obj->dev->driver->gem_vm_ops; | 553 | vma->vm_ops = obj->dev->driver->gem_vm_ops; |
554 | vma->vm_private_data = map->handle; | 554 | vma->vm_private_data = map->handle; |
555 | vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); | 555 | vma->vm_page_prot = pgprot_writecombine(vm_get_page_prot(vma->vm_flags)); |
556 | 556 | ||
557 | /* Take a ref for this mapping of the object, so that the fault | 557 | /* Take a ref for this mapping of the object, so that the fault |
558 | * handler can dereference the mmap offset's pointer to the object. | 558 | * handler can dereference the mmap offset's pointer to the object. |
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index c861d80fd779..97dc5a4f0de4 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c | |||
@@ -103,6 +103,11 @@ static struct drm_mm_node *drm_mm_kmalloc(struct drm_mm *mm, int atomic) | |||
103 | return child; | 103 | return child; |
104 | } | 104 | } |
105 | 105 | ||
106 | /* drm_mm_pre_get() - pre allocate drm_mm_node structure | ||
107 | * drm_mm: memory manager struct we are pre-allocating for | ||
108 | * | ||
109 | * Returns 0 on success or -ENOMEM if allocation fails. | ||
110 | */ | ||
106 | int drm_mm_pre_get(struct drm_mm *mm) | 111 | int drm_mm_pre_get(struct drm_mm *mm) |
107 | { | 112 | { |
108 | struct drm_mm_node *node; | 113 | struct drm_mm_node *node; |
@@ -253,12 +258,14 @@ void drm_mm_put_block(struct drm_mm_node *cur) | |||
253 | prev_node->size += next_node->size; | 258 | prev_node->size += next_node->size; |
254 | list_del(&next_node->ml_entry); | 259 | list_del(&next_node->ml_entry); |
255 | list_del(&next_node->fl_entry); | 260 | list_del(&next_node->fl_entry); |
261 | spin_lock(&mm->unused_lock); | ||
256 | if (mm->num_unused < MM_UNUSED_TARGET) { | 262 | if (mm->num_unused < MM_UNUSED_TARGET) { |
257 | list_add(&next_node->fl_entry, | 263 | list_add(&next_node->fl_entry, |
258 | &mm->unused_nodes); | 264 | &mm->unused_nodes); |
259 | ++mm->num_unused; | 265 | ++mm->num_unused; |
260 | } else | 266 | } else |
261 | kfree(next_node); | 267 | kfree(next_node); |
268 | spin_unlock(&mm->unused_lock); | ||
262 | } else { | 269 | } else { |
263 | next_node->size += cur->size; | 270 | next_node->size += cur->size; |
264 | next_node->start = cur->start; | 271 | next_node->start = cur->start; |
@@ -271,11 +278,13 @@ void drm_mm_put_block(struct drm_mm_node *cur) | |||
271 | list_add(&cur->fl_entry, &mm->fl_entry); | 278 | list_add(&cur->fl_entry, &mm->fl_entry); |
272 | } else { | 279 | } else { |
273 | list_del(&cur->ml_entry); | 280 | list_del(&cur->ml_entry); |
281 | spin_lock(&mm->unused_lock); | ||
274 | if (mm->num_unused < MM_UNUSED_TARGET) { | 282 | if (mm->num_unused < MM_UNUSED_TARGET) { |
275 | list_add(&cur->fl_entry, &mm->unused_nodes); | 283 | list_add(&cur->fl_entry, &mm->unused_nodes); |
276 | ++mm->num_unused; | 284 | ++mm->num_unused; |
277 | } else | 285 | } else |
278 | kfree(cur); | 286 | kfree(cur); |
287 | spin_unlock(&mm->unused_lock); | ||
279 | } | 288 | } |
280 | } | 289 | } |
281 | 290 | ||
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index f8ce9a3a420d..26bf0552b3cb 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -267,10 +267,10 @@ static void i915_dump_pages(struct seq_file *m, struct page **pages, int page_co | |||
267 | uint32_t *mem; | 267 | uint32_t *mem; |
268 | 268 | ||
269 | for (page = 0; page < page_count; page++) { | 269 | for (page = 0; page < page_count; page++) { |
270 | mem = kmap(pages[page]); | 270 | mem = kmap_atomic(pages[page], KM_USER0); |
271 | for (i = 0; i < PAGE_SIZE; i += 4) | 271 | for (i = 0; i < PAGE_SIZE; i += 4) |
272 | seq_printf(m, "%08x : %08x\n", i, mem[i / 4]); | 272 | seq_printf(m, "%08x : %08x\n", i, mem[i / 4]); |
273 | kunmap(pages[page]); | 273 | kunmap_atomic(pages[page], KM_USER0); |
274 | } | 274 | } |
275 | } | 275 | } |
276 | 276 | ||
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 57204e298975..a725f6591192 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -296,6 +296,7 @@ typedef struct drm_i915_private { | |||
296 | u32 saveVBLANK_A; | 296 | u32 saveVBLANK_A; |
297 | u32 saveVSYNC_A; | 297 | u32 saveVSYNC_A; |
298 | u32 saveBCLRPAT_A; | 298 | u32 saveBCLRPAT_A; |
299 | u32 saveTRANSACONF; | ||
299 | u32 saveTRANS_HTOTAL_A; | 300 | u32 saveTRANS_HTOTAL_A; |
300 | u32 saveTRANS_HBLANK_A; | 301 | u32 saveTRANS_HBLANK_A; |
301 | u32 saveTRANS_HSYNC_A; | 302 | u32 saveTRANS_HSYNC_A; |
@@ -326,6 +327,7 @@ typedef struct drm_i915_private { | |||
326 | u32 saveVBLANK_B; | 327 | u32 saveVBLANK_B; |
327 | u32 saveVSYNC_B; | 328 | u32 saveVSYNC_B; |
328 | u32 saveBCLRPAT_B; | 329 | u32 saveBCLRPAT_B; |
330 | u32 saveTRANSBCONF; | ||
329 | u32 saveTRANS_HTOTAL_B; | 331 | u32 saveTRANS_HTOTAL_B; |
330 | u32 saveTRANS_HBLANK_B; | 332 | u32 saveTRANS_HBLANK_B; |
331 | u32 saveTRANS_HSYNC_B; | 333 | u32 saveTRANS_HSYNC_B; |
@@ -414,6 +416,16 @@ typedef struct drm_i915_private { | |||
414 | u32 savePFB_WIN_SZ; | 416 | u32 savePFB_WIN_SZ; |
415 | u32 savePFA_WIN_POS; | 417 | u32 savePFA_WIN_POS; |
416 | u32 savePFB_WIN_POS; | 418 | u32 savePFB_WIN_POS; |
419 | u32 savePCH_DREF_CONTROL; | ||
420 | u32 saveDISP_ARB_CTL; | ||
421 | u32 savePIPEA_DATA_M1; | ||
422 | u32 savePIPEA_DATA_N1; | ||
423 | u32 savePIPEA_LINK_M1; | ||
424 | u32 savePIPEA_LINK_N1; | ||
425 | u32 savePIPEB_DATA_M1; | ||
426 | u32 savePIPEB_DATA_N1; | ||
427 | u32 savePIPEB_LINK_M1; | ||
428 | u32 savePIPEB_LINK_N1; | ||
417 | 429 | ||
418 | struct { | 430 | struct { |
419 | struct drm_mm gtt_space; | 431 | struct drm_mm gtt_space; |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index c3ceffa46ea0..aa7fd82aa6eb 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -254,10 +254,15 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev) | |||
254 | { | 254 | { |
255 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 255 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
256 | int ret = IRQ_NONE; | 256 | int ret = IRQ_NONE; |
257 | u32 de_iir, gt_iir; | 257 | u32 de_iir, gt_iir, de_ier; |
258 | u32 new_de_iir, new_gt_iir; | 258 | u32 new_de_iir, new_gt_iir; |
259 | struct drm_i915_master_private *master_priv; | 259 | struct drm_i915_master_private *master_priv; |
260 | 260 | ||
261 | /* disable master interrupt before clearing iir */ | ||
262 | de_ier = I915_READ(DEIER); | ||
263 | I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); | ||
264 | (void)I915_READ(DEIER); | ||
265 | |||
261 | de_iir = I915_READ(DEIIR); | 266 | de_iir = I915_READ(DEIIR); |
262 | gt_iir = I915_READ(GTIIR); | 267 | gt_iir = I915_READ(GTIIR); |
263 | 268 | ||
@@ -290,6 +295,9 @@ irqreturn_t igdng_irq_handler(struct drm_device *dev) | |||
290 | gt_iir = new_gt_iir; | 295 | gt_iir = new_gt_iir; |
291 | } | 296 | } |
292 | 297 | ||
298 | I915_WRITE(DEIER, de_ier); | ||
299 | (void)I915_READ(DEIER); | ||
300 | |||
293 | return ret; | 301 | return ret; |
294 | } | 302 | } |
295 | 303 | ||
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 992d5617e798..6eec8171a44e 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -239,6 +239,11 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
239 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | 239 | if (drm_core_check_feature(dev, DRIVER_MODESET)) |
240 | return; | 240 | return; |
241 | 241 | ||
242 | if (IS_IGDNG(dev)) { | ||
243 | dev_priv->savePCH_DREF_CONTROL = I915_READ(PCH_DREF_CONTROL); | ||
244 | dev_priv->saveDISP_ARB_CTL = I915_READ(DISP_ARB_CTL); | ||
245 | } | ||
246 | |||
242 | /* Pipe & plane A info */ | 247 | /* Pipe & plane A info */ |
243 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); | 248 | dev_priv->savePIPEACONF = I915_READ(PIPEACONF); |
244 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); | 249 | dev_priv->savePIPEASRC = I915_READ(PIPEASRC); |
@@ -263,6 +268,11 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
263 | dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); | 268 | dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A); |
264 | 269 | ||
265 | if (IS_IGDNG(dev)) { | 270 | if (IS_IGDNG(dev)) { |
271 | dev_priv->savePIPEA_DATA_M1 = I915_READ(PIPEA_DATA_M1); | ||
272 | dev_priv->savePIPEA_DATA_N1 = I915_READ(PIPEA_DATA_N1); | ||
273 | dev_priv->savePIPEA_LINK_M1 = I915_READ(PIPEA_LINK_M1); | ||
274 | dev_priv->savePIPEA_LINK_N1 = I915_READ(PIPEA_LINK_N1); | ||
275 | |||
266 | dev_priv->saveFDI_TXA_CTL = I915_READ(FDI_TXA_CTL); | 276 | dev_priv->saveFDI_TXA_CTL = I915_READ(FDI_TXA_CTL); |
267 | dev_priv->saveFDI_RXA_CTL = I915_READ(FDI_RXA_CTL); | 277 | dev_priv->saveFDI_RXA_CTL = I915_READ(FDI_RXA_CTL); |
268 | 278 | ||
@@ -270,6 +280,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
270 | dev_priv->savePFA_WIN_SZ = I915_READ(PFA_WIN_SZ); | 280 | dev_priv->savePFA_WIN_SZ = I915_READ(PFA_WIN_SZ); |
271 | dev_priv->savePFA_WIN_POS = I915_READ(PFA_WIN_POS); | 281 | dev_priv->savePFA_WIN_POS = I915_READ(PFA_WIN_POS); |
272 | 282 | ||
283 | dev_priv->saveTRANSACONF = I915_READ(TRANSACONF); | ||
273 | dev_priv->saveTRANS_HTOTAL_A = I915_READ(TRANS_HTOTAL_A); | 284 | dev_priv->saveTRANS_HTOTAL_A = I915_READ(TRANS_HTOTAL_A); |
274 | dev_priv->saveTRANS_HBLANK_A = I915_READ(TRANS_HBLANK_A); | 285 | dev_priv->saveTRANS_HBLANK_A = I915_READ(TRANS_HBLANK_A); |
275 | dev_priv->saveTRANS_HSYNC_A = I915_READ(TRANS_HSYNC_A); | 286 | dev_priv->saveTRANS_HSYNC_A = I915_READ(TRANS_HSYNC_A); |
@@ -314,6 +325,11 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
314 | dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B); | 325 | dev_priv->saveBCLRPAT_B = I915_READ(BCLRPAT_B); |
315 | 326 | ||
316 | if (IS_IGDNG(dev)) { | 327 | if (IS_IGDNG(dev)) { |
328 | dev_priv->savePIPEB_DATA_M1 = I915_READ(PIPEB_DATA_M1); | ||
329 | dev_priv->savePIPEB_DATA_N1 = I915_READ(PIPEB_DATA_N1); | ||
330 | dev_priv->savePIPEB_LINK_M1 = I915_READ(PIPEB_LINK_M1); | ||
331 | dev_priv->savePIPEB_LINK_N1 = I915_READ(PIPEB_LINK_N1); | ||
332 | |||
317 | dev_priv->saveFDI_TXB_CTL = I915_READ(FDI_TXB_CTL); | 333 | dev_priv->saveFDI_TXB_CTL = I915_READ(FDI_TXB_CTL); |
318 | dev_priv->saveFDI_RXB_CTL = I915_READ(FDI_RXB_CTL); | 334 | dev_priv->saveFDI_RXB_CTL = I915_READ(FDI_RXB_CTL); |
319 | 335 | ||
@@ -321,6 +337,7 @@ static void i915_save_modeset_reg(struct drm_device *dev) | |||
321 | dev_priv->savePFB_WIN_SZ = I915_READ(PFB_WIN_SZ); | 337 | dev_priv->savePFB_WIN_SZ = I915_READ(PFB_WIN_SZ); |
322 | dev_priv->savePFB_WIN_POS = I915_READ(PFB_WIN_POS); | 338 | dev_priv->savePFB_WIN_POS = I915_READ(PFB_WIN_POS); |
323 | 339 | ||
340 | dev_priv->saveTRANSBCONF = I915_READ(TRANSBCONF); | ||
324 | dev_priv->saveTRANS_HTOTAL_B = I915_READ(TRANS_HTOTAL_B); | 341 | dev_priv->saveTRANS_HTOTAL_B = I915_READ(TRANS_HTOTAL_B); |
325 | dev_priv->saveTRANS_HBLANK_B = I915_READ(TRANS_HBLANK_B); | 342 | dev_priv->saveTRANS_HBLANK_B = I915_READ(TRANS_HBLANK_B); |
326 | dev_priv->saveTRANS_HSYNC_B = I915_READ(TRANS_HSYNC_B); | 343 | dev_priv->saveTRANS_HSYNC_B = I915_READ(TRANS_HSYNC_B); |
@@ -368,6 +385,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
368 | fpb1_reg = FPB1; | 385 | fpb1_reg = FPB1; |
369 | } | 386 | } |
370 | 387 | ||
388 | if (IS_IGDNG(dev)) { | ||
389 | I915_WRITE(PCH_DREF_CONTROL, dev_priv->savePCH_DREF_CONTROL); | ||
390 | I915_WRITE(DISP_ARB_CTL, dev_priv->saveDISP_ARB_CTL); | ||
391 | } | ||
392 | |||
371 | /* Pipe & plane A info */ | 393 | /* Pipe & plane A info */ |
372 | /* Prime the clock */ | 394 | /* Prime the clock */ |
373 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { | 395 | if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) { |
@@ -395,6 +417,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
395 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); | 417 | I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A); |
396 | 418 | ||
397 | if (IS_IGDNG(dev)) { | 419 | if (IS_IGDNG(dev)) { |
420 | I915_WRITE(PIPEA_DATA_M1, dev_priv->savePIPEA_DATA_M1); | ||
421 | I915_WRITE(PIPEA_DATA_N1, dev_priv->savePIPEA_DATA_N1); | ||
422 | I915_WRITE(PIPEA_LINK_M1, dev_priv->savePIPEA_LINK_M1); | ||
423 | I915_WRITE(PIPEA_LINK_N1, dev_priv->savePIPEA_LINK_N1); | ||
424 | |||
398 | I915_WRITE(FDI_RXA_CTL, dev_priv->saveFDI_RXA_CTL); | 425 | I915_WRITE(FDI_RXA_CTL, dev_priv->saveFDI_RXA_CTL); |
399 | I915_WRITE(FDI_TXA_CTL, dev_priv->saveFDI_TXA_CTL); | 426 | I915_WRITE(FDI_TXA_CTL, dev_priv->saveFDI_TXA_CTL); |
400 | 427 | ||
@@ -402,6 +429,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
402 | I915_WRITE(PFA_WIN_SZ, dev_priv->savePFA_WIN_SZ); | 429 | I915_WRITE(PFA_WIN_SZ, dev_priv->savePFA_WIN_SZ); |
403 | I915_WRITE(PFA_WIN_POS, dev_priv->savePFA_WIN_POS); | 430 | I915_WRITE(PFA_WIN_POS, dev_priv->savePFA_WIN_POS); |
404 | 431 | ||
432 | I915_WRITE(TRANSACONF, dev_priv->saveTRANSACONF); | ||
405 | I915_WRITE(TRANS_HTOTAL_A, dev_priv->saveTRANS_HTOTAL_A); | 433 | I915_WRITE(TRANS_HTOTAL_A, dev_priv->saveTRANS_HTOTAL_A); |
406 | I915_WRITE(TRANS_HBLANK_A, dev_priv->saveTRANS_HBLANK_A); | 434 | I915_WRITE(TRANS_HBLANK_A, dev_priv->saveTRANS_HBLANK_A); |
407 | I915_WRITE(TRANS_HSYNC_A, dev_priv->saveTRANS_HSYNC_A); | 435 | I915_WRITE(TRANS_HSYNC_A, dev_priv->saveTRANS_HSYNC_A); |
@@ -439,7 +467,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
439 | /* Actually enable it */ | 467 | /* Actually enable it */ |
440 | I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B); | 468 | I915_WRITE(dpll_b_reg, dev_priv->saveDPLL_B); |
441 | DRM_UDELAY(150); | 469 | DRM_UDELAY(150); |
442 | if (IS_I965G(dev)) | 470 | if (IS_I965G(dev) && !IS_IGDNG(dev)) |
443 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); | 471 | I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD); |
444 | DRM_UDELAY(150); | 472 | DRM_UDELAY(150); |
445 | 473 | ||
@@ -454,6 +482,11 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
454 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); | 482 | I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B); |
455 | 483 | ||
456 | if (IS_IGDNG(dev)) { | 484 | if (IS_IGDNG(dev)) { |
485 | I915_WRITE(PIPEB_DATA_M1, dev_priv->savePIPEB_DATA_M1); | ||
486 | I915_WRITE(PIPEB_DATA_N1, dev_priv->savePIPEB_DATA_N1); | ||
487 | I915_WRITE(PIPEB_LINK_M1, dev_priv->savePIPEB_LINK_M1); | ||
488 | I915_WRITE(PIPEB_LINK_N1, dev_priv->savePIPEB_LINK_N1); | ||
489 | |||
457 | I915_WRITE(FDI_RXB_CTL, dev_priv->saveFDI_RXB_CTL); | 490 | I915_WRITE(FDI_RXB_CTL, dev_priv->saveFDI_RXB_CTL); |
458 | I915_WRITE(FDI_TXB_CTL, dev_priv->saveFDI_TXB_CTL); | 491 | I915_WRITE(FDI_TXB_CTL, dev_priv->saveFDI_TXB_CTL); |
459 | 492 | ||
@@ -461,6 +494,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
461 | I915_WRITE(PFB_WIN_SZ, dev_priv->savePFB_WIN_SZ); | 494 | I915_WRITE(PFB_WIN_SZ, dev_priv->savePFB_WIN_SZ); |
462 | I915_WRITE(PFB_WIN_POS, dev_priv->savePFB_WIN_POS); | 495 | I915_WRITE(PFB_WIN_POS, dev_priv->savePFB_WIN_POS); |
463 | 496 | ||
497 | I915_WRITE(TRANSBCONF, dev_priv->saveTRANSBCONF); | ||
464 | I915_WRITE(TRANS_HTOTAL_B, dev_priv->saveTRANS_HTOTAL_B); | 498 | I915_WRITE(TRANS_HTOTAL_B, dev_priv->saveTRANS_HTOTAL_B); |
465 | I915_WRITE(TRANS_HBLANK_B, dev_priv->saveTRANS_HBLANK_B); | 499 | I915_WRITE(TRANS_HBLANK_B, dev_priv->saveTRANS_HBLANK_B); |
466 | I915_WRITE(TRANS_HSYNC_B, dev_priv->saveTRANS_HSYNC_B); | 500 | I915_WRITE(TRANS_HSYNC_B, dev_priv->saveTRANS_HSYNC_B); |
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 212e22740fc1..e5051446c48e 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c | |||
@@ -262,8 +262,8 @@ static bool intel_crt_detect_hotplug(struct drm_connector *connector) | |||
262 | } while (time_after(timeout, jiffies)); | 262 | } while (time_after(timeout, jiffies)); |
263 | } | 263 | } |
264 | 264 | ||
265 | if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) == | 265 | if ((I915_READ(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) != |
266 | CRT_HOTPLUG_MONITOR_COLOR) | 266 | CRT_HOTPLUG_MONITOR_NONE) |
267 | return true; | 267 | return true; |
268 | 268 | ||
269 | return false; | 269 | return false; |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3ba6546b7c7f..099f420de57a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -863,10 +863,8 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
863 | struct drm_device *dev = crtc->dev; | 863 | struct drm_device *dev = crtc->dev; |
864 | struct drm_i915_private *dev_priv = dev->dev_private; | 864 | struct drm_i915_private *dev_priv = dev->dev_private; |
865 | intel_clock_t clock; | 865 | intel_clock_t clock; |
866 | int max_n; | ||
867 | bool found; | ||
868 | int err_most = 47; | 866 | int err_most = 47; |
869 | found = false; | 867 | int err_min = 10000; |
870 | 868 | ||
871 | /* eDP has only 2 clock choice, no n/m/p setting */ | 869 | /* eDP has only 2 clock choice, no n/m/p setting */ |
872 | if (HAS_eDP) | 870 | if (HAS_eDP) |
@@ -890,10 +888,9 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
890 | } | 888 | } |
891 | 889 | ||
892 | memset(best_clock, 0, sizeof(*best_clock)); | 890 | memset(best_clock, 0, sizeof(*best_clock)); |
893 | max_n = limit->n.max; | ||
894 | for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) { | 891 | for (clock.p1 = limit->p1.max; clock.p1 >= limit->p1.min; clock.p1--) { |
895 | /* based on hardware requriment prefer smaller n to precision */ | 892 | /* based on hardware requriment prefer smaller n to precision */ |
896 | for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { | 893 | for (clock.n = limit->n.min; clock.n <= limit->n.max; clock.n++) { |
897 | /* based on hardware requirment prefere larger m1,m2 */ | 894 | /* based on hardware requirment prefere larger m1,m2 */ |
898 | for (clock.m1 = limit->m1.max; | 895 | for (clock.m1 = limit->m1.max; |
899 | clock.m1 >= limit->m1.min; clock.m1--) { | 896 | clock.m1 >= limit->m1.min; clock.m1--) { |
@@ -907,18 +904,18 @@ intel_igdng_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
907 | this_err = abs((10000 - (target*10000/clock.dot))); | 904 | this_err = abs((10000 - (target*10000/clock.dot))); |
908 | if (this_err < err_most) { | 905 | if (this_err < err_most) { |
909 | *best_clock = clock; | 906 | *best_clock = clock; |
910 | err_most = this_err; | ||
911 | max_n = clock.n; | ||
912 | found = true; | ||
913 | /* found on first matching */ | 907 | /* found on first matching */ |
914 | goto out; | 908 | goto out; |
909 | } else if (this_err < err_min) { | ||
910 | *best_clock = clock; | ||
911 | err_min = this_err; | ||
915 | } | 912 | } |
916 | } | 913 | } |
917 | } | 914 | } |
918 | } | 915 | } |
919 | } | 916 | } |
920 | out: | 917 | out: |
921 | return found; | 918 | return true; |
922 | } | 919 | } |
923 | 920 | ||
924 | /* DisplayPort has only two frequencies, 162MHz and 270MHz */ | 921 | /* DisplayPort has only two frequencies, 162MHz and 270MHz */ |
diff --git a/drivers/gpu/drm/i915/intel_hdmi.c b/drivers/gpu/drm/i915/intel_hdmi.c index 663ab6de0b58..c33451aec1bd 100644 --- a/drivers/gpu/drm/i915/intel_hdmi.c +++ b/drivers/gpu/drm/i915/intel_hdmi.c | |||
@@ -77,14 +77,32 @@ static void intel_hdmi_dpms(struct drm_encoder *encoder, int mode) | |||
77 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; | 77 | struct intel_hdmi_priv *hdmi_priv = intel_output->dev_priv; |
78 | u32 temp; | 78 | u32 temp; |
79 | 79 | ||
80 | if (mode != DRM_MODE_DPMS_ON) { | 80 | temp = I915_READ(hdmi_priv->sdvox_reg); |
81 | temp = I915_READ(hdmi_priv->sdvox_reg); | 81 | |
82 | /* HW workaround, need to toggle enable bit off and on for 12bpc, but | ||
83 | * we do this anyway which shows more stable in testing. | ||
84 | */ | ||
85 | if (IS_IGDNG(dev)) { | ||
82 | I915_WRITE(hdmi_priv->sdvox_reg, temp & ~SDVO_ENABLE); | 86 | I915_WRITE(hdmi_priv->sdvox_reg, temp & ~SDVO_ENABLE); |
87 | POSTING_READ(hdmi_priv->sdvox_reg); | ||
88 | } | ||
89 | |||
90 | if (mode != DRM_MODE_DPMS_ON) { | ||
91 | temp &= ~SDVO_ENABLE; | ||
83 | } else { | 92 | } else { |
84 | temp = I915_READ(hdmi_priv->sdvox_reg); | 93 | temp |= SDVO_ENABLE; |
85 | I915_WRITE(hdmi_priv->sdvox_reg, temp | SDVO_ENABLE); | ||
86 | } | 94 | } |
95 | |||
96 | I915_WRITE(hdmi_priv->sdvox_reg, temp); | ||
87 | POSTING_READ(hdmi_priv->sdvox_reg); | 97 | POSTING_READ(hdmi_priv->sdvox_reg); |
98 | |||
99 | /* HW workaround, need to write this twice for issue that may result | ||
100 | * in first write getting masked. | ||
101 | */ | ||
102 | if (IS_IGDNG(dev)) { | ||
103 | I915_WRITE(hdmi_priv->sdvox_reg, temp); | ||
104 | POSTING_READ(hdmi_priv->sdvox_reg); | ||
105 | } | ||
88 | } | 106 | } |
89 | 107 | ||
90 | static void intel_hdmi_save(struct drm_connector *connector) | 108 | static void intel_hdmi_save(struct drm_connector *connector) |
diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 901befe03da2..d67c42555ab9 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c | |||
@@ -107,6 +107,7 @@ static uint32_t atom_iio_execute(struct atom_context *ctx, int base, | |||
107 | base += 3; | 107 | base += 3; |
108 | break; | 108 | break; |
109 | case ATOM_IIO_WRITE: | 109 | case ATOM_IIO_WRITE: |
110 | (void)ctx->card->reg_read(ctx->card, CU16(base + 1)); | ||
110 | ctx->card->reg_write(ctx->card, CU16(base + 1), temp); | 111 | ctx->card->reg_write(ctx->card, CU16(base + 1), temp); |
111 | base += 3; | 112 | base += 3; |
112 | break; | 113 | break; |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 757f5cd37744..224506a2f7b1 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -519,6 +519,7 @@ typedef int (*radeon_packet3_check_t)(struct radeon_cs_parser *p, | |||
519 | * AGP | 519 | * AGP |
520 | */ | 520 | */ |
521 | int radeon_agp_init(struct radeon_device *rdev); | 521 | int radeon_agp_init(struct radeon_device *rdev); |
522 | void radeon_agp_resume(struct radeon_device *rdev); | ||
522 | void radeon_agp_fini(struct radeon_device *rdev); | 523 | void radeon_agp_fini(struct radeon_device *rdev); |
523 | 524 | ||
524 | 525 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_agp.c b/drivers/gpu/drm/radeon/radeon_agp.c index 23ea9955ac59..54bf49a6d676 100644 --- a/drivers/gpu/drm/radeon/radeon_agp.c +++ b/drivers/gpu/drm/radeon/radeon_agp.c | |||
@@ -237,6 +237,18 @@ int radeon_agp_init(struct radeon_device *rdev) | |||
237 | #endif | 237 | #endif |
238 | } | 238 | } |
239 | 239 | ||
240 | void radeon_agp_resume(struct radeon_device *rdev) | ||
241 | { | ||
242 | #if __OS_HAS_AGP | ||
243 | int r; | ||
244 | if (rdev->flags & RADEON_IS_AGP) { | ||
245 | r = radeon_agp_init(rdev); | ||
246 | if (r) | ||
247 | dev_warn(rdev->dev, "radeon AGP reinit failed\n"); | ||
248 | } | ||
249 | #endif | ||
250 | } | ||
251 | |||
240 | void radeon_agp_fini(struct radeon_device *rdev) | 252 | void radeon_agp_fini(struct radeon_device *rdev) |
241 | { | 253 | { |
242 | #if __OS_HAS_AGP | 254 | #if __OS_HAS_AGP |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index fce4c4087fda..29763ceae3af 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -566,8 +566,9 @@ static enum drm_connector_status radeon_vga_detect(struct drm_connector *connect | |||
566 | radeon_i2c_do_lock(radeon_connector, 0); | 566 | radeon_i2c_do_lock(radeon_connector, 0); |
567 | 567 | ||
568 | if (!radeon_connector->edid) { | 568 | if (!radeon_connector->edid) { |
569 | DRM_ERROR("DDC responded but not EDID found for %s\n", | 569 | DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", |
570 | drm_get_connector_name(connector)); | 570 | drm_get_connector_name(connector)); |
571 | ret = connector_status_connected; | ||
571 | } else { | 572 | } else { |
572 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); | 573 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); |
573 | 574 | ||
@@ -720,8 +721,8 @@ static enum drm_connector_status radeon_dvi_detect(struct drm_connector *connect | |||
720 | radeon_i2c_do_lock(radeon_connector, 0); | 721 | radeon_i2c_do_lock(radeon_connector, 0); |
721 | 722 | ||
722 | if (!radeon_connector->edid) { | 723 | if (!radeon_connector->edid) { |
723 | DRM_ERROR("DDC responded but not EDID found for %s\n", | 724 | DRM_ERROR("%s: probed a monitor but no|invalid EDID\n", |
724 | drm_get_connector_name(connector)); | 725 | drm_get_connector_name(connector)); |
725 | } else { | 726 | } else { |
726 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); | 727 | radeon_connector->use_digital = !!(radeon_connector->edid->input & DRM_EDID_INPUT_DIGITAL); |
727 | 728 | ||
@@ -1149,6 +1150,13 @@ radeon_add_legacy_connector(struct drm_device *dev, | |||
1149 | if (ret) | 1150 | if (ret) |
1150 | goto failed; | 1151 | goto failed; |
1151 | radeon_connector->dac_load_detect = true; | 1152 | radeon_connector->dac_load_detect = true; |
1153 | /* RS400,RC410,RS480 chipset seems to report a lot | ||
1154 | * of false positive on load detect, we haven't yet | ||
1155 | * found a way to make load detect reliable on those | ||
1156 | * chipset, thus just disable it for TV. | ||
1157 | */ | ||
1158 | if (rdev->family == CHIP_RS400 || rdev->family == CHIP_RS480) | ||
1159 | radeon_connector->dac_load_detect = false; | ||
1152 | drm_connector_attach_property(&radeon_connector->base, | 1160 | drm_connector_attach_property(&radeon_connector->base, |
1153 | rdev->mode_info.load_detect_property, | 1161 | rdev->mode_info.load_detect_property, |
1154 | 1); | 1162 | 1); |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index e3f9edfa40fe..41bb76fbe734 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -688,6 +688,8 @@ int radeon_resume_kms(struct drm_device *dev) | |||
688 | return -1; | 688 | return -1; |
689 | } | 689 | } |
690 | pci_set_master(dev->pdev); | 690 | pci_set_master(dev->pdev); |
691 | /* resume AGP if in use */ | ||
692 | radeon_agp_resume(rdev); | ||
691 | radeon_resume(rdev); | 693 | radeon_resume(rdev); |
692 | radeon_restore_bios_scratch_regs(rdev); | 694 | radeon_restore_bios_scratch_regs(rdev); |
693 | fb_set_suspend(rdev->fbdev_info, 0); | 695 | fb_set_suspend(rdev->fbdev_info, 0); |
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 7935f793bf62..ba68c9fe90a1 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
@@ -137,8 +137,6 @@ int rv515_mc_wait_for_idle(struct radeon_device *rdev) | |||
137 | 137 | ||
138 | void rv515_vga_render_disable(struct radeon_device *rdev) | 138 | void rv515_vga_render_disable(struct radeon_device *rdev) |
139 | { | 139 | { |
140 | WREG32(R_000330_D1VGA_CONTROL, 0); | ||
141 | WREG32(R_000338_D2VGA_CONTROL, 0); | ||
142 | WREG32(R_000300_VGA_RENDER_CONTROL, | 140 | WREG32(R_000300_VGA_RENDER_CONTROL, |
143 | RREG32(R_000300_VGA_RENDER_CONTROL) & C_000300_VGA_VSTATUS_CNTL); | 141 | RREG32(R_000300_VGA_RENDER_CONTROL) & C_000300_VGA_VSTATUS_CNTL); |
144 | } | 142 | } |
@@ -382,7 +380,6 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) | |||
382 | save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL); | 380 | save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL); |
383 | 381 | ||
384 | /* Stop all video */ | 382 | /* Stop all video */ |
385 | WREG32(R_000330_D1VGA_CONTROL, 0); | ||
386 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | 383 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); |
387 | WREG32(R_000300_VGA_RENDER_CONTROL, 0); | 384 | WREG32(R_000300_VGA_RENDER_CONTROL, 0); |
388 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); | 385 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); |
@@ -391,6 +388,8 @@ void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) | |||
391 | WREG32(R_006880_D2CRTC_CONTROL, 0); | 388 | WREG32(R_006880_D2CRTC_CONTROL, 0); |
392 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); | 389 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); |
393 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | 390 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); |
391 | WREG32(R_000330_D1VGA_CONTROL, 0); | ||
392 | WREG32(R_000338_D2VGA_CONTROL, 0); | ||
394 | } | 393 | } |
395 | 394 | ||
396 | void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) | 395 | void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) |
@@ -404,14 +403,14 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) | |||
404 | WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); | 403 | WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); |
405 | mdelay(1); | 404 | mdelay(1); |
406 | /* Restore video state */ | 405 | /* Restore video state */ |
406 | WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control); | ||
407 | WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control); | ||
407 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); | 408 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); |
408 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1); | 409 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1); |
409 | WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control); | 410 | WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control); |
410 | WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control); | 411 | WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control); |
411 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); | 412 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); |
412 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | 413 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); |
413 | WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control); | ||
414 | WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control); | ||
415 | WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); | 414 | WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); |
416 | } | 415 | } |
417 | 416 | ||
diff --git a/drivers/i2c/busses/i2c-pnx.c b/drivers/i2c/busses/i2c-pnx.c index 1fca59077949..fbab6846ae64 100644 --- a/drivers/i2c/busses/i2c-pnx.c +++ b/drivers/i2c/busses/i2c-pnx.c | |||
@@ -650,7 +650,7 @@ static int __devinit i2c_pnx_probe(struct platform_device *pdev) | |||
650 | return 0; | 650 | return 0; |
651 | 651 | ||
652 | out_irq: | 652 | out_irq: |
653 | free_irq(alg_data->irq, alg_data); | 653 | free_irq(alg_data->irq, i2c_pnx->adapter); |
654 | out_clock: | 654 | out_clock: |
655 | i2c_pnx->set_clock_stop(pdev); | 655 | i2c_pnx->set_clock_stop(pdev); |
656 | out_unmap: | 656 | out_unmap: |
@@ -669,7 +669,7 @@ static int __devexit i2c_pnx_remove(struct platform_device *pdev) | |||
669 | struct i2c_adapter *adap = i2c_pnx->adapter; | 669 | struct i2c_adapter *adap = i2c_pnx->adapter; |
670 | struct i2c_pnx_algo_data *alg_data = adap->algo_data; | 670 | struct i2c_pnx_algo_data *alg_data = adap->algo_data; |
671 | 671 | ||
672 | free_irq(alg_data->irq, alg_data); | 672 | free_irq(alg_data->irq, i2c_pnx->adapter); |
673 | i2c_del_adapter(adap); | 673 | i2c_del_adapter(adap); |
674 | i2c_pnx->set_clock_stop(pdev); | 674 | i2c_pnx->set_clock_stop(pdev); |
675 | iounmap((void *)alg_data->ioaddr); | 675 | iounmap((void *)alg_data->ioaddr); |
diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/i2c/chips/tsl2550.c index aa96bd2d27ea..a0702f36a72f 100644 --- a/drivers/i2c/chips/tsl2550.c +++ b/drivers/i2c/chips/tsl2550.c | |||
@@ -257,6 +257,7 @@ static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO, | |||
257 | 257 | ||
258 | static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf) | 258 | static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf) |
259 | { | 259 | { |
260 | struct tsl2550_data *data = i2c_get_clientdata(client); | ||
260 | u8 ch0, ch1; | 261 | u8 ch0, ch1; |
261 | int ret; | 262 | int ret; |
262 | 263 | ||
@@ -274,6 +275,8 @@ static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf) | |||
274 | ret = tsl2550_calculate_lux(ch0, ch1); | 275 | ret = tsl2550_calculate_lux(ch0, ch1); |
275 | if (ret < 0) | 276 | if (ret < 0) |
276 | return ret; | 277 | return ret; |
278 | if (data->operating_mode == 1) | ||
279 | ret *= 5; | ||
277 | 280 | ||
278 | return sprintf(buf, "%d\n", ret); | 281 | return sprintf(buf, "%d\n", ret); |
279 | } | 282 | } |
diff --git a/drivers/i2c/i2c-core.c b/drivers/i2c/i2c-core.c index 8d80fceca6a4..296504355142 100644 --- a/drivers/i2c/i2c-core.c +++ b/drivers/i2c/i2c-core.c | |||
@@ -762,6 +762,7 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
762 | { | 762 | { |
763 | int res = 0; | 763 | int res = 0; |
764 | struct i2c_adapter *found; | 764 | struct i2c_adapter *found; |
765 | struct i2c_client *client, *next; | ||
765 | 766 | ||
766 | /* First make sure that this adapter was ever added */ | 767 | /* First make sure that this adapter was ever added */ |
767 | mutex_lock(&core_lock); | 768 | mutex_lock(&core_lock); |
@@ -781,6 +782,16 @@ int i2c_del_adapter(struct i2c_adapter *adap) | |||
781 | if (res) | 782 | if (res) |
782 | return res; | 783 | return res; |
783 | 784 | ||
785 | /* Remove devices instantiated from sysfs */ | ||
786 | list_for_each_entry_safe(client, next, &userspace_devices, detected) { | ||
787 | if (client->adapter == adap) { | ||
788 | dev_dbg(&adap->dev, "Removing %s at 0x%x\n", | ||
789 | client->name, client->addr); | ||
790 | list_del(&client->detected); | ||
791 | i2c_unregister_device(client); | ||
792 | } | ||
793 | } | ||
794 | |||
784 | /* Detach any active clients. This can't fail, thus we do not | 795 | /* Detach any active clients. This can't fail, thus we do not |
785 | checking the returned value. */ | 796 | checking the returned value. */ |
786 | res = device_for_each_child(&adap->dev, NULL, __unregister_client); | 797 | res = device_for_each_child(&adap->dev, NULL, __unregister_client); |
diff --git a/drivers/ide/ide-ioctls.c b/drivers/ide/ide-ioctls.c index d3440b5010a5..6e7ae2b6cfc6 100644 --- a/drivers/ide/ide-ioctls.c +++ b/drivers/ide/ide-ioctls.c | |||
@@ -162,7 +162,7 @@ static int ide_cmd_ioctl(ide_drive_t *drive, unsigned long arg) | |||
162 | if (tf->command == ATA_CMD_SET_FEATURES && | 162 | if (tf->command == ATA_CMD_SET_FEATURES && |
163 | tf->feature == SETFEATURES_XFER && | 163 | tf->feature == SETFEATURES_XFER && |
164 | tf->nsect >= XFER_SW_DMA_0) { | 164 | tf->nsect >= XFER_SW_DMA_0) { |
165 | xfer_rate = ide_find_dma_mode(drive, XFER_UDMA_6); | 165 | xfer_rate = ide_find_dma_mode(drive, tf->nsect); |
166 | if (xfer_rate != tf->nsect) { | 166 | if (xfer_rate != tf->nsect) { |
167 | err = -EINVAL; | 167 | err = -EINVAL; |
168 | goto abort; | 168 | goto abort; |
diff --git a/drivers/ieee802154/fakehard.c b/drivers/ieee802154/fakehard.c index 96a2959ce877..7c544f7c74c4 100644 --- a/drivers/ieee802154/fakehard.c +++ b/drivers/ieee802154/fakehard.c | |||
@@ -260,15 +260,12 @@ static int ieee802154_fake_close(struct net_device *dev) | |||
260 | static netdev_tx_t ieee802154_fake_xmit(struct sk_buff *skb, | 260 | static netdev_tx_t ieee802154_fake_xmit(struct sk_buff *skb, |
261 | struct net_device *dev) | 261 | struct net_device *dev) |
262 | { | 262 | { |
263 | skb->iif = dev->ifindex; | ||
264 | skb->dev = dev; | ||
265 | dev->stats.tx_packets++; | 263 | dev->stats.tx_packets++; |
266 | dev->stats.tx_bytes += skb->len; | 264 | dev->stats.tx_bytes += skb->len; |
267 | 265 | ||
268 | dev->trans_start = jiffies; | ||
269 | |||
270 | /* FIXME: do hardware work here ... */ | 266 | /* FIXME: do hardware work here ... */ |
271 | 267 | ||
268 | dev_kfree_skb(skb); | ||
272 | return NETDEV_TX_OK; | 269 | return NETDEV_TX_OK; |
273 | } | 270 | } |
274 | 271 | ||
diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c index 655474b29e21..abd4791acb0e 100644 --- a/drivers/media/common/ir-functions.c +++ b/drivers/media/common/ir-functions.c | |||
@@ -64,7 +64,7 @@ void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, | |||
64 | 64 | ||
65 | ir->ir_type = ir_type; | 65 | ir->ir_type = ir_type; |
66 | 66 | ||
67 | memset(ir->ir_codes, sizeof(ir->ir_codes), 0); | 67 | memset(ir->ir_codes, 0, sizeof(ir->ir_codes)); |
68 | 68 | ||
69 | /* | 69 | /* |
70 | * FIXME: This is a temporary workaround to use the new IR tables | 70 | * FIXME: This is a temporary workaround to use the new IR tables |
diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index f65591fb7cec..2a53dd096eef 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c | |||
@@ -663,6 +663,14 @@ static struct zl10353_config cxusb_zl10353_xc3028_config = { | |||
663 | .parallel_ts = 1, | 663 | .parallel_ts = 1, |
664 | }; | 664 | }; |
665 | 665 | ||
666 | static struct zl10353_config cxusb_zl10353_xc3028_config_no_i2c_gate = { | ||
667 | .demod_address = 0x0f, | ||
668 | .if2 = 45600, | ||
669 | .no_tuner = 1, | ||
670 | .parallel_ts = 1, | ||
671 | .disable_i2c_gate_ctrl = 1, | ||
672 | }; | ||
673 | |||
666 | static struct mt352_config cxusb_mt352_xc3028_config = { | 674 | static struct mt352_config cxusb_mt352_xc3028_config = { |
667 | .demod_address = 0x0f, | 675 | .demod_address = 0x0f, |
668 | .if2 = 4560, | 676 | .if2 = 4560, |
@@ -894,7 +902,7 @@ static int cxusb_dualdig4_frontend_attach(struct dvb_usb_adapter *adap) | |||
894 | cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); | 902 | cxusb_bluebird_gpio_pulse(adap->dev, 0x02, 1); |
895 | 903 | ||
896 | if ((adap->fe = dvb_attach(zl10353_attach, | 904 | if ((adap->fe = dvb_attach(zl10353_attach, |
897 | &cxusb_zl10353_xc3028_config, | 905 | &cxusb_zl10353_xc3028_config_no_i2c_gate, |
898 | &adap->dev->i2c_adap)) == NULL) | 906 | &adap->dev->i2c_adap)) == NULL) |
899 | return -EIO; | 907 | return -EIO; |
900 | 908 | ||
diff --git a/drivers/media/dvb/siano/Kconfig b/drivers/media/dvb/siano/Kconfig index 8c1aed77ea30..85a222c4eaa0 100644 --- a/drivers/media/dvb/siano/Kconfig +++ b/drivers/media/dvb/siano/Kconfig | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | config SMS_SIANO_MDTV | 5 | config SMS_SIANO_MDTV |
6 | tristate "Siano SMS1xxx based MDTV receiver" | 6 | tristate "Siano SMS1xxx based MDTV receiver" |
7 | depends on DVB_CORE && INPUT | 7 | depends on DVB_CORE && INPUT && HAS_DMA |
8 | ---help--- | 8 | ---help--- |
9 | Choose Y or M here if you have MDTV receiver with a Siano chipset. | 9 | Choose Y or M here if you have MDTV receiver with a Siano chipset. |
10 | 10 | ||
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index c3f579de6e71..c6cf11661868 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c | |||
@@ -181,12 +181,10 @@ static void gemtek_pci_mute(struct gemtek_pci *card) | |||
181 | 181 | ||
182 | static void gemtek_pci_unmute(struct gemtek_pci *card) | 182 | static void gemtek_pci_unmute(struct gemtek_pci *card) |
183 | { | 183 | { |
184 | mutex_lock(&card->lock); | ||
185 | if (card->mute) { | 184 | if (card->mute) { |
186 | gemtek_pci_setfrequency(card, card->current_frequency); | 185 | gemtek_pci_setfrequency(card, card->current_frequency); |
187 | card->mute = false; | 186 | card->mute = false; |
188 | } | 187 | } |
189 | mutex_unlock(&card->lock); | ||
190 | } | 188 | } |
191 | 189 | ||
192 | static int gemtek_pci_getsignal(struct gemtek_pci *card) | 190 | static int gemtek_pci_getsignal(struct gemtek_pci *card) |
diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c index c015da813dda..d14cfb200ed0 100644 --- a/drivers/media/video/davinci/vpif_display.c +++ b/drivers/media/video/davinci/vpif_display.c | |||
@@ -1426,7 +1426,6 @@ static __init int vpif_probe(struct platform_device *pdev) | |||
1426 | struct vpif_display_config *config; | 1426 | struct vpif_display_config *config; |
1427 | int i, j = 0, k, q, m, err = 0; | 1427 | int i, j = 0, k, q, m, err = 0; |
1428 | struct i2c_adapter *i2c_adap; | 1428 | struct i2c_adapter *i2c_adap; |
1429 | struct vpif_config *config; | ||
1430 | struct common_obj *common; | 1429 | struct common_obj *common; |
1431 | struct channel_obj *ch; | 1430 | struct channel_obj *ch; |
1432 | struct video_device *vfd; | 1431 | struct video_device *vfd; |
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index bdb249bd9d5d..c0fd5c6feeac 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c | |||
@@ -1584,8 +1584,8 @@ struct em28xx_board em28xx_boards[] = { | |||
1584 | [EM2870_BOARD_REDDO_DVB_C_USB_BOX] = { | 1584 | [EM2870_BOARD_REDDO_DVB_C_USB_BOX] = { |
1585 | .name = "Reddo DVB-C USB TV Box", | 1585 | .name = "Reddo DVB-C USB TV Box", |
1586 | .tuner_type = TUNER_ABSENT, | 1586 | .tuner_type = TUNER_ABSENT, |
1587 | .tuner_gpio = reddo_dvb_c_usb_box, | ||
1587 | .has_dvb = 1, | 1588 | .has_dvb = 1, |
1588 | .dvb_gpio = reddo_dvb_c_usb_box, | ||
1589 | }, | 1589 | }, |
1590 | }; | 1590 | }; |
1591 | const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); | 1591 | const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); |
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c index 5f37952c75cf..72802291e812 100644 --- a/drivers/media/video/mx1_camera.c +++ b/drivers/media/video/mx1_camera.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/moduleparam.h> | 28 | #include <linux/moduleparam.h> |
29 | #include <linux/mutex.h> | 29 | #include <linux/mutex.h> |
30 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
31 | #include <linux/sched.h> | ||
31 | #include <linux/time.h> | 32 | #include <linux/time.h> |
32 | #include <linux/version.h> | 33 | #include <linux/version.h> |
33 | #include <linux/videodev2.h> | 34 | #include <linux/videodev2.h> |
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c index dff2e5e2d8c6..7db82bdf6f31 100644 --- a/drivers/media/video/mx3_camera.c +++ b/drivers/media/video/mx3_camera.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
18 | #include <linux/vmalloc.h> | 18 | #include <linux/vmalloc.h> |
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/sched.h> | ||
20 | 21 | ||
21 | #include <media/v4l2-common.h> | 22 | #include <media/v4l2-common.h> |
22 | #include <media/v4l2-dev.h> | 23 | #include <media/v4l2-dev.h> |
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 2f78b4f263f5..9c8b7c7b89ee 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
32 | #include <linux/videodev2.h> | 32 | #include <linux/videodev2.h> |
33 | #include <linux/pm_runtime.h> | 33 | #include <linux/pm_runtime.h> |
34 | #include <linux/sched.h> | ||
34 | 35 | ||
35 | #include <media/v4l2-common.h> | 36 | #include <media/v4l2-common.h> |
36 | #include <media/v4l2-dev.h> | 37 | #include <media/v4l2-dev.h> |
@@ -1723,11 +1724,12 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev) | |||
1723 | 1724 | ||
1724 | err = soc_camera_host_register(&pcdev->ici); | 1725 | err = soc_camera_host_register(&pcdev->ici); |
1725 | if (err) | 1726 | if (err) |
1726 | goto exit_free_irq; | 1727 | goto exit_free_clk; |
1727 | 1728 | ||
1728 | return 0; | 1729 | return 0; |
1729 | 1730 | ||
1730 | exit_free_irq: | 1731 | exit_free_clk: |
1732 | pm_runtime_disable(&pdev->dev); | ||
1731 | free_irq(pcdev->irq, pcdev); | 1733 | free_irq(pcdev->irq, pcdev); |
1732 | exit_release_mem: | 1734 | exit_release_mem: |
1733 | if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) | 1735 | if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) |
@@ -1747,6 +1749,7 @@ static int __devexit sh_mobile_ceu_remove(struct platform_device *pdev) | |||
1747 | struct sh_mobile_ceu_dev, ici); | 1749 | struct sh_mobile_ceu_dev, ici); |
1748 | 1750 | ||
1749 | soc_camera_host_unregister(soc_host); | 1751 | soc_camera_host_unregister(soc_host); |
1752 | pm_runtime_disable(&pdev->dev); | ||
1750 | free_irq(pcdev->irq, pcdev); | 1753 | free_irq(pcdev->irq, pcdev); |
1751 | if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) | 1754 | if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) |
1752 | dma_release_declared_memory(&pdev->dev); | 1755 | dma_release_declared_memory(&pdev->dev); |
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 36e617bd13c7..95fdeb23c2c1 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c | |||
@@ -1097,6 +1097,13 @@ static int default_s_crop(struct soc_camera_device *icd, struct v4l2_crop *a) | |||
1097 | return v4l2_subdev_call(sd, video, s_crop, a); | 1097 | return v4l2_subdev_call(sd, video, s_crop, a); |
1098 | } | 1098 | } |
1099 | 1099 | ||
1100 | static void soc_camera_device_init(struct device *dev, void *pdata) | ||
1101 | { | ||
1102 | dev->platform_data = pdata; | ||
1103 | dev->bus = &soc_camera_bus_type; | ||
1104 | dev->release = dummy_release; | ||
1105 | } | ||
1106 | |||
1100 | int soc_camera_host_register(struct soc_camera_host *ici) | 1107 | int soc_camera_host_register(struct soc_camera_host *ici) |
1101 | { | 1108 | { |
1102 | struct soc_camera_host *ix; | 1109 | struct soc_camera_host *ix; |
@@ -1158,6 +1165,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici) | |||
1158 | 1165 | ||
1159 | list_for_each_entry(icd, &devices, list) { | 1166 | list_for_each_entry(icd, &devices, list) { |
1160 | if (icd->iface == ici->nr) { | 1167 | if (icd->iface == ici->nr) { |
1168 | void *pdata = icd->dev.platform_data; | ||
1161 | /* The bus->remove will be called */ | 1169 | /* The bus->remove will be called */ |
1162 | device_unregister(&icd->dev); | 1170 | device_unregister(&icd->dev); |
1163 | /* | 1171 | /* |
@@ -1169,6 +1177,7 @@ void soc_camera_host_unregister(struct soc_camera_host *ici) | |||
1169 | * device private data. | 1177 | * device private data. |
1170 | */ | 1178 | */ |
1171 | memset(&icd->dev, 0, sizeof(icd->dev)); | 1179 | memset(&icd->dev, 0, sizeof(icd->dev)); |
1180 | soc_camera_device_init(&icd->dev, pdata); | ||
1172 | } | 1181 | } |
1173 | } | 1182 | } |
1174 | 1183 | ||
@@ -1200,10 +1209,7 @@ static int soc_camera_device_register(struct soc_camera_device *icd) | |||
1200 | * man, stay reasonable... */ | 1209 | * man, stay reasonable... */ |
1201 | return -ENOMEM; | 1210 | return -ENOMEM; |
1202 | 1211 | ||
1203 | icd->devnum = num; | 1212 | icd->devnum = num; |
1204 | icd->dev.bus = &soc_camera_bus_type; | ||
1205 | |||
1206 | icd->dev.release = dummy_release; | ||
1207 | icd->use_count = 0; | 1213 | icd->use_count = 0; |
1208 | icd->host_priv = NULL; | 1214 | icd->host_priv = NULL; |
1209 | mutex_init(&icd->video_lock); | 1215 | mutex_init(&icd->video_lock); |
@@ -1311,12 +1317,13 @@ static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev) | |||
1311 | icd->iface = icl->bus_id; | 1317 | icd->iface = icl->bus_id; |
1312 | icd->pdev = &pdev->dev; | 1318 | icd->pdev = &pdev->dev; |
1313 | platform_set_drvdata(pdev, icd); | 1319 | platform_set_drvdata(pdev, icd); |
1314 | icd->dev.platform_data = icl; | ||
1315 | 1320 | ||
1316 | ret = soc_camera_device_register(icd); | 1321 | ret = soc_camera_device_register(icd); |
1317 | if (ret < 0) | 1322 | if (ret < 0) |
1318 | goto escdevreg; | 1323 | goto escdevreg; |
1319 | 1324 | ||
1325 | soc_camera_device_init(&icd->dev, icl); | ||
1326 | |||
1320 | icd->user_width = DEFAULT_WIDTH; | 1327 | icd->user_width = DEFAULT_WIDTH; |
1321 | icd->user_height = DEFAULT_HEIGHT; | 1328 | icd->user_height = DEFAULT_HEIGHT; |
1322 | 1329 | ||
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c index 635ffc7b0391..c3065c4bcba9 100644 --- a/drivers/media/video/videobuf-dma-contig.c +++ b/drivers/media/video/videobuf-dma-contig.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
20 | #include <linux/pagemap.h> | 20 | #include <linux/pagemap.h> |
21 | #include <linux/dma-mapping.h> | 21 | #include <linux/dma-mapping.h> |
22 | #include <linux/sched.h> | ||
22 | #include <media/videobuf-dma-contig.h> | 23 | #include <media/videobuf-dma-contig.h> |
23 | 24 | ||
24 | struct videobuf_dma_contig_memory { | 25 | struct videobuf_dma_contig_memory { |
diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index db39f4a52f53..2cb2736d65aa 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c | |||
@@ -158,6 +158,7 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf, | |||
158 | struct i2c_msg msg[2]; | 158 | struct i2c_msg msg[2]; |
159 | u8 msgbuf[2]; | 159 | u8 msgbuf[2]; |
160 | struct i2c_client *client; | 160 | struct i2c_client *client; |
161 | unsigned long timeout, read_time; | ||
161 | int status, i; | 162 | int status, i; |
162 | 163 | ||
163 | memset(msg, 0, sizeof(msg)); | 164 | memset(msg, 0, sizeof(msg)); |
@@ -183,47 +184,60 @@ static ssize_t at24_eeprom_read(struct at24_data *at24, char *buf, | |||
183 | if (count > io_limit) | 184 | if (count > io_limit) |
184 | count = io_limit; | 185 | count = io_limit; |
185 | 186 | ||
186 | /* Smaller eeproms can work given some SMBus extension calls */ | ||
187 | if (at24->use_smbus) { | 187 | if (at24->use_smbus) { |
188 | /* Smaller eeproms can work given some SMBus extension calls */ | ||
188 | if (count > I2C_SMBUS_BLOCK_MAX) | 189 | if (count > I2C_SMBUS_BLOCK_MAX) |
189 | count = I2C_SMBUS_BLOCK_MAX; | 190 | count = I2C_SMBUS_BLOCK_MAX; |
190 | status = i2c_smbus_read_i2c_block_data(client, offset, | 191 | } else { |
191 | count, buf); | 192 | /* |
192 | dev_dbg(&client->dev, "smbus read %zu@%d --> %d\n", | 193 | * When we have a better choice than SMBus calls, use a |
193 | count, offset, status); | 194 | * combined I2C message. Write address; then read up to |
194 | return (status < 0) ? -EIO : status; | 195 | * io_limit data bytes. Note that read page rollover helps us |
196 | * here (unlike writes). msgbuf is u8 and will cast to our | ||
197 | * needs. | ||
198 | */ | ||
199 | i = 0; | ||
200 | if (at24->chip.flags & AT24_FLAG_ADDR16) | ||
201 | msgbuf[i++] = offset >> 8; | ||
202 | msgbuf[i++] = offset; | ||
203 | |||
204 | msg[0].addr = client->addr; | ||
205 | msg[0].buf = msgbuf; | ||
206 | msg[0].len = i; | ||
207 | |||
208 | msg[1].addr = client->addr; | ||
209 | msg[1].flags = I2C_M_RD; | ||
210 | msg[1].buf = buf; | ||
211 | msg[1].len = count; | ||
195 | } | 212 | } |
196 | 213 | ||
197 | /* | 214 | /* |
198 | * When we have a better choice than SMBus calls, use a combined | 215 | * Reads fail if the previous write didn't complete yet. We may |
199 | * I2C message. Write address; then read up to io_limit data bytes. | 216 | * loop a few times until this one succeeds, waiting at least |
200 | * Note that read page rollover helps us here (unlike writes). | 217 | * long enough for one entire page write to work. |
201 | * msgbuf is u8 and will cast to our needs. | ||
202 | */ | 218 | */ |
203 | i = 0; | 219 | timeout = jiffies + msecs_to_jiffies(write_timeout); |
204 | if (at24->chip.flags & AT24_FLAG_ADDR16) | 220 | do { |
205 | msgbuf[i++] = offset >> 8; | 221 | read_time = jiffies; |
206 | msgbuf[i++] = offset; | 222 | if (at24->use_smbus) { |
207 | 223 | status = i2c_smbus_read_i2c_block_data(client, offset, | |
208 | msg[0].addr = client->addr; | 224 | count, buf); |
209 | msg[0].buf = msgbuf; | 225 | } else { |
210 | msg[0].len = i; | 226 | status = i2c_transfer(client->adapter, msg, 2); |
227 | if (status == 2) | ||
228 | status = count; | ||
229 | } | ||
230 | dev_dbg(&client->dev, "read %zu@%d --> %d (%ld)\n", | ||
231 | count, offset, status, jiffies); | ||
211 | 232 | ||
212 | msg[1].addr = client->addr; | 233 | if (status == count) |
213 | msg[1].flags = I2C_M_RD; | 234 | return count; |
214 | msg[1].buf = buf; | ||
215 | msg[1].len = count; | ||
216 | 235 | ||
217 | status = i2c_transfer(client->adapter, msg, 2); | 236 | /* REVISIT: at HZ=100, this is sloooow */ |
218 | dev_dbg(&client->dev, "i2c read %zu@%d --> %d\n", | 237 | msleep(1); |
219 | count, offset, status); | 238 | } while (time_before(read_time, timeout)); |
220 | 239 | ||
221 | if (status == 2) | 240 | return -ETIMEDOUT; |
222 | return count; | ||
223 | else if (status >= 0) | ||
224 | return -EIO; | ||
225 | else | ||
226 | return status; | ||
227 | } | 241 | } |
228 | 242 | ||
229 | static ssize_t at24_read(struct at24_data *at24, | 243 | static ssize_t at24_read(struct at24_data *at24, |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 705a5894a6bb..90d168ad03b6 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -56,7 +56,7 @@ static void mmci_set_clkreg(struct mmci_host *host, unsigned int desired) | |||
56 | clk = 255; | 56 | clk = 255; |
57 | host->cclk = host->mclk / (2 * (clk + 1)); | 57 | host->cclk = host->mclk / (2 * (clk + 1)); |
58 | } | 58 | } |
59 | if (host->hw_designer == 0x80) | 59 | if (host->hw_designer == AMBA_VENDOR_ST) |
60 | clk |= MCI_FCEN; /* Bug fix in ST IP block */ | 60 | clk |= MCI_FCEN; /* Bug fix in ST IP block */ |
61 | clk |= MCI_CLK_ENABLE; | 61 | clk |= MCI_CLK_ENABLE; |
62 | /* This hasn't proven to be worthwhile */ | 62 | /* This hasn't proven to be worthwhile */ |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index e19ca4bb7510..b2f71f79baaf 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -975,7 +975,7 @@ config ENC28J60_WRITEVERIFY | |||
975 | 975 | ||
976 | config ETHOC | 976 | config ETHOC |
977 | tristate "OpenCores 10/100 Mbps Ethernet MAC support" | 977 | tristate "OpenCores 10/100 Mbps Ethernet MAC support" |
978 | depends on NET_ETHERNET && HAS_IOMEM | 978 | depends on NET_ETHERNET && HAS_IOMEM && HAS_DMA |
979 | select MII | 979 | select MII |
980 | select PHYLIB | 980 | select PHYLIB |
981 | select CRC32 | 981 | select CRC32 |
diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c index 2be49c817995..b25467ac895c 100644 --- a/drivers/net/arm/ep93xx_eth.c +++ b/drivers/net/arm/ep93xx_eth.c | |||
@@ -628,15 +628,6 @@ static int ep93xx_open(struct net_device *dev) | |||
628 | if (ep93xx_alloc_buffers(ep)) | 628 | if (ep93xx_alloc_buffers(ep)) |
629 | return -ENOMEM; | 629 | return -ENOMEM; |
630 | 630 | ||
631 | if (is_zero_ether_addr(dev->dev_addr)) { | ||
632 | random_ether_addr(dev->dev_addr); | ||
633 | printk(KERN_INFO "%s: generated random MAC address " | ||
634 | "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x.\n", dev->name, | ||
635 | dev->dev_addr[0], dev->dev_addr[1], | ||
636 | dev->dev_addr[2], dev->dev_addr[3], | ||
637 | dev->dev_addr[4], dev->dev_addr[5]); | ||
638 | } | ||
639 | |||
640 | napi_enable(&ep->napi); | 631 | napi_enable(&ep->napi); |
641 | 632 | ||
642 | if (ep93xx_start_hw(dev)) { | 633 | if (ep93xx_start_hw(dev)) { |
@@ -877,6 +868,9 @@ static int ep93xx_eth_probe(struct platform_device *pdev) | |||
877 | ep->mii.mdio_write = ep93xx_mdio_write; | 868 | ep->mii.mdio_write = ep93xx_mdio_write; |
878 | ep->mdc_divisor = 40; /* Max HCLK 100 MHz, min MDIO clk 2.5 MHz. */ | 869 | ep->mdc_divisor = 40; /* Max HCLK 100 MHz, min MDIO clk 2.5 MHz. */ |
879 | 870 | ||
871 | if (is_zero_ether_addr(dev->dev_addr)) | ||
872 | random_ether_addr(dev->dev_addr); | ||
873 | |||
880 | err = register_netdev(dev); | 874 | err = register_netdev(dev); |
881 | if (err) { | 875 | if (err) { |
882 | dev_err(&pdev->dev, "Failed to register netdev\n"); | 876 | dev_err(&pdev->dev, "Failed to register netdev\n"); |
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index ce6f1ac25df8..3f4b4300f533 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c | |||
@@ -1088,7 +1088,14 @@ static struct net_device * au1000_probe(int port_num) | |||
1088 | return NULL; | 1088 | return NULL; |
1089 | } | 1089 | } |
1090 | 1090 | ||
1091 | if ((err = register_netdev(dev)) != 0) { | 1091 | dev->base_addr = base; |
1092 | dev->irq = irq; | ||
1093 | dev->netdev_ops = &au1000_netdev_ops; | ||
1094 | SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops); | ||
1095 | dev->watchdog_timeo = ETH_TX_TIMEOUT; | ||
1096 | |||
1097 | err = register_netdev(dev); | ||
1098 | if (err != 0) { | ||
1092 | printk(KERN_ERR "%s: Cannot register net device, error %d\n", | 1099 | printk(KERN_ERR "%s: Cannot register net device, error %d\n", |
1093 | DRV_NAME, err); | 1100 | DRV_NAME, err); |
1094 | free_netdev(dev); | 1101 | free_netdev(dev); |
@@ -1209,12 +1216,6 @@ static struct net_device * au1000_probe(int port_num) | |||
1209 | aup->tx_db_inuse[i] = pDB; | 1216 | aup->tx_db_inuse[i] = pDB; |
1210 | } | 1217 | } |
1211 | 1218 | ||
1212 | dev->base_addr = base; | ||
1213 | dev->irq = irq; | ||
1214 | dev->netdev_ops = &au1000_netdev_ops; | ||
1215 | SET_ETHTOOL_OPS(dev, &au1000_ethtool_ops); | ||
1216 | dev->watchdog_timeo = ETH_TX_TIMEOUT; | ||
1217 | |||
1218 | /* | 1219 | /* |
1219 | * The boot code uses the ethernet controller, so reset it to start | 1220 | * The boot code uses the ethernet controller, so reset it to start |
1220 | * fresh. au1000_init() expects that the device is in reset state. | 1221 | * fresh. au1000_init() expects that the device is in reset state. |
diff --git a/drivers/net/b44.c b/drivers/net/b44.c index e046943ef29d..2a9132343b66 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c | |||
@@ -912,9 +912,6 @@ static irqreturn_t b44_interrupt(int irq, void *dev_id) | |||
912 | bp->istat = istat; | 912 | bp->istat = istat; |
913 | __b44_disable_ints(bp); | 913 | __b44_disable_ints(bp); |
914 | __napi_schedule(&bp->napi); | 914 | __napi_schedule(&bp->napi); |
915 | } else { | ||
916 | printk(KERN_ERR PFX "%s: Error, poll already scheduled\n", | ||
917 | dev->name); | ||
918 | } | 915 | } |
919 | 916 | ||
920 | irq_ack: | 917 | irq_ack: |
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c index db6380379478..e3478314c002 100644 --- a/drivers/net/davinci_emac.c +++ b/drivers/net/davinci_emac.c | |||
@@ -164,16 +164,14 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1"; | |||
164 | # define EMAC_MBP_MCASTCHAN(ch) ((ch) & 0x7) | 164 | # define EMAC_MBP_MCASTCHAN(ch) ((ch) & 0x7) |
165 | 165 | ||
166 | /* EMAC mac_control register */ | 166 | /* EMAC mac_control register */ |
167 | #define EMAC_MACCONTROL_TXPTYPE (0x200) | 167 | #define EMAC_MACCONTROL_TXPTYPE BIT(9) |
168 | #define EMAC_MACCONTROL_TXPACEEN (0x40) | 168 | #define EMAC_MACCONTROL_TXPACEEN BIT(6) |
169 | #define EMAC_MACCONTROL_MIIEN (0x20) | 169 | #define EMAC_MACCONTROL_GMIIEN BIT(5) |
170 | #define EMAC_MACCONTROL_GIGABITEN (0x80) | 170 | #define EMAC_MACCONTROL_GIGABITEN BIT(7) |
171 | #define EMAC_MACCONTROL_GIGABITEN_SHIFT (7) | 171 | #define EMAC_MACCONTROL_FULLDUPLEXEN BIT(0) |
172 | #define EMAC_MACCONTROL_FULLDUPLEXEN (0x1) | ||
173 | #define EMAC_MACCONTROL_RMIISPEED_MASK BIT(15) | 172 | #define EMAC_MACCONTROL_RMIISPEED_MASK BIT(15) |
174 | 173 | ||
175 | /* GIGABIT MODE related bits */ | 174 | /* GIGABIT MODE related bits */ |
176 | #define EMAC_DM646X_MACCONTORL_GMIIEN BIT(5) | ||
177 | #define EMAC_DM646X_MACCONTORL_GIG BIT(7) | 175 | #define EMAC_DM646X_MACCONTORL_GIG BIT(7) |
178 | #define EMAC_DM646X_MACCONTORL_GIGFORCE BIT(17) | 176 | #define EMAC_DM646X_MACCONTORL_GIGFORCE BIT(17) |
179 | 177 | ||
@@ -192,10 +190,10 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1"; | |||
192 | #define EMAC_RX_BUFFER_OFFSET_MASK (0xFFFF) | 190 | #define EMAC_RX_BUFFER_OFFSET_MASK (0xFFFF) |
193 | 191 | ||
194 | /* MAC_IN_VECTOR (0x180) register bit fields */ | 192 | /* MAC_IN_VECTOR (0x180) register bit fields */ |
195 | #define EMAC_DM644X_MAC_IN_VECTOR_HOST_INT (0x20000) | 193 | #define EMAC_DM644X_MAC_IN_VECTOR_HOST_INT BIT(17) |
196 | #define EMAC_DM644X_MAC_IN_VECTOR_STATPEND_INT (0x10000) | 194 | #define EMAC_DM644X_MAC_IN_VECTOR_STATPEND_INT BIT(16) |
197 | #define EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC (0x0100) | 195 | #define EMAC_DM644X_MAC_IN_VECTOR_RX_INT_VEC BIT(8) |
198 | #define EMAC_DM644X_MAC_IN_VECTOR_TX_INT_VEC (0x01) | 196 | #define EMAC_DM644X_MAC_IN_VECTOR_TX_INT_VEC BIT(0) |
199 | 197 | ||
200 | /** NOTE:: For DM646x the IN_VECTOR has changed */ | 198 | /** NOTE:: For DM646x the IN_VECTOR has changed */ |
201 | #define EMAC_DM646X_MAC_IN_VECTOR_RX_INT_VEC BIT(EMAC_DEF_RX_CH) | 199 | #define EMAC_DM646X_MAC_IN_VECTOR_RX_INT_VEC BIT(EMAC_DEF_RX_CH) |
@@ -203,7 +201,6 @@ static const char emac_version_string[] = "TI DaVinci EMAC Linux v6.1"; | |||
203 | #define EMAC_DM646X_MAC_IN_VECTOR_HOST_INT BIT(26) | 201 | #define EMAC_DM646X_MAC_IN_VECTOR_HOST_INT BIT(26) |
204 | #define EMAC_DM646X_MAC_IN_VECTOR_STATPEND_INT BIT(27) | 202 | #define EMAC_DM646X_MAC_IN_VECTOR_STATPEND_INT BIT(27) |
205 | 203 | ||
206 | |||
207 | /* CPPI bit positions */ | 204 | /* CPPI bit positions */ |
208 | #define EMAC_CPPI_SOP_BIT BIT(31) | 205 | #define EMAC_CPPI_SOP_BIT BIT(31) |
209 | #define EMAC_CPPI_EOP_BIT BIT(30) | 206 | #define EMAC_CPPI_EOP_BIT BIT(30) |
@@ -750,8 +747,7 @@ static void emac_update_phystatus(struct emac_priv *priv) | |||
750 | 747 | ||
751 | if (priv->speed == SPEED_1000 && (priv->version == EMAC_VERSION_2)) { | 748 | if (priv->speed == SPEED_1000 && (priv->version == EMAC_VERSION_2)) { |
752 | mac_control = emac_read(EMAC_MACCONTROL); | 749 | mac_control = emac_read(EMAC_MACCONTROL); |
753 | mac_control |= (EMAC_DM646X_MACCONTORL_GMIIEN | | 750 | mac_control |= (EMAC_DM646X_MACCONTORL_GIG | |
754 | EMAC_DM646X_MACCONTORL_GIG | | ||
755 | EMAC_DM646X_MACCONTORL_GIGFORCE); | 751 | EMAC_DM646X_MACCONTORL_GIGFORCE); |
756 | } else { | 752 | } else { |
757 | /* Clear the GIG bit and GIGFORCE bit */ | 753 | /* Clear the GIG bit and GIGFORCE bit */ |
@@ -2108,7 +2104,7 @@ static int emac_hw_enable(struct emac_priv *priv) | |||
2108 | 2104 | ||
2109 | /* Enable MII */ | 2105 | /* Enable MII */ |
2110 | val = emac_read(EMAC_MACCONTROL); | 2106 | val = emac_read(EMAC_MACCONTROL); |
2111 | val |= (EMAC_MACCONTROL_MIIEN); | 2107 | val |= (EMAC_MACCONTROL_GMIIEN); |
2112 | emac_write(EMAC_MACCONTROL, val); | 2108 | emac_write(EMAC_MACCONTROL, val); |
2113 | 2109 | ||
2114 | /* Enable NAPI and interrupts */ | 2110 | /* Enable NAPI and interrupts */ |
diff --git a/drivers/net/e100.c b/drivers/net/e100.c index 3c29a20b751e..d269a68ce354 100644 --- a/drivers/net/e100.c +++ b/drivers/net/e100.c | |||
@@ -157,6 +157,7 @@ | |||
157 | #include <linux/init.h> | 157 | #include <linux/init.h> |
158 | #include <linux/pci.h> | 158 | #include <linux/pci.h> |
159 | #include <linux/dma-mapping.h> | 159 | #include <linux/dma-mapping.h> |
160 | #include <linux/dmapool.h> | ||
160 | #include <linux/netdevice.h> | 161 | #include <linux/netdevice.h> |
161 | #include <linux/etherdevice.h> | 162 | #include <linux/etherdevice.h> |
162 | #include <linux/mii.h> | 163 | #include <linux/mii.h> |
@@ -602,6 +603,7 @@ struct nic { | |||
602 | struct mem *mem; | 603 | struct mem *mem; |
603 | dma_addr_t dma_addr; | 604 | dma_addr_t dma_addr; |
604 | 605 | ||
606 | struct pci_pool *cbs_pool; | ||
605 | dma_addr_t cbs_dma_addr; | 607 | dma_addr_t cbs_dma_addr; |
606 | u8 adaptive_ifs; | 608 | u8 adaptive_ifs; |
607 | u8 tx_threshold; | 609 | u8 tx_threshold; |
@@ -1793,9 +1795,7 @@ static void e100_clean_cbs(struct nic *nic) | |||
1793 | nic->cb_to_clean = nic->cb_to_clean->next; | 1795 | nic->cb_to_clean = nic->cb_to_clean->next; |
1794 | nic->cbs_avail++; | 1796 | nic->cbs_avail++; |
1795 | } | 1797 | } |
1796 | pci_free_consistent(nic->pdev, | 1798 | pci_pool_free(nic->cbs_pool, nic->cbs, nic->cbs_dma_addr); |
1797 | sizeof(struct cb) * nic->params.cbs.count, | ||
1798 | nic->cbs, nic->cbs_dma_addr); | ||
1799 | nic->cbs = NULL; | 1799 | nic->cbs = NULL; |
1800 | nic->cbs_avail = 0; | 1800 | nic->cbs_avail = 0; |
1801 | } | 1801 | } |
@@ -1813,8 +1813,8 @@ static int e100_alloc_cbs(struct nic *nic) | |||
1813 | nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = NULL; | 1813 | nic->cb_to_use = nic->cb_to_send = nic->cb_to_clean = NULL; |
1814 | nic->cbs_avail = 0; | 1814 | nic->cbs_avail = 0; |
1815 | 1815 | ||
1816 | nic->cbs = pci_alloc_consistent(nic->pdev, | 1816 | nic->cbs = pci_pool_alloc(nic->cbs_pool, GFP_KERNEL, |
1817 | sizeof(struct cb) * count, &nic->cbs_dma_addr); | 1817 | &nic->cbs_dma_addr); |
1818 | if (!nic->cbs) | 1818 | if (!nic->cbs) |
1819 | return -ENOMEM; | 1819 | return -ENOMEM; |
1820 | 1820 | ||
@@ -2841,7 +2841,11 @@ static int __devinit e100_probe(struct pci_dev *pdev, | |||
2841 | DPRINTK(PROBE, ERR, "Cannot register net device, aborting.\n"); | 2841 | DPRINTK(PROBE, ERR, "Cannot register net device, aborting.\n"); |
2842 | goto err_out_free; | 2842 | goto err_out_free; |
2843 | } | 2843 | } |
2844 | 2844 | nic->cbs_pool = pci_pool_create(netdev->name, | |
2845 | nic->pdev, | ||
2846 | nic->params.cbs.count * sizeof(struct cb), | ||
2847 | sizeof(u32), | ||
2848 | 0); | ||
2845 | DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n", | 2849 | DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, MAC addr %pM\n", |
2846 | (unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0), | 2850 | (unsigned long long)pci_resource_start(pdev, use_io ? 1 : 0), |
2847 | pdev->irq, netdev->dev_addr); | 2851 | pdev->irq, netdev->dev_addr); |
@@ -2871,6 +2875,7 @@ static void __devexit e100_remove(struct pci_dev *pdev) | |||
2871 | unregister_netdev(netdev); | 2875 | unregister_netdev(netdev); |
2872 | e100_free(nic); | 2876 | e100_free(nic); |
2873 | pci_iounmap(pdev, nic->csr); | 2877 | pci_iounmap(pdev, nic->csr); |
2878 | pci_pool_destroy(nic->cbs_pool); | ||
2874 | free_netdev(netdev); | 2879 | free_netdev(netdev); |
2875 | pci_release_regions(pdev); | 2880 | pci_release_regions(pdev); |
2876 | pci_disable_device(pdev); | 2881 | pci_disable_device(pdev); |
diff --git a/drivers/net/e1000e/e1000.h b/drivers/net/e1000e/e1000.h index 189dfa2d6c76..3e187b0e4203 100644 --- a/drivers/net/e1000e/e1000.h +++ b/drivers/net/e1000e/e1000.h | |||
@@ -141,6 +141,8 @@ struct e1000_info; | |||
141 | #define HV_TNCRS_UPPER PHY_REG(778, 29) /* Transmit with no CRS */ | 141 | #define HV_TNCRS_UPPER PHY_REG(778, 29) /* Transmit with no CRS */ |
142 | #define HV_TNCRS_LOWER PHY_REG(778, 30) | 142 | #define HV_TNCRS_LOWER PHY_REG(778, 30) |
143 | 143 | ||
144 | #define E1000_FCRTV_PCH 0x05F40 /* PCH Flow Control Refresh Timer Value */ | ||
145 | |||
144 | /* BM PHY Copper Specific Status */ | 146 | /* BM PHY Copper Specific Status */ |
145 | #define BM_CS_STATUS 17 | 147 | #define BM_CS_STATUS 17 |
146 | #define BM_CS_STATUS_LINK_UP 0x0400 | 148 | #define BM_CS_STATUS_LINK_UP 0x0400 |
diff --git a/drivers/net/e1000e/ethtool.c b/drivers/net/e1000e/ethtool.c index 1bf4d2a5d34f..e82638ecae88 100644 --- a/drivers/net/e1000e/ethtool.c +++ b/drivers/net/e1000e/ethtool.c | |||
@@ -327,10 +327,18 @@ static int e1000_set_pauseparam(struct net_device *netdev, | |||
327 | 327 | ||
328 | hw->fc.current_mode = hw->fc.requested_mode; | 328 | hw->fc.current_mode = hw->fc.requested_mode; |
329 | 329 | ||
330 | retval = ((hw->phy.media_type == e1000_media_type_fiber) ? | 330 | if (hw->phy.media_type == e1000_media_type_fiber) { |
331 | hw->mac.ops.setup_link(hw) : e1000e_force_mac_fc(hw)); | 331 | retval = hw->mac.ops.setup_link(hw); |
332 | /* implicit goto out */ | ||
333 | } else { | ||
334 | retval = e1000e_force_mac_fc(hw); | ||
335 | if (retval) | ||
336 | goto out; | ||
337 | e1000e_set_fc_watermarks(hw); | ||
338 | } | ||
332 | } | 339 | } |
333 | 340 | ||
341 | out: | ||
334 | clear_bit(__E1000_RESETTING, &adapter->state); | 342 | clear_bit(__E1000_RESETTING, &adapter->state); |
335 | return retval; | 343 | return retval; |
336 | } | 344 | } |
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index 51ddb04ab195..eff3f4783655 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c | |||
@@ -1118,7 +1118,8 @@ static s32 e1000_oem_bits_config_ich8lan(struct e1000_hw *hw, bool d0_state) | |||
1118 | oem_reg |= HV_OEM_BITS_LPLU; | 1118 | oem_reg |= HV_OEM_BITS_LPLU; |
1119 | } | 1119 | } |
1120 | /* Restart auto-neg to activate the bits */ | 1120 | /* Restart auto-neg to activate the bits */ |
1121 | oem_reg |= HV_OEM_BITS_RESTART_AN; | 1121 | if (!e1000_check_reset_block(hw)) |
1122 | oem_reg |= HV_OEM_BITS_RESTART_AN; | ||
1122 | ret_val = hw->phy.ops.write_phy_reg_locked(hw, HV_OEM_BITS, oem_reg); | 1123 | ret_val = hw->phy.ops.write_phy_reg_locked(hw, HV_OEM_BITS, oem_reg); |
1123 | 1124 | ||
1124 | out: | 1125 | out: |
@@ -3558,6 +3559,7 @@ struct e1000_info e1000_pch_info = { | |||
3558 | | FLAG_HAS_AMT | 3559 | | FLAG_HAS_AMT |
3559 | | FLAG_HAS_FLASH | 3560 | | FLAG_HAS_FLASH |
3560 | | FLAG_HAS_JUMBO_FRAMES | 3561 | | FLAG_HAS_JUMBO_FRAMES |
3562 | | FLAG_DISABLE_FC_PAUSE_TIME /* errata */ | ||
3561 | | FLAG_APME_IN_WUC, | 3563 | | FLAG_APME_IN_WUC, |
3562 | .pba = 26, | 3564 | .pba = 26, |
3563 | .max_hw_frame_size = 4096, | 3565 | .max_hw_frame_size = 4096, |
diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c index 0687c6aa4e46..fad8f9ea0043 100644 --- a/drivers/net/e1000e/netdev.c +++ b/drivers/net/e1000e/netdev.c | |||
@@ -2769,25 +2769,38 @@ void e1000e_reset(struct e1000_adapter *adapter) | |||
2769 | /* | 2769 | /* |
2770 | * flow control settings | 2770 | * flow control settings |
2771 | * | 2771 | * |
2772 | * The high water mark must be low enough to fit two full frame | 2772 | * The high water mark must be low enough to fit one full frame |
2773 | * (or the size used for early receive) above it in the Rx FIFO. | 2773 | * (or the size used for early receive) above it in the Rx FIFO. |
2774 | * Set it to the lower of: | 2774 | * Set it to the lower of: |
2775 | * - 90% of the Rx FIFO size, and | 2775 | * - 90% of the Rx FIFO size, and |
2776 | * - the full Rx FIFO size minus the early receive size (for parts | 2776 | * - the full Rx FIFO size minus the early receive size (for parts |
2777 | * with ERT support assuming ERT set to E1000_ERT_2048), or | 2777 | * with ERT support assuming ERT set to E1000_ERT_2048), or |
2778 | * - the full Rx FIFO size minus two full frames | 2778 | * - the full Rx FIFO size minus one full frame |
2779 | */ | 2779 | */ |
2780 | if ((adapter->flags & FLAG_HAS_ERT) && | 2780 | if (hw->mac.type == e1000_pchlan) { |
2781 | (adapter->netdev->mtu > ETH_DATA_LEN)) | 2781 | /* |
2782 | hwm = min(((pba << 10) * 9 / 10), | 2782 | * Workaround PCH LOM adapter hangs with certain network |
2783 | ((pba << 10) - (E1000_ERT_2048 << 3))); | 2783 | * loads. If hangs persist, try disabling Tx flow control. |
2784 | else | 2784 | */ |
2785 | hwm = min(((pba << 10) * 9 / 10), | 2785 | if (adapter->netdev->mtu > ETH_DATA_LEN) { |
2786 | ((pba << 10) - (2 * adapter->max_frame_size))); | 2786 | fc->high_water = 0x3500; |
2787 | fc->low_water = 0x1500; | ||
2788 | } else { | ||
2789 | fc->high_water = 0x5000; | ||
2790 | fc->low_water = 0x3000; | ||
2791 | } | ||
2792 | } else { | ||
2793 | if ((adapter->flags & FLAG_HAS_ERT) && | ||
2794 | (adapter->netdev->mtu > ETH_DATA_LEN)) | ||
2795 | hwm = min(((pba << 10) * 9 / 10), | ||
2796 | ((pba << 10) - (E1000_ERT_2048 << 3))); | ||
2797 | else | ||
2798 | hwm = min(((pba << 10) * 9 / 10), | ||
2799 | ((pba << 10) - adapter->max_frame_size)); | ||
2787 | 2800 | ||
2788 | fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */ | 2801 | fc->high_water = hwm & E1000_FCRTH_RTH; /* 8-byte granularity */ |
2789 | fc->low_water = (fc->high_water - (2 * adapter->max_frame_size)); | 2802 | fc->low_water = fc->high_water - 8; |
2790 | fc->low_water &= E1000_FCRTL_RTL; /* 8-byte granularity */ | 2803 | } |
2791 | 2804 | ||
2792 | if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME) | 2805 | if (adapter->flags & FLAG_DISABLE_FC_PAUSE_TIME) |
2793 | fc->pause_time = 0xFFFF; | 2806 | fc->pause_time = 0xFFFF; |
@@ -2813,6 +2826,10 @@ void e1000e_reset(struct e1000_adapter *adapter) | |||
2813 | if (mac->ops.init_hw(hw)) | 2826 | if (mac->ops.init_hw(hw)) |
2814 | e_err("Hardware Error\n"); | 2827 | e_err("Hardware Error\n"); |
2815 | 2828 | ||
2829 | /* additional part of the flow-control workaround above */ | ||
2830 | if (hw->mac.type == e1000_pchlan) | ||
2831 | ew32(FCRTV_PCH, 0x1000); | ||
2832 | |||
2816 | e1000_update_mng_vlan(adapter); | 2833 | e1000_update_mng_vlan(adapter); |
2817 | 2834 | ||
2818 | /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */ | 2835 | /* Enable h/w to recognize an 802.1Q VLAN Ethernet packet */ |
@@ -3610,7 +3627,7 @@ static void e1000_watchdog_task(struct work_struct *work) | |||
3610 | case SPEED_100: | 3627 | case SPEED_100: |
3611 | txb2b = 0; | 3628 | txb2b = 0; |
3612 | netdev->tx_queue_len = 100; | 3629 | netdev->tx_queue_len = 100; |
3613 | /* maybe add some timeout factor ? */ | 3630 | adapter->tx_timeout_factor = 10; |
3614 | break; | 3631 | break; |
3615 | } | 3632 | } |
3616 | 3633 | ||
@@ -4288,8 +4305,10 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) | |||
4288 | 4305 | ||
4289 | while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) | 4306 | while (test_and_set_bit(__E1000_RESETTING, &adapter->state)) |
4290 | msleep(1); | 4307 | msleep(1); |
4291 | /* e1000e_down has a dependency on max_frame_size */ | 4308 | /* e1000e_down -> e1000e_reset dependent on max_frame_size & mtu */ |
4292 | adapter->max_frame_size = max_frame; | 4309 | adapter->max_frame_size = max_frame; |
4310 | e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu); | ||
4311 | netdev->mtu = new_mtu; | ||
4293 | if (netif_running(netdev)) | 4312 | if (netif_running(netdev)) |
4294 | e1000e_down(adapter); | 4313 | e1000e_down(adapter); |
4295 | 4314 | ||
@@ -4319,9 +4338,6 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu) | |||
4319 | adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN | 4338 | adapter->rx_buffer_len = ETH_FRAME_LEN + VLAN_HLEN |
4320 | + ETH_FCS_LEN; | 4339 | + ETH_FCS_LEN; |
4321 | 4340 | ||
4322 | e_info("changing MTU from %d to %d\n", netdev->mtu, new_mtu); | ||
4323 | netdev->mtu = new_mtu; | ||
4324 | |||
4325 | if (netif_running(netdev)) | 4341 | if (netif_running(netdev)) |
4326 | e1000e_up(adapter); | 4342 | e1000e_up(adapter); |
4327 | else | 4343 | else |
diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index 03175b3a2c9e..85f955f70417 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c | |||
@@ -71,7 +71,6 @@ static const u16 e1000_igp_2_cable_length_table[] = | |||
71 | #define I82577_CFG_ASSERT_CRS_ON_TX (1 << 15) | 71 | #define I82577_CFG_ASSERT_CRS_ON_TX (1 << 15) |
72 | #define I82577_CFG_ENABLE_DOWNSHIFT (3 << 10) /* auto downshift 100/10 */ | 72 | #define I82577_CFG_ENABLE_DOWNSHIFT (3 << 10) /* auto downshift 100/10 */ |
73 | #define I82577_CTRL_REG 23 | 73 | #define I82577_CTRL_REG 23 |
74 | #define I82577_CTRL_DOWNSHIFT_MASK (7 << 10) | ||
75 | 74 | ||
76 | /* 82577 specific PHY registers */ | 75 | /* 82577 specific PHY registers */ |
77 | #define I82577_PHY_CTRL_2 18 | 76 | #define I82577_PHY_CTRL_2 18 |
@@ -660,15 +659,6 @@ s32 e1000_copper_link_setup_82577(struct e1000_hw *hw) | |||
660 | phy_data |= I82577_CFG_ENABLE_DOWNSHIFT; | 659 | phy_data |= I82577_CFG_ENABLE_DOWNSHIFT; |
661 | 660 | ||
662 | ret_val = phy->ops.write_phy_reg(hw, I82577_CFG_REG, phy_data); | 661 | ret_val = phy->ops.write_phy_reg(hw, I82577_CFG_REG, phy_data); |
663 | if (ret_val) | ||
664 | goto out; | ||
665 | |||
666 | /* Set number of link attempts before downshift */ | ||
667 | ret_val = phy->ops.read_phy_reg(hw, I82577_CTRL_REG, &phy_data); | ||
668 | if (ret_val) | ||
669 | goto out; | ||
670 | phy_data &= ~I82577_CTRL_DOWNSHIFT_MASK; | ||
671 | ret_val = phy->ops.write_phy_reg(hw, I82577_CTRL_REG, phy_data); | ||
672 | 662 | ||
673 | out: | 663 | out: |
674 | return ret_val; | 664 | return ret_val; |
@@ -2658,19 +2648,18 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, | |||
2658 | page = 0; | 2648 | page = 0; |
2659 | 2649 | ||
2660 | if (reg > MAX_PHY_MULTI_PAGE_REG) { | 2650 | if (reg > MAX_PHY_MULTI_PAGE_REG) { |
2661 | if ((hw->phy.type != e1000_phy_82578) || | 2651 | u32 phy_addr = hw->phy.addr; |
2662 | ((reg != I82578_ADDR_REG) && | ||
2663 | (reg != I82578_ADDR_REG + 1))) { | ||
2664 | u32 phy_addr = hw->phy.addr; | ||
2665 | 2652 | ||
2666 | hw->phy.addr = 1; | 2653 | hw->phy.addr = 1; |
2667 | 2654 | ||
2668 | /* Page is shifted left, PHY expects (page x 32) */ | 2655 | /* Page is shifted left, PHY expects (page x 32) */ |
2669 | ret_val = e1000e_write_phy_reg_mdic(hw, | 2656 | ret_val = e1000e_write_phy_reg_mdic(hw, |
2670 | IGP01E1000_PHY_PAGE_SELECT, | 2657 | IGP01E1000_PHY_PAGE_SELECT, |
2671 | (page << IGP_PAGE_SHIFT)); | 2658 | (page << IGP_PAGE_SHIFT)); |
2672 | hw->phy.addr = phy_addr; | 2659 | hw->phy.addr = phy_addr; |
2673 | } | 2660 | |
2661 | if (ret_val) | ||
2662 | goto out; | ||
2674 | } | 2663 | } |
2675 | 2664 | ||
2676 | ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, | 2665 | ret_val = e1000e_read_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, |
@@ -2678,7 +2667,7 @@ static s32 __e1000_read_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 *data, | |||
2678 | out: | 2667 | out: |
2679 | /* Revert to MDIO fast mode, if applicable */ | 2668 | /* Revert to MDIO fast mode, if applicable */ |
2680 | if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) | 2669 | if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) |
2681 | ret_val = e1000_set_mdio_slow_mode_hv(hw, false); | 2670 | ret_val |= e1000_set_mdio_slow_mode_hv(hw, false); |
2682 | 2671 | ||
2683 | if (!locked) | 2672 | if (!locked) |
2684 | hw->phy.ops.release_phy(hw); | 2673 | hw->phy.ops.release_phy(hw); |
@@ -2784,19 +2773,18 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, | |||
2784 | } | 2773 | } |
2785 | 2774 | ||
2786 | if (reg > MAX_PHY_MULTI_PAGE_REG) { | 2775 | if (reg > MAX_PHY_MULTI_PAGE_REG) { |
2787 | if ((hw->phy.type != e1000_phy_82578) || | 2776 | u32 phy_addr = hw->phy.addr; |
2788 | ((reg != I82578_ADDR_REG) && | ||
2789 | (reg != I82578_ADDR_REG + 1))) { | ||
2790 | u32 phy_addr = hw->phy.addr; | ||
2791 | 2777 | ||
2792 | hw->phy.addr = 1; | 2778 | hw->phy.addr = 1; |
2793 | 2779 | ||
2794 | /* Page is shifted left, PHY expects (page x 32) */ | 2780 | /* Page is shifted left, PHY expects (page x 32) */ |
2795 | ret_val = e1000e_write_phy_reg_mdic(hw, | 2781 | ret_val = e1000e_write_phy_reg_mdic(hw, |
2796 | IGP01E1000_PHY_PAGE_SELECT, | 2782 | IGP01E1000_PHY_PAGE_SELECT, |
2797 | (page << IGP_PAGE_SHIFT)); | 2783 | (page << IGP_PAGE_SHIFT)); |
2798 | hw->phy.addr = phy_addr; | 2784 | hw->phy.addr = phy_addr; |
2799 | } | 2785 | |
2786 | if (ret_val) | ||
2787 | goto out; | ||
2800 | } | 2788 | } |
2801 | 2789 | ||
2802 | ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, | 2790 | ret_val = e1000e_write_phy_reg_mdic(hw, MAX_PHY_REG_ADDRESS & reg, |
@@ -2805,7 +2793,7 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data, | |||
2805 | out: | 2793 | out: |
2806 | /* Revert to MDIO fast mode, if applicable */ | 2794 | /* Revert to MDIO fast mode, if applicable */ |
2807 | if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) | 2795 | if ((hw->phy.type == e1000_phy_82577) && in_slow_mode) |
2808 | ret_val = e1000_set_mdio_slow_mode_hv(hw, false); | 2796 | ret_val |= e1000_set_mdio_slow_mode_hv(hw, false); |
2809 | 2797 | ||
2810 | if (!locked) | 2798 | if (!locked) |
2811 | hw->phy.ops.release_phy(hw); | 2799 | hw->phy.ops.release_phy(hw); |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index a5036f7c1923..a456578b8578 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -240,11 +240,11 @@ static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter, | |||
240 | static inline bool ixgbe_tx_is_paused(struct ixgbe_adapter *adapter, | 240 | static inline bool ixgbe_tx_is_paused(struct ixgbe_adapter *adapter, |
241 | struct ixgbe_ring *tx_ring) | 241 | struct ixgbe_ring *tx_ring) |
242 | { | 242 | { |
243 | int tc; | ||
244 | u32 txoff = IXGBE_TFCS_TXOFF; | 243 | u32 txoff = IXGBE_TFCS_TXOFF; |
245 | 244 | ||
246 | #ifdef CONFIG_IXGBE_DCB | 245 | #ifdef CONFIG_IXGBE_DCB |
247 | if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { | 246 | if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) { |
247 | int tc; | ||
248 | int reg_idx = tx_ring->reg_idx; | 248 | int reg_idx = tx_ring->reg_idx; |
249 | int dcb_i = adapter->ring_feature[RING_F_DCB].indices; | 249 | int dcb_i = adapter->ring_feature[RING_F_DCB].indices; |
250 | 250 | ||
diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c index 0be14d702beb..c146304d8d6c 100644 --- a/drivers/net/ks8851_mll.c +++ b/drivers/net/ks8851_mll.c | |||
@@ -568,6 +568,16 @@ static inline void ks_outblk(struct ks_net *ks, u16 *wptr, u32 len) | |||
568 | iowrite16(*wptr++, ks->hw_addr); | 568 | iowrite16(*wptr++, ks->hw_addr); |
569 | } | 569 | } |
570 | 570 | ||
571 | static void ks_disable_int(struct ks_net *ks) | ||
572 | { | ||
573 | ks_wrreg16(ks, KS_IER, 0x0000); | ||
574 | } /* ks_disable_int */ | ||
575 | |||
576 | static void ks_enable_int(struct ks_net *ks) | ||
577 | { | ||
578 | ks_wrreg16(ks, KS_IER, ks->rc_ier); | ||
579 | } /* ks_enable_int */ | ||
580 | |||
571 | /** | 581 | /** |
572 | * ks_tx_fifo_space - return the available hardware buffer size. | 582 | * ks_tx_fifo_space - return the available hardware buffer size. |
573 | * @ks: The chip information | 583 | * @ks: The chip information |
@@ -681,6 +691,47 @@ static void ks_soft_reset(struct ks_net *ks, unsigned op) | |||
681 | } | 691 | } |
682 | 692 | ||
683 | 693 | ||
694 | void ks_enable_qmu(struct ks_net *ks) | ||
695 | { | ||
696 | u16 w; | ||
697 | |||
698 | w = ks_rdreg16(ks, KS_TXCR); | ||
699 | /* Enables QMU Transmit (TXCR). */ | ||
700 | ks_wrreg16(ks, KS_TXCR, w | TXCR_TXE); | ||
701 | |||
702 | /* | ||
703 | * RX Frame Count Threshold Enable and Auto-Dequeue RXQ Frame | ||
704 | * Enable | ||
705 | */ | ||
706 | |||
707 | w = ks_rdreg16(ks, KS_RXQCR); | ||
708 | ks_wrreg16(ks, KS_RXQCR, w | RXQCR_RXFCTE); | ||
709 | |||
710 | /* Enables QMU Receive (RXCR1). */ | ||
711 | w = ks_rdreg16(ks, KS_RXCR1); | ||
712 | ks_wrreg16(ks, KS_RXCR1, w | RXCR1_RXE); | ||
713 | ks->enabled = true; | ||
714 | } /* ks_enable_qmu */ | ||
715 | |||
716 | static void ks_disable_qmu(struct ks_net *ks) | ||
717 | { | ||
718 | u16 w; | ||
719 | |||
720 | w = ks_rdreg16(ks, KS_TXCR); | ||
721 | |||
722 | /* Disables QMU Transmit (TXCR). */ | ||
723 | w &= ~TXCR_TXE; | ||
724 | ks_wrreg16(ks, KS_TXCR, w); | ||
725 | |||
726 | /* Disables QMU Receive (RXCR1). */ | ||
727 | w = ks_rdreg16(ks, KS_RXCR1); | ||
728 | w &= ~RXCR1_RXE ; | ||
729 | ks_wrreg16(ks, KS_RXCR1, w); | ||
730 | |||
731 | ks->enabled = false; | ||
732 | |||
733 | } /* ks_disable_qmu */ | ||
734 | |||
684 | /** | 735 | /** |
685 | * ks_read_qmu - read 1 pkt data from the QMU. | 736 | * ks_read_qmu - read 1 pkt data from the QMU. |
686 | * @ks: The chip information | 737 | * @ks: The chip information |
@@ -752,7 +803,7 @@ static void ks_rcv(struct ks_net *ks, struct net_device *netdev) | |||
752 | (frame_hdr->len < RX_BUF_SIZE) && frame_hdr->len)) { | 803 | (frame_hdr->len < RX_BUF_SIZE) && frame_hdr->len)) { |
753 | skb_reserve(skb, 2); | 804 | skb_reserve(skb, 2); |
754 | /* read data block including CRC 4 bytes */ | 805 | /* read data block including CRC 4 bytes */ |
755 | ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len + 4); | 806 | ks_read_qmu(ks, (u16 *)skb->data, frame_hdr->len); |
756 | skb_put(skb, frame_hdr->len); | 807 | skb_put(skb, frame_hdr->len); |
757 | skb->dev = netdev; | 808 | skb->dev = netdev; |
758 | skb->protocol = eth_type_trans(skb, netdev); | 809 | skb->protocol = eth_type_trans(skb, netdev); |
@@ -861,7 +912,7 @@ static int ks_net_open(struct net_device *netdev) | |||
861 | ks_dbg(ks, "%s - entry\n", __func__); | 912 | ks_dbg(ks, "%s - entry\n", __func__); |
862 | 913 | ||
863 | /* reset the HW */ | 914 | /* reset the HW */ |
864 | err = request_irq(ks->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, ks); | 915 | err = request_irq(ks->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, netdev); |
865 | 916 | ||
866 | if (err) { | 917 | if (err) { |
867 | printk(KERN_ERR "Failed to request IRQ: %d: %d\n", | 918 | printk(KERN_ERR "Failed to request IRQ: %d: %d\n", |
@@ -869,6 +920,15 @@ static int ks_net_open(struct net_device *netdev) | |||
869 | return err; | 920 | return err; |
870 | } | 921 | } |
871 | 922 | ||
923 | /* wake up powermode to normal mode */ | ||
924 | ks_set_powermode(ks, PMECR_PM_NORMAL); | ||
925 | mdelay(1); /* wait for normal mode to take effect */ | ||
926 | |||
927 | ks_wrreg16(ks, KS_ISR, 0xffff); | ||
928 | ks_enable_int(ks); | ||
929 | ks_enable_qmu(ks); | ||
930 | netif_start_queue(ks->netdev); | ||
931 | |||
872 | if (netif_msg_ifup(ks)) | 932 | if (netif_msg_ifup(ks)) |
873 | ks_dbg(ks, "network device %s up\n", netdev->name); | 933 | ks_dbg(ks, "network device %s up\n", netdev->name); |
874 | 934 | ||
@@ -892,19 +952,14 @@ static int ks_net_stop(struct net_device *netdev) | |||
892 | 952 | ||
893 | netif_stop_queue(netdev); | 953 | netif_stop_queue(netdev); |
894 | 954 | ||
895 | kfree(ks->frame_head_info); | ||
896 | |||
897 | mutex_lock(&ks->lock); | 955 | mutex_lock(&ks->lock); |
898 | 956 | ||
899 | /* turn off the IRQs and ack any outstanding */ | 957 | /* turn off the IRQs and ack any outstanding */ |
900 | ks_wrreg16(ks, KS_IER, 0x0000); | 958 | ks_wrreg16(ks, KS_IER, 0x0000); |
901 | ks_wrreg16(ks, KS_ISR, 0xffff); | 959 | ks_wrreg16(ks, KS_ISR, 0xffff); |
902 | 960 | ||
903 | /* shutdown RX process */ | 961 | /* shutdown RX/TX QMU */ |
904 | ks_wrreg16(ks, KS_RXCR1, 0x0000); | 962 | ks_disable_qmu(ks); |
905 | |||
906 | /* shutdown TX process */ | ||
907 | ks_wrreg16(ks, KS_TXCR, 0x0000); | ||
908 | 963 | ||
909 | /* set powermode to soft power down to save power */ | 964 | /* set powermode to soft power down to save power */ |
910 | ks_set_powermode(ks, PMECR_PM_SOFTDOWN); | 965 | ks_set_powermode(ks, PMECR_PM_SOFTDOWN); |
@@ -929,17 +984,8 @@ static int ks_net_stop(struct net_device *netdev) | |||
929 | */ | 984 | */ |
930 | static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len) | 985 | static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len) |
931 | { | 986 | { |
932 | unsigned fid = ks->fid; | ||
933 | |||
934 | fid = ks->fid; | ||
935 | ks->fid = (ks->fid + 1) & TXFR_TXFID_MASK; | ||
936 | |||
937 | /* reduce the tx interrupt occurrances. */ | ||
938 | if (!fid) | ||
939 | fid |= TXFR_TXIC; /* irq on completion */ | ||
940 | |||
941 | /* start header at txb[0] to align txw entries */ | 987 | /* start header at txb[0] to align txw entries */ |
942 | ks->txh.txw[0] = cpu_to_le16(fid); | 988 | ks->txh.txw[0] = 0; |
943 | ks->txh.txw[1] = cpu_to_le16(len); | 989 | ks->txh.txw[1] = cpu_to_le16(len); |
944 | 990 | ||
945 | /* 1. set sudo-DMA mode */ | 991 | /* 1. set sudo-DMA mode */ |
@@ -957,16 +1003,6 @@ static void ks_write_qmu(struct ks_net *ks, u8 *pdata, u16 len) | |||
957 | ; | 1003 | ; |
958 | } | 1004 | } |
959 | 1005 | ||
960 | static void ks_disable_int(struct ks_net *ks) | ||
961 | { | ||
962 | ks_wrreg16(ks, KS_IER, 0x0000); | ||
963 | } /* ks_disable_int */ | ||
964 | |||
965 | static void ks_enable_int(struct ks_net *ks) | ||
966 | { | ||
967 | ks_wrreg16(ks, KS_IER, ks->rc_ier); | ||
968 | } /* ks_enable_int */ | ||
969 | |||
970 | /** | 1006 | /** |
971 | * ks_start_xmit - transmit packet | 1007 | * ks_start_xmit - transmit packet |
972 | * @skb : The buffer to transmit | 1008 | * @skb : The buffer to transmit |
@@ -1410,25 +1446,6 @@ static int ks_read_selftest(struct ks_net *ks) | |||
1410 | return ret; | 1446 | return ret; |
1411 | } | 1447 | } |
1412 | 1448 | ||
1413 | static void ks_disable(struct ks_net *ks) | ||
1414 | { | ||
1415 | u16 w; | ||
1416 | |||
1417 | w = ks_rdreg16(ks, KS_TXCR); | ||
1418 | |||
1419 | /* Disables QMU Transmit (TXCR). */ | ||
1420 | w &= ~TXCR_TXE; | ||
1421 | ks_wrreg16(ks, KS_TXCR, w); | ||
1422 | |||
1423 | /* Disables QMU Receive (RXCR1). */ | ||
1424 | w = ks_rdreg16(ks, KS_RXCR1); | ||
1425 | w &= ~RXCR1_RXE ; | ||
1426 | ks_wrreg16(ks, KS_RXCR1, w); | ||
1427 | |||
1428 | ks->enabled = false; | ||
1429 | |||
1430 | } /* ks_disable */ | ||
1431 | |||
1432 | static void ks_setup(struct ks_net *ks) | 1449 | static void ks_setup(struct ks_net *ks) |
1433 | { | 1450 | { |
1434 | u16 w; | 1451 | u16 w; |
@@ -1463,7 +1480,7 @@ static void ks_setup(struct ks_net *ks) | |||
1463 | w = TXCR_TXFCE | TXCR_TXPE | TXCR_TXCRC | TXCR_TCGIP; | 1480 | w = TXCR_TXFCE | TXCR_TXPE | TXCR_TXCRC | TXCR_TCGIP; |
1464 | ks_wrreg16(ks, KS_TXCR, w); | 1481 | ks_wrreg16(ks, KS_TXCR, w); |
1465 | 1482 | ||
1466 | w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE; | 1483 | w = RXCR1_RXFCE | RXCR1_RXBE | RXCR1_RXUE | RXCR1_RXME | RXCR1_RXIPFCC; |
1467 | 1484 | ||
1468 | if (ks->promiscuous) /* bPromiscuous */ | 1485 | if (ks->promiscuous) /* bPromiscuous */ |
1469 | w |= (RXCR1_RXAE | RXCR1_RXINVF); | 1486 | w |= (RXCR1_RXAE | RXCR1_RXINVF); |
@@ -1486,28 +1503,6 @@ static void ks_setup_int(struct ks_net *ks) | |||
1486 | ks->rc_ier = (IRQ_LCI | IRQ_TXI | IRQ_RXI); | 1503 | ks->rc_ier = (IRQ_LCI | IRQ_TXI | IRQ_RXI); |
1487 | } /* ks_setup_int */ | 1504 | } /* ks_setup_int */ |
1488 | 1505 | ||
1489 | void ks_enable(struct ks_net *ks) | ||
1490 | { | ||
1491 | u16 w; | ||
1492 | |||
1493 | w = ks_rdreg16(ks, KS_TXCR); | ||
1494 | /* Enables QMU Transmit (TXCR). */ | ||
1495 | ks_wrreg16(ks, KS_TXCR, w | TXCR_TXE); | ||
1496 | |||
1497 | /* | ||
1498 | * RX Frame Count Threshold Enable and Auto-Dequeue RXQ Frame | ||
1499 | * Enable | ||
1500 | */ | ||
1501 | |||
1502 | w = ks_rdreg16(ks, KS_RXQCR); | ||
1503 | ks_wrreg16(ks, KS_RXQCR, w | RXQCR_RXFCTE); | ||
1504 | |||
1505 | /* Enables QMU Receive (RXCR1). */ | ||
1506 | w = ks_rdreg16(ks, KS_RXCR1); | ||
1507 | ks_wrreg16(ks, KS_RXCR1, w | RXCR1_RXE); | ||
1508 | ks->enabled = true; | ||
1509 | } /* ks_enable */ | ||
1510 | |||
1511 | static int ks_hw_init(struct ks_net *ks) | 1506 | static int ks_hw_init(struct ks_net *ks) |
1512 | { | 1507 | { |
1513 | #define MHEADER_SIZE (sizeof(struct type_frame_head) * MAX_RECV_FRAMES) | 1508 | #define MHEADER_SIZE (sizeof(struct type_frame_head) * MAX_RECV_FRAMES) |
@@ -1612,11 +1607,9 @@ static int __devinit ks8851_probe(struct platform_device *pdev) | |||
1612 | 1607 | ||
1613 | ks_soft_reset(ks, GRR_GSR); | 1608 | ks_soft_reset(ks, GRR_GSR); |
1614 | ks_hw_init(ks); | 1609 | ks_hw_init(ks); |
1615 | ks_disable(ks); | 1610 | ks_disable_qmu(ks); |
1616 | ks_setup(ks); | 1611 | ks_setup(ks); |
1617 | ks_setup_int(ks); | 1612 | ks_setup_int(ks); |
1618 | ks_enable_int(ks); | ||
1619 | ks_enable(ks); | ||
1620 | memcpy(netdev->dev_addr, ks->mac_addr, 6); | 1613 | memcpy(netdev->dev_addr, ks->mac_addr, 6); |
1621 | 1614 | ||
1622 | data = ks_rdreg16(ks, KS_OBCR); | 1615 | data = ks_rdreg16(ks, KS_OBCR); |
@@ -1658,6 +1651,7 @@ static int __devexit ks8851_remove(struct platform_device *pdev) | |||
1658 | struct ks_net *ks = netdev_priv(netdev); | 1651 | struct ks_net *ks = netdev_priv(netdev); |
1659 | struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1652 | struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1660 | 1653 | ||
1654 | kfree(ks->frame_head_info); | ||
1661 | unregister_netdev(netdev); | 1655 | unregister_netdev(netdev); |
1662 | iounmap(ks->hw_addr); | 1656 | iounmap(ks->hw_addr); |
1663 | free_netdev(netdev); | 1657 | free_netdev(netdev); |
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 3aabfd9dd212..2490aa39804c 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
@@ -360,6 +360,7 @@ static int macvlan_init(struct net_device *dev) | |||
360 | dev->state = (dev->state & ~MACVLAN_STATE_MASK) | | 360 | dev->state = (dev->state & ~MACVLAN_STATE_MASK) | |
361 | (lowerdev->state & MACVLAN_STATE_MASK); | 361 | (lowerdev->state & MACVLAN_STATE_MASK); |
362 | dev->features = lowerdev->features & MACVLAN_FEATURES; | 362 | dev->features = lowerdev->features & MACVLAN_FEATURES; |
363 | dev->gso_max_size = lowerdev->gso_max_size; | ||
363 | dev->iflink = lowerdev->ifindex; | 364 | dev->iflink = lowerdev->ifindex; |
364 | dev->hard_header_len = lowerdev->hard_header_len; | 365 | dev->hard_header_len = lowerdev->hard_header_len; |
365 | 366 | ||
@@ -596,6 +597,7 @@ static int macvlan_device_event(struct notifier_block *unused, | |||
596 | case NETDEV_FEAT_CHANGE: | 597 | case NETDEV_FEAT_CHANGE: |
597 | list_for_each_entry(vlan, &port->vlans, list) { | 598 | list_for_each_entry(vlan, &port->vlans, list) { |
598 | vlan->dev->features = dev->features & MACVLAN_FEATURES; | 599 | vlan->dev->features = dev->features & MACVLAN_FEATURES; |
600 | vlan->dev->gso_max_size = dev->gso_max_size; | ||
599 | netdev_features_change(vlan->dev); | 601 | netdev_features_change(vlan->dev); |
600 | } | 602 | } |
601 | break; | 603 | break; |
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h index 7384f59df615..e1237b802872 100644 --- a/drivers/net/netxen/netxen_nic.h +++ b/drivers/net/netxen/netxen_nic.h | |||
@@ -1163,6 +1163,8 @@ struct netxen_adapter { | |||
1163 | u32 int_vec_bit; | 1163 | u32 int_vec_bit; |
1164 | u32 heartbit; | 1164 | u32 heartbit; |
1165 | 1165 | ||
1166 | u8 mac_addr[ETH_ALEN]; | ||
1167 | |||
1166 | struct netxen_adapter_stats stats; | 1168 | struct netxen_adapter_stats stats; |
1167 | 1169 | ||
1168 | struct netxen_recv_context recv_ctx; | 1170 | struct netxen_recv_context recv_ctx; |
diff --git a/drivers/net/netxen/netxen_nic_hdr.h b/drivers/net/netxen/netxen_nic_hdr.h index 1c46da632125..17bb3818d84e 100644 --- a/drivers/net/netxen/netxen_nic_hdr.h +++ b/drivers/net/netxen/netxen_nic_hdr.h | |||
@@ -545,6 +545,8 @@ enum { | |||
545 | #define NETXEN_NIU_TEST_MUX_CTL (NETXEN_CRB_NIU + 0x00094) | 545 | #define NETXEN_NIU_TEST_MUX_CTL (NETXEN_CRB_NIU + 0x00094) |
546 | #define NETXEN_NIU_XG_PAUSE_CTL (NETXEN_CRB_NIU + 0x00098) | 546 | #define NETXEN_NIU_XG_PAUSE_CTL (NETXEN_CRB_NIU + 0x00098) |
547 | #define NETXEN_NIU_XG_PAUSE_LEVEL (NETXEN_CRB_NIU + 0x000dc) | 547 | #define NETXEN_NIU_XG_PAUSE_LEVEL (NETXEN_CRB_NIU + 0x000dc) |
548 | #define NETXEN_NIU_FRAME_COUNT_SELECT (NETXEN_CRB_NIU + 0x000ac) | ||
549 | #define NETXEN_NIU_FRAME_COUNT (NETXEN_CRB_NIU + 0x000b0) | ||
548 | #define NETXEN_NIU_XG_SEL (NETXEN_CRB_NIU + 0x00128) | 550 | #define NETXEN_NIU_XG_SEL (NETXEN_CRB_NIU + 0x00128) |
549 | #define NETXEN_NIU_GB_PAUSE_CTL (NETXEN_CRB_NIU + 0x0030c) | 551 | #define NETXEN_NIU_GB_PAUSE_CTL (NETXEN_CRB_NIU + 0x0030c) |
550 | 552 | ||
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c index 3185a98b0917..52a3798d8d94 100644 --- a/drivers/net/netxen/netxen_nic_hw.c +++ b/drivers/net/netxen/netxen_nic_hw.c | |||
@@ -383,24 +383,51 @@ int netxen_niu_disable_xg_port(struct netxen_adapter *adapter) | |||
383 | 383 | ||
384 | int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) | 384 | int netxen_p2_nic_set_promisc(struct netxen_adapter *adapter, u32 mode) |
385 | { | 385 | { |
386 | __u32 reg; | 386 | u32 mac_cfg; |
387 | u32 cnt = 0; | ||
388 | __u32 reg = 0x0200; | ||
387 | u32 port = adapter->physical_port; | 389 | u32 port = adapter->physical_port; |
390 | u16 board_type = adapter->ahw.board_type; | ||
388 | 391 | ||
389 | if (port > NETXEN_NIU_MAX_XG_PORTS) | 392 | if (port > NETXEN_NIU_MAX_XG_PORTS) |
390 | return -EINVAL; | 393 | return -EINVAL; |
391 | 394 | ||
392 | reg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port)); | 395 | mac_cfg = NXRD32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port)); |
393 | if (mode == NETXEN_NIU_PROMISC_MODE) | 396 | mac_cfg &= ~0x4; |
394 | reg = (reg | 0x2000UL); | 397 | NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg); |
395 | else | ||
396 | reg = (reg & ~0x2000UL); | ||
397 | 398 | ||
398 | if (mode == NETXEN_NIU_ALLMULTI_MODE) | 399 | if ((board_type == NETXEN_BRDTYPE_P2_SB31_10G_IMEZ) || |
399 | reg = (reg | 0x1000UL); | 400 | (board_type == NETXEN_BRDTYPE_P2_SB31_10G_HMEZ)) |
400 | else | 401 | reg = (0x20 << port); |
401 | reg = (reg & ~0x1000UL); | 402 | |
403 | NXWR32(adapter, NETXEN_NIU_FRAME_COUNT_SELECT, reg); | ||
404 | |||
405 | mdelay(10); | ||
406 | |||
407 | while (NXRD32(adapter, NETXEN_NIU_FRAME_COUNT) && ++cnt < 20) | ||
408 | mdelay(10); | ||
409 | |||
410 | if (cnt < 20) { | ||
411 | |||
412 | reg = NXRD32(adapter, | ||
413 | NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port)); | ||
414 | |||
415 | if (mode == NETXEN_NIU_PROMISC_MODE) | ||
416 | reg = (reg | 0x2000UL); | ||
417 | else | ||
418 | reg = (reg & ~0x2000UL); | ||
419 | |||
420 | if (mode == NETXEN_NIU_ALLMULTI_MODE) | ||
421 | reg = (reg | 0x1000UL); | ||
422 | else | ||
423 | reg = (reg & ~0x1000UL); | ||
424 | |||
425 | NXWR32(adapter, | ||
426 | NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg); | ||
427 | } | ||
402 | 428 | ||
403 | NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_1 + (0x10000 * port), reg); | 429 | mac_cfg |= 0x4; |
430 | NXWR32(adapter, NETXEN_NIU_XGE_CONFIG_0 + (0x10000 * port), mac_cfg); | ||
404 | 431 | ||
405 | return 0; | 432 | return 0; |
406 | } | 433 | } |
@@ -436,7 +463,7 @@ netxen_nic_enable_mcast_filter(struct netxen_adapter *adapter) | |||
436 | { | 463 | { |
437 | u32 val = 0; | 464 | u32 val = 0; |
438 | u16 port = adapter->physical_port; | 465 | u16 port = adapter->physical_port; |
439 | u8 *addr = adapter->netdev->dev_addr; | 466 | u8 *addr = adapter->mac_addr; |
440 | 467 | ||
441 | if (adapter->mc_enabled) | 468 | if (adapter->mc_enabled) |
442 | return 0; | 469 | return 0; |
@@ -465,7 +492,7 @@ netxen_nic_disable_mcast_filter(struct netxen_adapter *adapter) | |||
465 | { | 492 | { |
466 | u32 val = 0; | 493 | u32 val = 0; |
467 | u16 port = adapter->physical_port; | 494 | u16 port = adapter->physical_port; |
468 | u8 *addr = adapter->netdev->dev_addr; | 495 | u8 *addr = adapter->mac_addr; |
469 | 496 | ||
470 | if (!adapter->mc_enabled) | 497 | if (!adapter->mc_enabled) |
471 | return 0; | 498 | return 0; |
@@ -660,7 +687,7 @@ void netxen_p3_nic_set_multi(struct net_device *netdev) | |||
660 | 687 | ||
661 | list_splice_tail_init(&adapter->mac_list, &del_list); | 688 | list_splice_tail_init(&adapter->mac_list, &del_list); |
662 | 689 | ||
663 | nx_p3_nic_add_mac(adapter, netdev->dev_addr, &del_list); | 690 | nx_p3_nic_add_mac(adapter, adapter->mac_addr, &del_list); |
664 | nx_p3_nic_add_mac(adapter, bcast_addr, &del_list); | 691 | nx_p3_nic_add_mac(adapter, bcast_addr, &del_list); |
665 | 692 | ||
666 | if (netdev->flags & IFF_PROMISC) { | 693 | if (netdev->flags & IFF_PROMISC) { |
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c index e40b914d6faf..8a0904368e08 100644 --- a/drivers/net/netxen/netxen_nic_init.c +++ b/drivers/net/netxen/netxen_nic_init.c | |||
@@ -544,6 +544,8 @@ int netxen_pinit_from_rom(struct netxen_adapter *adapter, int verbose) | |||
544 | continue; | 544 | continue; |
545 | if (off == (ROMUSB_GLB + 0x1c)) /* MS clock */ | 545 | if (off == (ROMUSB_GLB + 0x1c)) /* MS clock */ |
546 | continue; | 546 | continue; |
547 | if ((off & 0x0ff00000) == NETXEN_CRB_DDR_NET) | ||
548 | continue; | ||
547 | if (off == (NETXEN_CRB_PEG_NET_1 + 0x18)) | 549 | if (off == (NETXEN_CRB_PEG_NET_1 + 0x18)) |
548 | buf[i].data = 0x1020; | 550 | buf[i].data = 0x1020; |
549 | /* skip the function enable register */ | 551 | /* skip the function enable register */ |
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 0b4a56a8c8d5..3bf78dbfbf0f 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -437,6 +437,7 @@ netxen_read_mac_addr(struct netxen_adapter *adapter) | |||
437 | netdev->dev_addr[i] = *(p + 5 - i); | 437 | netdev->dev_addr[i] = *(p + 5 - i); |
438 | 438 | ||
439 | memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len); | 439 | memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len); |
440 | memcpy(adapter->mac_addr, netdev->dev_addr, netdev->addr_len); | ||
440 | 441 | ||
441 | /* set station address */ | 442 | /* set station address */ |
442 | 443 | ||
@@ -459,6 +460,7 @@ int netxen_nic_set_mac(struct net_device *netdev, void *p) | |||
459 | netxen_napi_disable(adapter); | 460 | netxen_napi_disable(adapter); |
460 | } | 461 | } |
461 | 462 | ||
463 | memcpy(adapter->mac_addr, addr->sa_data, netdev->addr_len); | ||
462 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); | 464 | memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len); |
463 | adapter->macaddr_set(adapter, addr->sa_data); | 465 | adapter->macaddr_set(adapter, addr->sa_data); |
464 | 466 | ||
@@ -956,7 +958,7 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev) | |||
956 | return err; | 958 | return err; |
957 | } | 959 | } |
958 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) | 960 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) |
959 | adapter->macaddr_set(adapter, netdev->dev_addr); | 961 | adapter->macaddr_set(adapter, adapter->mac_addr); |
960 | 962 | ||
961 | adapter->set_multi(netdev); | 963 | adapter->set_multi(netdev); |
962 | adapter->set_mtu(adapter, netdev->mtu); | 964 | adapter->set_mtu(adapter, netdev->mtu); |
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index b9221bdc7184..0fe2fc90f207 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -3235,6 +3235,10 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev) | |||
3235 | flush_scheduled_work(); | 3235 | flush_scheduled_work(); |
3236 | 3236 | ||
3237 | unregister_netdev(dev); | 3237 | unregister_netdev(dev); |
3238 | |||
3239 | /* restore original MAC address */ | ||
3240 | rtl_rar_set(tp, dev->perm_addr); | ||
3241 | |||
3238 | rtl_disable_msi(pdev, tp); | 3242 | rtl_disable_msi(pdev, tp); |
3239 | rtl8169_release_board(pdev, dev, tp->mmio_addr); | 3243 | rtl8169_release_board(pdev, dev, tp->mmio_addr); |
3240 | pci_set_drvdata(pdev, NULL); | 3244 | pci_set_drvdata(pdev, NULL); |
@@ -4881,6 +4885,9 @@ static void rtl_shutdown(struct pci_dev *pdev) | |||
4881 | 4885 | ||
4882 | rtl8169_net_suspend(dev); | 4886 | rtl8169_net_suspend(dev); |
4883 | 4887 | ||
4888 | /* restore original MAC address */ | ||
4889 | rtl_rar_set(tp, dev->perm_addr); | ||
4890 | |||
4884 | spin_lock_irq(&tp->lock); | 4891 | spin_lock_irq(&tp->lock); |
4885 | 4892 | ||
4886 | rtl8169_asic_down(ioaddr); | 4893 | rtl8169_asic_down(ioaddr); |
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c index 05c91ee6921e..f12206bdbb75 100644 --- a/drivers/net/smc91x.c +++ b/drivers/net/smc91x.c | |||
@@ -2283,7 +2283,7 @@ static int __devinit smc_drv_probe(struct platform_device *pdev) | |||
2283 | 2283 | ||
2284 | ndev->irq = ires->start; | 2284 | ndev->irq = ires->start; |
2285 | 2285 | ||
2286 | if (ires->flags & IRQF_TRIGGER_MASK) | 2286 | if (irq_flags == -1 || ires->flags & IRQF_TRIGGER_MASK) |
2287 | irq_flags = ires->flags & IRQF_TRIGGER_MASK; | 2287 | irq_flags = ires->flags & IRQF_TRIGGER_MASK; |
2288 | 2288 | ||
2289 | ret = smc_request_attrib(pdev, ndev); | 2289 | ret = smc_request_attrib(pdev, ndev); |
diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c index b4909a2dec66..0f7909276237 100644 --- a/drivers/net/smsc9420.c +++ b/drivers/net/smsc9420.c | |||
@@ -252,6 +252,9 @@ static int smsc9420_ethtool_get_settings(struct net_device *dev, | |||
252 | { | 252 | { |
253 | struct smsc9420_pdata *pd = netdev_priv(dev); | 253 | struct smsc9420_pdata *pd = netdev_priv(dev); |
254 | 254 | ||
255 | if (!pd->phy_dev) | ||
256 | return -ENODEV; | ||
257 | |||
255 | cmd->maxtxpkt = 1; | 258 | cmd->maxtxpkt = 1; |
256 | cmd->maxrxpkt = 1; | 259 | cmd->maxrxpkt = 1; |
257 | return phy_ethtool_gset(pd->phy_dev, cmd); | 260 | return phy_ethtool_gset(pd->phy_dev, cmd); |
@@ -262,6 +265,9 @@ static int smsc9420_ethtool_set_settings(struct net_device *dev, | |||
262 | { | 265 | { |
263 | struct smsc9420_pdata *pd = netdev_priv(dev); | 266 | struct smsc9420_pdata *pd = netdev_priv(dev); |
264 | 267 | ||
268 | if (!pd->phy_dev) | ||
269 | return -ENODEV; | ||
270 | |||
265 | return phy_ethtool_sset(pd->phy_dev, cmd); | 271 | return phy_ethtool_sset(pd->phy_dev, cmd); |
266 | } | 272 | } |
267 | 273 | ||
@@ -290,6 +296,10 @@ static void smsc9420_ethtool_set_msglevel(struct net_device *netdev, u32 data) | |||
290 | static int smsc9420_ethtool_nway_reset(struct net_device *netdev) | 296 | static int smsc9420_ethtool_nway_reset(struct net_device *netdev) |
291 | { | 297 | { |
292 | struct smsc9420_pdata *pd = netdev_priv(netdev); | 298 | struct smsc9420_pdata *pd = netdev_priv(netdev); |
299 | |||
300 | if (!pd->phy_dev) | ||
301 | return -ENODEV; | ||
302 | |||
293 | return phy_start_aneg(pd->phy_dev); | 303 | return phy_start_aneg(pd->phy_dev); |
294 | } | 304 | } |
295 | 305 | ||
@@ -312,6 +322,10 @@ smsc9420_ethtool_getregs(struct net_device *dev, struct ethtool_regs *regs, | |||
312 | for (i = 0; i < 0x100; i += (sizeof(u32))) | 322 | for (i = 0; i < 0x100; i += (sizeof(u32))) |
313 | data[j++] = smsc9420_reg_read(pd, i); | 323 | data[j++] = smsc9420_reg_read(pd, i); |
314 | 324 | ||
325 | // cannot read phy registers if the net device is down | ||
326 | if (!phy_dev) | ||
327 | return; | ||
328 | |||
315 | for (i = 0; i <= 31; i++) | 329 | for (i = 0; i <= 31; i++) |
316 | data[j++] = smsc9420_mii_read(phy_dev->bus, phy_dev->addr, i); | 330 | data[j++] = smsc9420_mii_read(phy_dev->bus, phy_dev->addr, i); |
317 | } | 331 | } |
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index c2f14dc9ba28..9542995ba667 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c | |||
@@ -416,13 +416,8 @@ static void init_dma_desc_rings(struct net_device *dev) | |||
416 | unsigned int txsize = priv->dma_tx_size; | 416 | unsigned int txsize = priv->dma_tx_size; |
417 | unsigned int rxsize = priv->dma_rx_size; | 417 | unsigned int rxsize = priv->dma_rx_size; |
418 | unsigned int bfsize = priv->dma_buf_sz; | 418 | unsigned int bfsize = priv->dma_buf_sz; |
419 | int buff2_needed = 0; | 419 | int buff2_needed = 0, dis_ic = 0; |
420 | int dis_ic = 0; | ||
421 | 420 | ||
422 | #ifdef CONFIG_STMMAC_TIMER | ||
423 | /* Using Timers disable interrupts on completion for the reception */ | ||
424 | dis_ic = 1; | ||
425 | #endif | ||
426 | /* Set the Buffer size according to the MTU; | 421 | /* Set the Buffer size according to the MTU; |
427 | * indeed, in case of jumbo we need to bump-up the buffer sizes. | 422 | * indeed, in case of jumbo we need to bump-up the buffer sizes. |
428 | */ | 423 | */ |
@@ -437,6 +432,11 @@ static void init_dma_desc_rings(struct net_device *dev) | |||
437 | else | 432 | else |
438 | bfsize = DMA_BUFFER_SIZE; | 433 | bfsize = DMA_BUFFER_SIZE; |
439 | 434 | ||
435 | #ifdef CONFIG_STMMAC_TIMER | ||
436 | /* Disable interrupts on completion for the reception if timer is on */ | ||
437 | if (likely(priv->tm->enable)) | ||
438 | dis_ic = 1; | ||
439 | #endif | ||
440 | /* If the MTU exceeds 8k so use the second buffer in the chain */ | 440 | /* If the MTU exceeds 8k so use the second buffer in the chain */ |
441 | if (bfsize >= BUF_SIZE_8KiB) | 441 | if (bfsize >= BUF_SIZE_8KiB) |
442 | buff2_needed = 1; | 442 | buff2_needed = 1; |
@@ -809,20 +809,22 @@ static void stmmac_tx(struct stmmac_priv *priv) | |||
809 | 809 | ||
810 | static inline void stmmac_enable_irq(struct stmmac_priv *priv) | 810 | static inline void stmmac_enable_irq(struct stmmac_priv *priv) |
811 | { | 811 | { |
812 | #ifndef CONFIG_STMMAC_TIMER | 812 | #ifdef CONFIG_STMMAC_TIMER |
813 | writel(DMA_INTR_DEFAULT_MASK, priv->dev->base_addr + DMA_INTR_ENA); | 813 | if (likely(priv->tm->enable)) |
814 | #else | 814 | priv->tm->timer_start(tmrate); |
815 | priv->tm->timer_start(tmrate); | 815 | else |
816 | #endif | 816 | #endif |
817 | writel(DMA_INTR_DEFAULT_MASK, priv->dev->base_addr + DMA_INTR_ENA); | ||
817 | } | 818 | } |
818 | 819 | ||
819 | static inline void stmmac_disable_irq(struct stmmac_priv *priv) | 820 | static inline void stmmac_disable_irq(struct stmmac_priv *priv) |
820 | { | 821 | { |
821 | #ifndef CONFIG_STMMAC_TIMER | 822 | #ifdef CONFIG_STMMAC_TIMER |
822 | writel(0, priv->dev->base_addr + DMA_INTR_ENA); | 823 | if (likely(priv->tm->enable)) |
823 | #else | 824 | priv->tm->timer_stop(); |
824 | priv->tm->timer_stop(); | 825 | else |
825 | #endif | 826 | #endif |
827 | writel(0, priv->dev->base_addr + DMA_INTR_ENA); | ||
826 | } | 828 | } |
827 | 829 | ||
828 | static int stmmac_has_work(struct stmmac_priv *priv) | 830 | static int stmmac_has_work(struct stmmac_priv *priv) |
@@ -1031,22 +1033,23 @@ static int stmmac_open(struct net_device *dev) | |||
1031 | } | 1033 | } |
1032 | 1034 | ||
1033 | #ifdef CONFIG_STMMAC_TIMER | 1035 | #ifdef CONFIG_STMMAC_TIMER |
1034 | priv->tm = kmalloc(sizeof(struct stmmac_timer *), GFP_KERNEL); | 1036 | priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL); |
1035 | if (unlikely(priv->tm == NULL)) { | 1037 | if (unlikely(priv->tm == NULL)) { |
1036 | pr_err("%s: ERROR: timer memory alloc failed \n", __func__); | 1038 | pr_err("%s: ERROR: timer memory alloc failed \n", __func__); |
1037 | return -ENOMEM; | 1039 | return -ENOMEM; |
1038 | } | 1040 | } |
1039 | priv->tm->freq = tmrate; | 1041 | priv->tm->freq = tmrate; |
1040 | 1042 | ||
1041 | /* Test if the HW timer can be actually used. | 1043 | /* Test if the external timer can be actually used. |
1042 | * In case of failure continue with no timer. */ | 1044 | * In case of failure continue without timer. */ |
1043 | if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) { | 1045 | if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) { |
1044 | pr_warning("stmmaceth: cannot attach the HW timer\n"); | 1046 | pr_warning("stmmaceth: cannot attach the external timer.\n"); |
1045 | tmrate = 0; | 1047 | tmrate = 0; |
1046 | priv->tm->freq = 0; | 1048 | priv->tm->freq = 0; |
1047 | priv->tm->timer_start = stmmac_no_timer_started; | 1049 | priv->tm->timer_start = stmmac_no_timer_started; |
1048 | priv->tm->timer_stop = stmmac_no_timer_stopped; | 1050 | priv->tm->timer_stop = stmmac_no_timer_stopped; |
1049 | } | 1051 | } else |
1052 | priv->tm->enable = 1; | ||
1050 | #endif | 1053 | #endif |
1051 | 1054 | ||
1052 | /* Create and initialize the TX/RX descriptors chains. */ | 1055 | /* Create and initialize the TX/RX descriptors chains. */ |
@@ -1322,9 +1325,11 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1322 | 1325 | ||
1323 | /* Interrupt on completition only for the latest segment */ | 1326 | /* Interrupt on completition only for the latest segment */ |
1324 | priv->mac_type->ops->close_tx_desc(desc); | 1327 | priv->mac_type->ops->close_tx_desc(desc); |
1328 | |||
1325 | #ifdef CONFIG_STMMAC_TIMER | 1329 | #ifdef CONFIG_STMMAC_TIMER |
1326 | /* Clean IC while using timers */ | 1330 | /* Clean IC while using timer */ |
1327 | priv->mac_type->ops->clear_tx_ic(desc); | 1331 | if (likely(priv->tm->enable)) |
1332 | priv->mac_type->ops->clear_tx_ic(desc); | ||
1328 | #endif | 1333 | #endif |
1329 | /* To avoid raise condition */ | 1334 | /* To avoid raise condition */ |
1330 | priv->mac_type->ops->set_tx_owner(first); | 1335 | priv->mac_type->ops->set_tx_owner(first); |
@@ -2028,7 +2033,8 @@ static int stmmac_suspend(struct platform_device *pdev, pm_message_t state) | |||
2028 | 2033 | ||
2029 | #ifdef CONFIG_STMMAC_TIMER | 2034 | #ifdef CONFIG_STMMAC_TIMER |
2030 | priv->tm->timer_stop(); | 2035 | priv->tm->timer_stop(); |
2031 | dis_ic = 1; | 2036 | if (likely(priv->tm->enable)) |
2037 | dis_ic = 1; | ||
2032 | #endif | 2038 | #endif |
2033 | napi_disable(&priv->napi); | 2039 | napi_disable(&priv->napi); |
2034 | 2040 | ||
diff --git a/drivers/net/stmmac/stmmac_timer.c b/drivers/net/stmmac/stmmac_timer.c index b838c6582077..679f61ffb1f8 100644 --- a/drivers/net/stmmac/stmmac_timer.c +++ b/drivers/net/stmmac/stmmac_timer.c | |||
@@ -63,7 +63,7 @@ int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm) | |||
63 | 63 | ||
64 | stmmac_rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); | 64 | stmmac_rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE); |
65 | if (stmmac_rtc == NULL) { | 65 | if (stmmac_rtc == NULL) { |
66 | pr_error("open rtc device failed\n"); | 66 | pr_err("open rtc device failed\n"); |
67 | return -ENODEV; | 67 | return -ENODEV; |
68 | } | 68 | } |
69 | 69 | ||
@@ -71,7 +71,7 @@ int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm) | |||
71 | 71 | ||
72 | /* Periodic mode is not supported */ | 72 | /* Periodic mode is not supported */ |
73 | if ((rtc_irq_set_freq(stmmac_rtc, &stmmac_task, tm->freq) < 0)) { | 73 | if ((rtc_irq_set_freq(stmmac_rtc, &stmmac_task, tm->freq) < 0)) { |
74 | pr_error("set periodic failed\n"); | 74 | pr_err("set periodic failed\n"); |
75 | rtc_irq_unregister(stmmac_rtc, &stmmac_task); | 75 | rtc_irq_unregister(stmmac_rtc, &stmmac_task); |
76 | rtc_class_close(stmmac_rtc); | 76 | rtc_class_close(stmmac_rtc); |
77 | return -1; | 77 | return -1; |
diff --git a/drivers/net/stmmac/stmmac_timer.h b/drivers/net/stmmac/stmmac_timer.h index f795cae33725..6863590d184b 100644 --- a/drivers/net/stmmac/stmmac_timer.h +++ b/drivers/net/stmmac/stmmac_timer.h | |||
@@ -26,6 +26,7 @@ struct stmmac_timer { | |||
26 | void (*timer_start) (unsigned int new_freq); | 26 | void (*timer_start) (unsigned int new_freq); |
27 | void (*timer_stop) (void); | 27 | void (*timer_stop) (void); |
28 | unsigned int freq; | 28 | unsigned int freq; |
29 | unsigned int enable; | ||
29 | }; | 30 | }; |
30 | 31 | ||
31 | /* Open the HW timer device and return 0 in case of success */ | 32 | /* Open the HW timer device and return 0 in case of success */ |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index fa4e58196c21..43bc3fcc0d85 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -378,7 +378,7 @@ static void dbg_dump(int line_count, const char *func_name, unsigned char *buf, | |||
378 | } | 378 | } |
379 | 379 | ||
380 | #define DUMP(buf_, len_) \ | 380 | #define DUMP(buf_, len_) \ |
381 | dbg_dump(__LINE__, __func__, buf_, len_) | 381 | dbg_dump(__LINE__, __func__, (unsigned char *)buf_, len_) |
382 | 382 | ||
383 | #define DUMP1(buf_, len_) \ | 383 | #define DUMP1(buf_, len_) \ |
384 | do { \ | 384 | do { \ |
@@ -1363,7 +1363,7 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp) | |||
1363 | /* reset the rts and dtr */ | 1363 | /* reset the rts and dtr */ |
1364 | /* do the actual close */ | 1364 | /* do the actual close */ |
1365 | serial->open_count--; | 1365 | serial->open_count--; |
1366 | kref_put(&serial->parent->ref, hso_serial_ref_free); | 1366 | |
1367 | if (serial->open_count <= 0) { | 1367 | if (serial->open_count <= 0) { |
1368 | serial->open_count = 0; | 1368 | serial->open_count = 0; |
1369 | spin_lock_irq(&serial->serial_lock); | 1369 | spin_lock_irq(&serial->serial_lock); |
@@ -1383,6 +1383,8 @@ static void hso_serial_close(struct tty_struct *tty, struct file *filp) | |||
1383 | usb_autopm_put_interface(serial->parent->interface); | 1383 | usb_autopm_put_interface(serial->parent->interface); |
1384 | 1384 | ||
1385 | mutex_unlock(&serial->parent->mutex); | 1385 | mutex_unlock(&serial->parent->mutex); |
1386 | |||
1387 | kref_put(&serial->parent->ref, hso_serial_ref_free); | ||
1386 | } | 1388 | } |
1387 | 1389 | ||
1388 | /* close the requested serial port */ | 1390 | /* close the requested serial port */ |
@@ -1527,7 +1529,7 @@ static void tiocmget_intr_callback(struct urb *urb) | |||
1527 | dev_warn(&usb->dev, | 1529 | dev_warn(&usb->dev, |
1528 | "hso received invalid serial state notification\n"); | 1530 | "hso received invalid serial state notification\n"); |
1529 | DUMP(serial_state_notification, | 1531 | DUMP(serial_state_notification, |
1530 | sizeof(hso_serial_state_notifation)) | 1532 | sizeof(struct hso_serial_state_notification)); |
1531 | } else { | 1533 | } else { |
1532 | 1534 | ||
1533 | UART_state_bitmap = le16_to_cpu(serial_state_notification-> | 1535 | UART_state_bitmap = le16_to_cpu(serial_state_notification-> |
diff --git a/drivers/net/veth.c b/drivers/net/veth.c index ade5b344f75d..52af5017c46b 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c | |||
@@ -210,32 +210,29 @@ rx_drop: | |||
210 | static struct net_device_stats *veth_get_stats(struct net_device *dev) | 210 | static struct net_device_stats *veth_get_stats(struct net_device *dev) |
211 | { | 211 | { |
212 | struct veth_priv *priv; | 212 | struct veth_priv *priv; |
213 | struct net_device_stats *dev_stats; | ||
214 | int cpu; | 213 | int cpu; |
215 | struct veth_net_stats *stats; | 214 | struct veth_net_stats *stats, total = {0}; |
216 | 215 | ||
217 | priv = netdev_priv(dev); | 216 | priv = netdev_priv(dev); |
218 | dev_stats = &dev->stats; | ||
219 | |||
220 | dev_stats->rx_packets = 0; | ||
221 | dev_stats->tx_packets = 0; | ||
222 | dev_stats->rx_bytes = 0; | ||
223 | dev_stats->tx_bytes = 0; | ||
224 | dev_stats->tx_dropped = 0; | ||
225 | dev_stats->rx_dropped = 0; | ||
226 | 217 | ||
227 | for_each_online_cpu(cpu) { | 218 | for_each_possible_cpu(cpu) { |
228 | stats = per_cpu_ptr(priv->stats, cpu); | 219 | stats = per_cpu_ptr(priv->stats, cpu); |
229 | 220 | ||
230 | dev_stats->rx_packets += stats->rx_packets; | 221 | total.rx_packets += stats->rx_packets; |
231 | dev_stats->tx_packets += stats->tx_packets; | 222 | total.tx_packets += stats->tx_packets; |
232 | dev_stats->rx_bytes += stats->rx_bytes; | 223 | total.rx_bytes += stats->rx_bytes; |
233 | dev_stats->tx_bytes += stats->tx_bytes; | 224 | total.tx_bytes += stats->tx_bytes; |
234 | dev_stats->tx_dropped += stats->tx_dropped; | 225 | total.tx_dropped += stats->tx_dropped; |
235 | dev_stats->rx_dropped += stats->rx_dropped; | 226 | total.rx_dropped += stats->rx_dropped; |
236 | } | 227 | } |
237 | 228 | dev->stats.rx_packets = total.rx_packets; | |
238 | return dev_stats; | 229 | dev->stats.tx_packets = total.tx_packets; |
230 | dev->stats.rx_bytes = total.rx_bytes; | ||
231 | dev->stats.tx_bytes = total.tx_bytes; | ||
232 | dev->stats.tx_dropped = total.tx_dropped; | ||
233 | dev->stats.rx_dropped = total.rx_dropped; | ||
234 | |||
235 | return &dev->stats; | ||
239 | } | 236 | } |
240 | 237 | ||
241 | static int veth_open(struct net_device *dev) | 238 | static int veth_open(struct net_device *dev) |
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c index e2c33c06190b..8e25ca7080c7 100644 --- a/drivers/net/wan/cosa.c +++ b/drivers/net/wan/cosa.c | |||
@@ -907,6 +907,7 @@ static ssize_t cosa_write(struct file *file, | |||
907 | current->state = TASK_RUNNING; | 907 | current->state = TASK_RUNNING; |
908 | chan->tx_status = 1; | 908 | chan->tx_status = 1; |
909 | spin_unlock_irqrestore(&cosa->lock, flags); | 909 | spin_unlock_irqrestore(&cosa->lock, flags); |
910 | up(&chan->wsem); | ||
910 | return -ERESTARTSYS; | 911 | return -ERESTARTSYS; |
911 | } | 912 | } |
912 | } | 913 | } |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 52bed89063d4..43d2be9867fc 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -1555,6 +1555,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
1555 | BIT(NL80211_IFTYPE_ADHOC) | | 1555 | BIT(NL80211_IFTYPE_ADHOC) | |
1556 | BIT(NL80211_IFTYPE_MESH_POINT); | 1556 | BIT(NL80211_IFTYPE_MESH_POINT); |
1557 | 1557 | ||
1558 | hw->wiphy->ps_default = false; | ||
1559 | |||
1558 | hw->queues = 4; | 1560 | hw->queues = 4; |
1559 | hw->max_rates = 4; | 1561 | hw->max_rates = 4; |
1560 | hw->channel_change_time = 5000; | 1562 | hw->channel_change_time = 5000; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index fb9bcfa6d947..b7e196e3c8d3 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -1277,8 +1277,16 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid) | |||
1277 | return -ENXIO; | 1277 | return -ENXIO; |
1278 | } | 1278 | } |
1279 | 1279 | ||
1280 | if (priv->stations[sta_id].tid[tid].agg.state == | ||
1281 | IWL_EMPTYING_HW_QUEUE_ADDBA) { | ||
1282 | IWL_DEBUG_HT(priv, "AGG stop before setup done\n"); | ||
1283 | ieee80211_stop_tx_ba_cb_irqsafe(priv->hw, ra, tid); | ||
1284 | priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; | ||
1285 | return 0; | ||
1286 | } | ||
1287 | |||
1280 | if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON) | 1288 | if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON) |
1281 | IWL_WARN(priv, "Stopping AGG while state not IWL_AGG_ON\n"); | 1289 | IWL_WARN(priv, "Stopping AGG while state not ON or starting\n"); |
1282 | 1290 | ||
1283 | tid_data = &priv->stations[sta_id].tid[tid]; | 1291 | tid_data = &priv->stations[sta_id].tid[tid]; |
1284 | ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4; | 1292 | ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4; |
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c index 0a8f735f6c4a..ab64522aaa64 100644 --- a/drivers/platform/x86/acerhdf.c +++ b/drivers/platform/x86/acerhdf.c | |||
@@ -52,7 +52,7 @@ | |||
52 | */ | 52 | */ |
53 | #undef START_IN_KERNEL_MODE | 53 | #undef START_IN_KERNEL_MODE |
54 | 54 | ||
55 | #define DRV_VER "0.5.17" | 55 | #define DRV_VER "0.5.18" |
56 | 56 | ||
57 | /* | 57 | /* |
58 | * According to the Atom N270 datasheet, | 58 | * According to the Atom N270 datasheet, |
@@ -61,7 +61,7 @@ | |||
61 | * measured by the on-die thermal monitor are within 0 <= Tj <= 90. So, | 61 | * measured by the on-die thermal monitor are within 0 <= Tj <= 90. So, |
62 | * assume 89°C is critical temperature. | 62 | * assume 89°C is critical temperature. |
63 | */ | 63 | */ |
64 | #define ACERHDF_TEMP_CRIT 89 | 64 | #define ACERHDF_TEMP_CRIT 89000 |
65 | #define ACERHDF_FAN_OFF 0 | 65 | #define ACERHDF_FAN_OFF 0 |
66 | #define ACERHDF_FAN_AUTO 1 | 66 | #define ACERHDF_FAN_AUTO 1 |
67 | 67 | ||
@@ -69,7 +69,7 @@ | |||
69 | * No matter what value the user puts into the fanon variable, turn on the fan | 69 | * No matter what value the user puts into the fanon variable, turn on the fan |
70 | * at 80 degree Celsius to prevent hardware damage | 70 | * at 80 degree Celsius to prevent hardware damage |
71 | */ | 71 | */ |
72 | #define ACERHDF_MAX_FANON 80 | 72 | #define ACERHDF_MAX_FANON 80000 |
73 | 73 | ||
74 | /* | 74 | /* |
75 | * Maximum interval between two temperature checks is 15 seconds, as the die | 75 | * Maximum interval between two temperature checks is 15 seconds, as the die |
@@ -85,8 +85,8 @@ static int kernelmode; | |||
85 | #endif | 85 | #endif |
86 | 86 | ||
87 | static unsigned int interval = 10; | 87 | static unsigned int interval = 10; |
88 | static unsigned int fanon = 63; | 88 | static unsigned int fanon = 63000; |
89 | static unsigned int fanoff = 58; | 89 | static unsigned int fanoff = 58000; |
90 | static unsigned int verbose; | 90 | static unsigned int verbose; |
91 | static unsigned int fanstate = ACERHDF_FAN_AUTO; | 91 | static unsigned int fanstate = ACERHDF_FAN_AUTO; |
92 | static char force_bios[16]; | 92 | static char force_bios[16]; |
@@ -171,7 +171,7 @@ static int acerhdf_get_temp(int *temp) | |||
171 | if (ec_read(bios_cfg->tempreg, &read_temp)) | 171 | if (ec_read(bios_cfg->tempreg, &read_temp)) |
172 | return -EINVAL; | 172 | return -EINVAL; |
173 | 173 | ||
174 | *temp = read_temp; | 174 | *temp = read_temp * 1000; |
175 | 175 | ||
176 | return 0; | 176 | return 0; |
177 | } | 177 | } |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index d93108d148fc..a848c7e20aeb 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -1680,36 +1680,48 @@ static void tpacpi_remove_driver_attributes(struct device_driver *drv) | |||
1680 | | (__bv1) << 8 | (__bv2) } | 1680 | | (__bv1) << 8 | (__bv2) } |
1681 | 1681 | ||
1682 | #define TPV_Q_X(__v, __bid1, __bid2, __bv1, __bv2, \ | 1682 | #define TPV_Q_X(__v, __bid1, __bid2, __bv1, __bv2, \ |
1683 | __eid1, __eid2, __ev1, __ev2) \ | 1683 | __eid, __ev1, __ev2) \ |
1684 | { .vendor = (__v), \ | 1684 | { .vendor = (__v), \ |
1685 | .bios = TPID(__bid1, __bid2), \ | 1685 | .bios = TPID(__bid1, __bid2), \ |
1686 | .ec = TPID(__eid1, __eid2), \ | 1686 | .ec = __eid, \ |
1687 | .quirks = (__ev1) << 24 | (__ev2) << 16 \ | 1687 | .quirks = (__ev1) << 24 | (__ev2) << 16 \ |
1688 | | (__bv1) << 8 | (__bv2) } | 1688 | | (__bv1) << 8 | (__bv2) } |
1689 | 1689 | ||
1690 | #define TPV_QI0(__id1, __id2, __bv1, __bv2) \ | 1690 | #define TPV_QI0(__id1, __id2, __bv1, __bv2) \ |
1691 | TPV_Q(PCI_VENDOR_ID_IBM, __id1, __id2, __bv1, __bv2) | 1691 | TPV_Q(PCI_VENDOR_ID_IBM, __id1, __id2, __bv1, __bv2) |
1692 | 1692 | ||
1693 | /* Outdated IBM BIOSes often lack the EC id string */ | ||
1693 | #define TPV_QI1(__id1, __id2, __bv1, __bv2, __ev1, __ev2) \ | 1694 | #define TPV_QI1(__id1, __id2, __bv1, __bv2, __ev1, __ev2) \ |
1694 | TPV_Q_X(PCI_VENDOR_ID_IBM, __id1, __id2, \ | 1695 | TPV_Q_X(PCI_VENDOR_ID_IBM, __id1, __id2, \ |
1695 | __bv1, __bv2, __id1, __id2, __ev1, __ev2) | 1696 | __bv1, __bv2, TPID(__id1, __id2), \ |
1697 | __ev1, __ev2), \ | ||
1698 | TPV_Q_X(PCI_VENDOR_ID_IBM, __id1, __id2, \ | ||
1699 | __bv1, __bv2, TPACPI_MATCH_UNKNOWN, \ | ||
1700 | __ev1, __ev2) | ||
1696 | 1701 | ||
1702 | /* Outdated IBM BIOSes often lack the EC id string */ | ||
1697 | #define TPV_QI2(__bid1, __bid2, __bv1, __bv2, \ | 1703 | #define TPV_QI2(__bid1, __bid2, __bv1, __bv2, \ |
1698 | __eid1, __eid2, __ev1, __ev2) \ | 1704 | __eid1, __eid2, __ev1, __ev2) \ |
1699 | TPV_Q_X(PCI_VENDOR_ID_IBM, __bid1, __bid2, \ | 1705 | TPV_Q_X(PCI_VENDOR_ID_IBM, __bid1, __bid2, \ |
1700 | __bv1, __bv2, __eid1, __eid2, __ev1, __ev2) | 1706 | __bv1, __bv2, TPID(__eid1, __eid2), \ |
1707 | __ev1, __ev2), \ | ||
1708 | TPV_Q_X(PCI_VENDOR_ID_IBM, __bid1, __bid2, \ | ||
1709 | __bv1, __bv2, TPACPI_MATCH_UNKNOWN, \ | ||
1710 | __ev1, __ev2) | ||
1701 | 1711 | ||
1702 | #define TPV_QL0(__id1, __id2, __bv1, __bv2) \ | 1712 | #define TPV_QL0(__id1, __id2, __bv1, __bv2) \ |
1703 | TPV_Q(PCI_VENDOR_ID_LENOVO, __id1, __id2, __bv1, __bv2) | 1713 | TPV_Q(PCI_VENDOR_ID_LENOVO, __id1, __id2, __bv1, __bv2) |
1704 | 1714 | ||
1705 | #define TPV_QL1(__id1, __id2, __bv1, __bv2, __ev1, __ev2) \ | 1715 | #define TPV_QL1(__id1, __id2, __bv1, __bv2, __ev1, __ev2) \ |
1706 | TPV_Q_X(PCI_VENDOR_ID_LENOVO, __id1, __id2, \ | 1716 | TPV_Q_X(PCI_VENDOR_ID_LENOVO, __id1, __id2, \ |
1707 | __bv1, __bv2, __id1, __id2, __ev1, __ev2) | 1717 | __bv1, __bv2, TPID(__id1, __id2), \ |
1718 | __ev1, __ev2) | ||
1708 | 1719 | ||
1709 | #define TPV_QL2(__bid1, __bid2, __bv1, __bv2, \ | 1720 | #define TPV_QL2(__bid1, __bid2, __bv1, __bv2, \ |
1710 | __eid1, __eid2, __ev1, __ev2) \ | 1721 | __eid1, __eid2, __ev1, __ev2) \ |
1711 | TPV_Q_X(PCI_VENDOR_ID_LENOVO, __bid1, __bid2, \ | 1722 | TPV_Q_X(PCI_VENDOR_ID_LENOVO, __bid1, __bid2, \ |
1712 | __bv1, __bv2, __eid1, __eid2, __ev1, __ev2) | 1723 | __bv1, __bv2, TPID(__eid1, __eid2), \ |
1724 | __ev1, __ev2) | ||
1713 | 1725 | ||
1714 | static const struct tpacpi_quirk tpacpi_bios_version_qtable[] __initconst = { | 1726 | static const struct tpacpi_quirk tpacpi_bios_version_qtable[] __initconst = { |
1715 | /* Numeric models ------------------ */ | 1727 | /* Numeric models ------------------ */ |
@@ -6313,7 +6325,7 @@ static int brightness_write(char *buf) | |||
6313 | * Doing it this way makes the syscall restartable in case of EINTR | 6325 | * Doing it this way makes the syscall restartable in case of EINTR |
6314 | */ | 6326 | */ |
6315 | rc = brightness_set(level); | 6327 | rc = brightness_set(level); |
6316 | return (rc == -EINTR)? ERESTARTSYS : rc; | 6328 | return (rc == -EINTR)? -ERESTARTSYS : rc; |
6317 | } | 6329 | } |
6318 | 6330 | ||
6319 | static struct ibm_struct brightness_driver_data = { | 6331 | static struct ibm_struct brightness_driver_data = { |
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 5fd2da494d08..c968cc31cd86 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c | |||
@@ -164,8 +164,8 @@ void scsi_remove_host(struct Scsi_Host *shost) | |||
164 | return; | 164 | return; |
165 | } | 165 | } |
166 | spin_unlock_irqrestore(shost->host_lock, flags); | 166 | spin_unlock_irqrestore(shost->host_lock, flags); |
167 | mutex_unlock(&shost->scan_mutex); | ||
168 | scsi_forget_host(shost); | 167 | scsi_forget_host(shost); |
168 | mutex_unlock(&shost->scan_mutex); | ||
169 | scsi_proc_host_rm(shost); | 169 | scsi_proc_host_rm(shost); |
170 | 170 | ||
171 | spin_lock_irqsave(shost->host_lock, flags); | 171 | spin_lock_irqsave(shost->host_lock, flags); |
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 0547a7f44d42..47291bcff0d5 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -952,16 +952,6 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, | |||
952 | return SCSI_SCAN_LUN_PRESENT; | 952 | return SCSI_SCAN_LUN_PRESENT; |
953 | } | 953 | } |
954 | 954 | ||
955 | static inline void scsi_destroy_sdev(struct scsi_device *sdev) | ||
956 | { | ||
957 | scsi_device_set_state(sdev, SDEV_DEL); | ||
958 | if (sdev->host->hostt->slave_destroy) | ||
959 | sdev->host->hostt->slave_destroy(sdev); | ||
960 | transport_destroy_device(&sdev->sdev_gendev); | ||
961 | put_device(&sdev->sdev_dev); | ||
962 | put_device(&sdev->sdev_gendev); | ||
963 | } | ||
964 | |||
965 | #ifdef CONFIG_SCSI_LOGGING | 955 | #ifdef CONFIG_SCSI_LOGGING |
966 | /** | 956 | /** |
967 | * scsi_inq_str - print INQUIRY data from min to max index, strip trailing whitespace | 957 | * scsi_inq_str - print INQUIRY data from min to max index, strip trailing whitespace |
@@ -1139,7 +1129,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget, | |||
1139 | } | 1129 | } |
1140 | } | 1130 | } |
1141 | } else | 1131 | } else |
1142 | scsi_destroy_sdev(sdev); | 1132 | __scsi_remove_device(sdev); |
1143 | out: | 1133 | out: |
1144 | return res; | 1134 | return res; |
1145 | } | 1135 | } |
@@ -1500,7 +1490,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, | |||
1500 | /* | 1490 | /* |
1501 | * the sdev we used didn't appear in the report luns scan | 1491 | * the sdev we used didn't appear in the report luns scan |
1502 | */ | 1492 | */ |
1503 | scsi_destroy_sdev(sdev); | 1493 | __scsi_remove_device(sdev); |
1504 | return ret; | 1494 | return ret; |
1505 | } | 1495 | } |
1506 | 1496 | ||
@@ -1710,7 +1700,7 @@ static void scsi_sysfs_add_devices(struct Scsi_Host *shost) | |||
1710 | shost_for_each_device(sdev, shost) { | 1700 | shost_for_each_device(sdev, shost) { |
1711 | if (!scsi_host_scan_allowed(shost) || | 1701 | if (!scsi_host_scan_allowed(shost) || |
1712 | scsi_sysfs_add_sdev(sdev) != 0) | 1702 | scsi_sysfs_add_sdev(sdev) != 0) |
1713 | scsi_destroy_sdev(sdev); | 1703 | __scsi_remove_device(sdev); |
1714 | } | 1704 | } |
1715 | } | 1705 | } |
1716 | 1706 | ||
@@ -1943,7 +1933,7 @@ void scsi_free_host_dev(struct scsi_device *sdev) | |||
1943 | { | 1933 | { |
1944 | BUG_ON(sdev->id != sdev->host->this_id); | 1934 | BUG_ON(sdev->id != sdev->host->this_id); |
1945 | 1935 | ||
1946 | scsi_destroy_sdev(sdev); | 1936 | __scsi_remove_device(sdev); |
1947 | } | 1937 | } |
1948 | EXPORT_SYMBOL(scsi_free_host_dev); | 1938 | EXPORT_SYMBOL(scsi_free_host_dev); |
1949 | 1939 | ||
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 5c7eb63a19d1..392d8db33905 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
@@ -854,82 +854,73 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) | |||
854 | transport_configure_device(&starget->dev); | 854 | transport_configure_device(&starget->dev); |
855 | error = device_add(&sdev->sdev_gendev); | 855 | error = device_add(&sdev->sdev_gendev); |
856 | if (error) { | 856 | if (error) { |
857 | put_device(sdev->sdev_gendev.parent); | ||
858 | printk(KERN_INFO "error 1\n"); | 857 | printk(KERN_INFO "error 1\n"); |
859 | return error; | 858 | goto out_remove; |
860 | } | 859 | } |
861 | error = device_add(&sdev->sdev_dev); | 860 | error = device_add(&sdev->sdev_dev); |
862 | if (error) { | 861 | if (error) { |
863 | printk(KERN_INFO "error 2\n"); | 862 | printk(KERN_INFO "error 2\n"); |
864 | goto clean_device; | 863 | device_del(&sdev->sdev_gendev); |
864 | goto out_remove; | ||
865 | } | 865 | } |
866 | transport_add_device(&sdev->sdev_gendev); | ||
867 | sdev->is_visible = 1; | ||
866 | 868 | ||
867 | /* create queue files, which may be writable, depending on the host */ | 869 | /* create queue files, which may be writable, depending on the host */ |
868 | if (sdev->host->hostt->change_queue_depth) | 870 | if (sdev->host->hostt->change_queue_depth) |
869 | error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_depth_rw); | 871 | error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_depth_rw); |
870 | else | 872 | else |
871 | error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_depth); | 873 | error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_depth); |
872 | if (error) { | 874 | if (error) |
873 | __scsi_remove_device(sdev); | 875 | goto out_remove; |
874 | goto out; | 876 | |
875 | } | ||
876 | if (sdev->host->hostt->change_queue_type) | 877 | if (sdev->host->hostt->change_queue_type) |
877 | error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_type_rw); | 878 | error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_type_rw); |
878 | else | 879 | else |
879 | error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_type); | 880 | error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_type); |
880 | if (error) { | 881 | if (error) |
881 | __scsi_remove_device(sdev); | 882 | goto out_remove; |
882 | goto out; | ||
883 | } | ||
884 | 883 | ||
885 | error = bsg_register_queue(rq, &sdev->sdev_gendev, NULL, NULL); | 884 | error = bsg_register_queue(rq, &sdev->sdev_gendev, NULL, NULL); |
886 | 885 | ||
887 | if (error) | 886 | if (error) |
887 | /* we're treating error on bsg register as non-fatal, | ||
888 | * so pretend nothing went wrong */ | ||
888 | sdev_printk(KERN_INFO, sdev, | 889 | sdev_printk(KERN_INFO, sdev, |
889 | "Failed to register bsg queue, errno=%d\n", error); | 890 | "Failed to register bsg queue, errno=%d\n", error); |
890 | 891 | ||
891 | /* we're treating error on bsg register as non-fatal, so pretend | ||
892 | * nothing went wrong */ | ||
893 | error = 0; | ||
894 | |||
895 | /* add additional host specific attributes */ | 892 | /* add additional host specific attributes */ |
896 | if (sdev->host->hostt->sdev_attrs) { | 893 | if (sdev->host->hostt->sdev_attrs) { |
897 | for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) { | 894 | for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) { |
898 | error = device_create_file(&sdev->sdev_gendev, | 895 | error = device_create_file(&sdev->sdev_gendev, |
899 | sdev->host->hostt->sdev_attrs[i]); | 896 | sdev->host->hostt->sdev_attrs[i]); |
900 | if (error) { | 897 | if (error) |
901 | __scsi_remove_device(sdev); | 898 | goto out_remove; |
902 | goto out; | ||
903 | } | ||
904 | } | 899 | } |
905 | } | 900 | } |
906 | 901 | ||
907 | transport_add_device(&sdev->sdev_gendev); | 902 | return 0; |
908 | out: | ||
909 | return error; | ||
910 | |||
911 | clean_device: | ||
912 | scsi_device_set_state(sdev, SDEV_CANCEL); | ||
913 | |||
914 | device_del(&sdev->sdev_gendev); | ||
915 | transport_destroy_device(&sdev->sdev_gendev); | ||
916 | put_device(&sdev->sdev_dev); | ||
917 | put_device(&sdev->sdev_gendev); | ||
918 | 903 | ||
904 | out_remove: | ||
905 | __scsi_remove_device(sdev); | ||
919 | return error; | 906 | return error; |
907 | |||
920 | } | 908 | } |
921 | 909 | ||
922 | void __scsi_remove_device(struct scsi_device *sdev) | 910 | void __scsi_remove_device(struct scsi_device *sdev) |
923 | { | 911 | { |
924 | struct device *dev = &sdev->sdev_gendev; | 912 | struct device *dev = &sdev->sdev_gendev; |
925 | 913 | ||
926 | if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0) | 914 | if (sdev->is_visible) { |
927 | return; | 915 | if (scsi_device_set_state(sdev, SDEV_CANCEL) != 0) |
916 | return; | ||
928 | 917 | ||
929 | bsg_unregister_queue(sdev->request_queue); | 918 | bsg_unregister_queue(sdev->request_queue); |
930 | device_unregister(&sdev->sdev_dev); | 919 | device_unregister(&sdev->sdev_dev); |
931 | transport_remove_device(dev); | 920 | transport_remove_device(dev); |
932 | device_del(dev); | 921 | device_del(dev); |
922 | } else | ||
923 | put_device(&sdev->sdev_dev); | ||
933 | scsi_device_set_state(sdev, SDEV_DEL); | 924 | scsi_device_set_state(sdev, SDEV_DEL); |
934 | if (sdev->host->hostt->slave_destroy) | 925 | if (sdev->host->hostt->slave_destroy) |
935 | sdev->host->hostt->slave_destroy(sdev); | 926 | sdev->host->hostt->slave_destroy(sdev); |
diff --git a/drivers/scsi/sd_dif.c b/drivers/scsi/sd_dif.c index 88da97745710..84be62149c6c 100644 --- a/drivers/scsi/sd_dif.c +++ b/drivers/scsi/sd_dif.c | |||
@@ -418,7 +418,7 @@ error: | |||
418 | __func__, virt, phys, be32_to_cpu(sdt->ref_tag), | 418 | __func__, virt, phys, be32_to_cpu(sdt->ref_tag), |
419 | be16_to_cpu(sdt->app_tag)); | 419 | be16_to_cpu(sdt->app_tag)); |
420 | 420 | ||
421 | return -EIO; | 421 | return -EILSEQ; |
422 | } | 422 | } |
423 | 423 | ||
424 | /* | 424 | /* |
diff --git a/drivers/serial/suncore.c b/drivers/serial/suncore.c index a2d4a19550ab..ed7d958b0a01 100644 --- a/drivers/serial/suncore.c +++ b/drivers/serial/suncore.c | |||
@@ -53,20 +53,21 @@ void sunserial_unregister_minors(struct uart_driver *drv, int count) | |||
53 | EXPORT_SYMBOL(sunserial_unregister_minors); | 53 | EXPORT_SYMBOL(sunserial_unregister_minors); |
54 | 54 | ||
55 | int sunserial_console_match(struct console *con, struct device_node *dp, | 55 | int sunserial_console_match(struct console *con, struct device_node *dp, |
56 | struct uart_driver *drv, int line) | 56 | struct uart_driver *drv, int line, bool ignore_line) |
57 | { | 57 | { |
58 | int off; | ||
59 | |||
60 | if (!con || of_console_device != dp) | 58 | if (!con || of_console_device != dp) |
61 | return 0; | 59 | return 0; |
62 | 60 | ||
63 | off = 0; | 61 | if (!ignore_line) { |
64 | if (of_console_options && | 62 | int off = 0; |
65 | *of_console_options == 'b') | ||
66 | off = 1; | ||
67 | 63 | ||
68 | if ((line & 1) != off) | 64 | if (of_console_options && |
69 | return 0; | 65 | *of_console_options == 'b') |
66 | off = 1; | ||
67 | |||
68 | if ((line & 1) != off) | ||
69 | return 0; | ||
70 | } | ||
70 | 71 | ||
71 | con->index = line; | 72 | con->index = line; |
72 | drv->cons = con; | 73 | drv->cons = con; |
@@ -76,23 +77,24 @@ int sunserial_console_match(struct console *con, struct device_node *dp, | |||
76 | } | 77 | } |
77 | EXPORT_SYMBOL(sunserial_console_match); | 78 | EXPORT_SYMBOL(sunserial_console_match); |
78 | 79 | ||
79 | void | 80 | void sunserial_console_termios(struct console *con, struct device_node *uart_dp) |
80 | sunserial_console_termios(struct console *con) | ||
81 | { | 81 | { |
82 | struct device_node *dp; | 82 | const char *mode, *s; |
83 | const char *od, *mode, *s; | ||
84 | char mode_prop[] = "ttyX-mode"; | 83 | char mode_prop[] = "ttyX-mode"; |
85 | int baud, bits, stop, cflag; | 84 | int baud, bits, stop, cflag; |
86 | char parity; | 85 | char parity; |
87 | 86 | ||
88 | dp = of_find_node_by_path("/options"); | 87 | if (!strcmp(uart_dp->name, "rsc") || |
89 | od = of_get_property(dp, "output-device", NULL); | 88 | !strcmp(uart_dp->name, "rsc-console") || |
90 | if (!strcmp(od, "rsc")) { | 89 | !strcmp(uart_dp->name, "rsc-control")) { |
91 | mode = of_get_property(of_console_device, | 90 | mode = of_get_property(uart_dp, |
92 | "ssp-console-modes", NULL); | 91 | "ssp-console-modes", NULL); |
93 | if (!mode) | 92 | if (!mode) |
94 | mode = "115200,8,n,1,-"; | 93 | mode = "115200,8,n,1,-"; |
94 | } else if (!strcmp(uart_dp->name, "lom-console")) { | ||
95 | mode = "9600,8,n,1,-"; | ||
95 | } else { | 96 | } else { |
97 | struct device_node *dp; | ||
96 | char c; | 98 | char c; |
97 | 99 | ||
98 | c = 'a'; | 100 | c = 'a'; |
@@ -101,6 +103,7 @@ sunserial_console_termios(struct console *con) | |||
101 | 103 | ||
102 | mode_prop[3] = c; | 104 | mode_prop[3] = c; |
103 | 105 | ||
106 | dp = of_find_node_by_path("/options"); | ||
104 | mode = of_get_property(dp, mode_prop, NULL); | 107 | mode = of_get_property(dp, mode_prop, NULL); |
105 | if (!mode) | 108 | if (!mode) |
106 | mode = "9600,8,n,1,-"; | 109 | mode = "9600,8,n,1,-"; |
diff --git a/drivers/serial/suncore.h b/drivers/serial/suncore.h index 042668aa602e..db2057936c31 100644 --- a/drivers/serial/suncore.h +++ b/drivers/serial/suncore.h | |||
@@ -26,7 +26,8 @@ extern int sunserial_register_minors(struct uart_driver *, int); | |||
26 | extern void sunserial_unregister_minors(struct uart_driver *, int); | 26 | extern void sunserial_unregister_minors(struct uart_driver *, int); |
27 | 27 | ||
28 | extern int sunserial_console_match(struct console *, struct device_node *, | 28 | extern int sunserial_console_match(struct console *, struct device_node *, |
29 | struct uart_driver *, int); | 29 | struct uart_driver *, int, bool); |
30 | extern void sunserial_console_termios(struct console *); | 30 | extern void sunserial_console_termios(struct console *, |
31 | struct device_node *); | ||
31 | 32 | ||
32 | #endif /* !(_SERIAL_SUN_H) */ | 33 | #endif /* !(_SERIAL_SUN_H) */ |
diff --git a/drivers/serial/sunhv.c b/drivers/serial/sunhv.c index d548652dee50..d14cca7fb88d 100644 --- a/drivers/serial/sunhv.c +++ b/drivers/serial/sunhv.c | |||
@@ -566,7 +566,7 @@ static int __devinit hv_probe(struct of_device *op, const struct of_device_id *m | |||
566 | goto out_free_con_read_page; | 566 | goto out_free_con_read_page; |
567 | 567 | ||
568 | sunserial_console_match(&sunhv_console, op->node, | 568 | sunserial_console_match(&sunhv_console, op->node, |
569 | &sunhv_reg, port->line); | 569 | &sunhv_reg, port->line, false); |
570 | 570 | ||
571 | err = uart_add_one_port(&sunhv_reg, port); | 571 | err = uart_add_one_port(&sunhv_reg, port); |
572 | if (err) | 572 | if (err) |
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index d1ad34128635..d514e28d0755 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c | |||
@@ -883,7 +883,7 @@ static int sunsab_console_setup(struct console *con, char *options) | |||
883 | printk("Console: ttyS%d (SAB82532)\n", | 883 | printk("Console: ttyS%d (SAB82532)\n", |
884 | (sunsab_reg.minor - 64) + con->index); | 884 | (sunsab_reg.minor - 64) + con->index); |
885 | 885 | ||
886 | sunserial_console_termios(con); | 886 | sunserial_console_termios(con, to_of_device(up->port.dev)->node); |
887 | 887 | ||
888 | switch (con->cflag & CBAUD) { | 888 | switch (con->cflag & CBAUD) { |
889 | case B150: baud = 150; break; | 889 | case B150: baud = 150; break; |
@@ -1027,10 +1027,12 @@ static int __devinit sab_probe(struct of_device *op, const struct of_device_id * | |||
1027 | goto out1; | 1027 | goto out1; |
1028 | 1028 | ||
1029 | sunserial_console_match(SUNSAB_CONSOLE(), op->node, | 1029 | sunserial_console_match(SUNSAB_CONSOLE(), op->node, |
1030 | &sunsab_reg, up[0].port.line); | 1030 | &sunsab_reg, up[0].port.line, |
1031 | false); | ||
1031 | 1032 | ||
1032 | sunserial_console_match(SUNSAB_CONSOLE(), op->node, | 1033 | sunserial_console_match(SUNSAB_CONSOLE(), op->node, |
1033 | &sunsab_reg, up[1].port.line); | 1034 | &sunsab_reg, up[1].port.line, |
1035 | false); | ||
1034 | 1036 | ||
1035 | err = uart_add_one_port(&sunsab_reg, &up[0].port); | 1037 | err = uart_add_one_port(&sunsab_reg, &up[0].port); |
1036 | if (err) | 1038 | if (err) |
@@ -1116,7 +1118,6 @@ static int __init sunsab_init(void) | |||
1116 | if (!sunsab_ports) | 1118 | if (!sunsab_ports) |
1117 | return -ENOMEM; | 1119 | return -ENOMEM; |
1118 | 1120 | ||
1119 | sunsab_reg.cons = SUNSAB_CONSOLE(); | ||
1120 | err = sunserial_register_minors(&sunsab_reg, num_channels); | 1121 | err = sunserial_register_minors(&sunsab_reg, num_channels); |
1121 | if (err) { | 1122 | if (err) { |
1122 | kfree(sunsab_ports); | 1123 | kfree(sunsab_ports); |
diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 68d262b15749..170d3d68c8f0 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c | |||
@@ -1329,11 +1329,9 @@ static void sunsu_console_write(struct console *co, const char *s, | |||
1329 | */ | 1329 | */ |
1330 | static int __init sunsu_console_setup(struct console *co, char *options) | 1330 | static int __init sunsu_console_setup(struct console *co, char *options) |
1331 | { | 1331 | { |
1332 | static struct ktermios dummy; | ||
1333 | struct ktermios termios; | ||
1332 | struct uart_port *port; | 1334 | struct uart_port *port; |
1333 | int baud = 9600; | ||
1334 | int bits = 8; | ||
1335 | int parity = 'n'; | ||
1336 | int flow = 'n'; | ||
1337 | 1335 | ||
1338 | printk("Console: ttyS%d (SU)\n", | 1336 | printk("Console: ttyS%d (SU)\n", |
1339 | (sunsu_reg.minor - 64) + co->index); | 1337 | (sunsu_reg.minor - 64) + co->index); |
@@ -1352,10 +1350,15 @@ static int __init sunsu_console_setup(struct console *co, char *options) | |||
1352 | */ | 1350 | */ |
1353 | spin_lock_init(&port->lock); | 1351 | spin_lock_init(&port->lock); |
1354 | 1352 | ||
1355 | if (options) | 1353 | /* Get firmware console settings. */ |
1356 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 1354 | sunserial_console_termios(co, to_of_device(port->dev)->node); |
1357 | 1355 | ||
1358 | return uart_set_options(port, co, baud, parity, bits, flow); | 1356 | memset(&termios, 0, sizeof(struct ktermios)); |
1357 | termios.c_cflag = co->cflag; | ||
1358 | port->mctrl |= TIOCM_DTR; | ||
1359 | port->ops->set_termios(port, &termios, &dummy); | ||
1360 | |||
1361 | return 0; | ||
1359 | } | 1362 | } |
1360 | 1363 | ||
1361 | static struct console sunsu_console = { | 1364 | static struct console sunsu_console = { |
@@ -1409,6 +1412,7 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m | |||
1409 | struct uart_sunsu_port *up; | 1412 | struct uart_sunsu_port *up; |
1410 | struct resource *rp; | 1413 | struct resource *rp; |
1411 | enum su_type type; | 1414 | enum su_type type; |
1415 | bool ignore_line; | ||
1412 | int err; | 1416 | int err; |
1413 | 1417 | ||
1414 | type = su_get_type(dp); | 1418 | type = su_get_type(dp); |
@@ -1467,8 +1471,14 @@ static int __devinit su_probe(struct of_device *op, const struct of_device_id *m | |||
1467 | 1471 | ||
1468 | up->port.ops = &sunsu_pops; | 1472 | up->port.ops = &sunsu_pops; |
1469 | 1473 | ||
1474 | ignore_line = false; | ||
1475 | if (!strcmp(dp->name, "rsc-console") || | ||
1476 | !strcmp(dp->name, "lom-console")) | ||
1477 | ignore_line = true; | ||
1478 | |||
1470 | sunserial_console_match(SUNSU_CONSOLE(), dp, | 1479 | sunserial_console_match(SUNSU_CONSOLE(), dp, |
1471 | &sunsu_reg, up->port.line); | 1480 | &sunsu_reg, up->port.line, |
1481 | ignore_line); | ||
1472 | err = uart_add_one_port(&sunsu_reg, &up->port); | 1482 | err = uart_add_one_port(&sunsu_reg, &up->port); |
1473 | if (err) | 1483 | if (err) |
1474 | goto out_unmap; | 1484 | goto out_unmap; |
@@ -1517,6 +1527,10 @@ static const struct of_device_id su_match[] = { | |||
1517 | .name = "serial", | 1527 | .name = "serial", |
1518 | .compatible = "su", | 1528 | .compatible = "su", |
1519 | }, | 1529 | }, |
1530 | { | ||
1531 | .type = "serial", | ||
1532 | .compatible = "su", | ||
1533 | }, | ||
1520 | {}, | 1534 | {}, |
1521 | }; | 1535 | }; |
1522 | MODULE_DEVICE_TABLE(of, su_match); | 1536 | MODULE_DEVICE_TABLE(of, su_match); |
@@ -1548,6 +1562,12 @@ static int __init sunsu_init(void) | |||
1548 | num_uart++; | 1562 | num_uart++; |
1549 | } | 1563 | } |
1550 | } | 1564 | } |
1565 | for_each_node_by_type(dp, "serial") { | ||
1566 | if (of_device_is_compatible(dp, "su")) { | ||
1567 | if (su_get_type(dp) == SU_PORT_PORT) | ||
1568 | num_uart++; | ||
1569 | } | ||
1570 | } | ||
1551 | 1571 | ||
1552 | if (num_uart) { | 1572 | if (num_uart) { |
1553 | err = sunserial_register_minors(&sunsu_reg, num_uart); | 1573 | err = sunserial_register_minors(&sunsu_reg, num_uart); |
diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index ef693ae22e7f..2c7a66af4f52 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c | |||
@@ -1180,7 +1180,7 @@ static int __init sunzilog_console_setup(struct console *con, char *options) | |||
1180 | (sunzilog_reg.minor - 64) + con->index, con->index); | 1180 | (sunzilog_reg.minor - 64) + con->index, con->index); |
1181 | 1181 | ||
1182 | /* Get firmware console settings. */ | 1182 | /* Get firmware console settings. */ |
1183 | sunserial_console_termios(con); | 1183 | sunserial_console_termios(con, to_of_device(up->port.dev)->node); |
1184 | 1184 | ||
1185 | /* Firmware console speed is limited to 150-->38400 baud so | 1185 | /* Firmware console speed is limited to 150-->38400 baud so |
1186 | * this hackish cflag thing is OK. | 1186 | * this hackish cflag thing is OK. |
@@ -1416,7 +1416,8 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m | |||
1416 | 1416 | ||
1417 | if (!keyboard_mouse) { | 1417 | if (!keyboard_mouse) { |
1418 | if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, | 1418 | if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, |
1419 | &sunzilog_reg, up[0].port.line)) | 1419 | &sunzilog_reg, up[0].port.line, |
1420 | false)) | ||
1420 | up->flags |= SUNZILOG_FLAG_IS_CONS; | 1421 | up->flags |= SUNZILOG_FLAG_IS_CONS; |
1421 | err = uart_add_one_port(&sunzilog_reg, &up[0].port); | 1422 | err = uart_add_one_port(&sunzilog_reg, &up[0].port); |
1422 | if (err) { | 1423 | if (err) { |
@@ -1425,7 +1426,8 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m | |||
1425 | return err; | 1426 | return err; |
1426 | } | 1427 | } |
1427 | if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, | 1428 | if (sunserial_console_match(SUNZILOG_CONSOLE(), op->node, |
1428 | &sunzilog_reg, up[1].port.line)) | 1429 | &sunzilog_reg, up[1].port.line, |
1430 | false)) | ||
1429 | up->flags |= SUNZILOG_FLAG_IS_CONS; | 1431 | up->flags |= SUNZILOG_FLAG_IS_CONS; |
1430 | err = uart_add_one_port(&sunzilog_reg, &up[1].port); | 1432 | err = uart_add_one_port(&sunzilog_reg, &up[1].port); |
1431 | if (err) { | 1433 | if (err) { |
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c index 8c85a9c3665a..f4a6541c3e60 100644 --- a/drivers/staging/go7007/s2250-board.c +++ b/drivers/staging/go7007/s2250-board.c | |||
@@ -261,7 +261,7 @@ static int read_reg_fp(struct i2c_client *client, u16 addr, u16 *val) | |||
261 | 261 | ||
262 | memset(buf, 0xcd, 6); | 262 | memset(buf, 0xcd, 6); |
263 | usb = go->hpi_context; | 263 | usb = go->hpi_context; |
264 | if (down_interruptible(&usb->i2c_lock) != 0) { | 264 | if (mutex_lock_interruptible(&usb->i2c_lock) != 0) { |
265 | printk(KERN_INFO "i2c lock failed\n"); | 265 | printk(KERN_INFO "i2c lock failed\n"); |
266 | kfree(buf); | 266 | kfree(buf); |
267 | return -EINTR; | 267 | return -EINTR; |
@@ -270,7 +270,7 @@ static int read_reg_fp(struct i2c_client *client, u16 addr, u16 *val) | |||
270 | kfree(buf); | 270 | kfree(buf); |
271 | return -EFAULT; | 271 | return -EFAULT; |
272 | } | 272 | } |
273 | up(&usb->i2c_lock); | 273 | mutex_unlock(&usb->i2c_lock); |
274 | 274 | ||
275 | *val = (buf[0] << 8) | buf[1]; | 275 | *val = (buf[0] << 8) | buf[1]; |
276 | kfree(buf); | 276 | kfree(buf); |
diff --git a/drivers/staging/go7007/s2250-loader.h b/drivers/staging/go7007/s2250-loader.h new file mode 100644 index 000000000000..b7c301af16cc --- /dev/null +++ b/drivers/staging/go7007/s2250-loader.h | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005-2006 Micronas USA Inc. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License (Version 2) as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program; if not, write to the Free Software Foundation, | ||
15 | * Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
16 | */ | ||
17 | |||
18 | #ifndef _S2250_LOADER_H_ | ||
19 | #define _S2250_LOADER_H_ | ||
20 | |||
21 | extern int s2250loader_init(void); | ||
22 | extern void s2250loader_cleanup(void); | ||
23 | |||
24 | #endif | ||
diff --git a/drivers/staging/octeon/ethernet-mdio.c b/drivers/staging/octeon/ethernet-mdio.c index 42230e62a222..31a58e508924 100644 --- a/drivers/staging/octeon/ethernet-mdio.c +++ b/drivers/staging/octeon/ethernet-mdio.c | |||
@@ -170,7 +170,7 @@ static u32 cvm_oct_get_link(struct net_device *dev) | |||
170 | return ret; | 170 | return ret; |
171 | } | 171 | } |
172 | 172 | ||
173 | struct const ethtool_ops cvm_oct_ethtool_ops = { | 173 | const struct ethtool_ops cvm_oct_ethtool_ops = { |
174 | .get_drvinfo = cvm_oct_get_drvinfo, | 174 | .get_drvinfo = cvm_oct_get_drvinfo, |
175 | .get_settings = cvm_oct_get_settings, | 175 | .get_settings = cvm_oct_get_settings, |
176 | .set_settings = cvm_oct_set_settings, | 176 | .set_settings = cvm_oct_set_settings, |
diff --git a/drivers/staging/octeon/ethernet-spi.c b/drivers/staging/octeon/ethernet-spi.c index 66190b0cb68f..00dc0f4bad19 100644 --- a/drivers/staging/octeon/ethernet-spi.c +++ b/drivers/staging/octeon/ethernet-spi.c | |||
@@ -317,6 +317,6 @@ void cvm_oct_spi_uninit(struct net_device *dev) | |||
317 | cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), 0); | 317 | cvmx_write_csr(CVMX_SPXX_INT_MSK(interface), 0); |
318 | cvmx_write_csr(CVMX_STXX_INT_MSK(interface), 0); | 318 | cvmx_write_csr(CVMX_STXX_INT_MSK(interface), 0); |
319 | } | 319 | } |
320 | free_irq(8 + 46, &number_spi_ports); | 320 | free_irq(OCTEON_IRQ_RML, &number_spi_ports); |
321 | } | 321 | } |
322 | } | 322 | } |
diff --git a/drivers/staging/octeon/ethernet.c b/drivers/staging/octeon/ethernet.c index b8479517dce2..492c5029992d 100644 --- a/drivers/staging/octeon/ethernet.c +++ b/drivers/staging/octeon/ethernet.c | |||
@@ -111,6 +111,16 @@ MODULE_PARM_DESC(disable_core_queueing, "\n" | |||
111 | "\tallows packets to be sent without lock contention in the packet\n" | 111 | "\tallows packets to be sent without lock contention in the packet\n" |
112 | "\tscheduler resulting in some cases in improved throughput.\n"); | 112 | "\tscheduler resulting in some cases in improved throughput.\n"); |
113 | 113 | ||
114 | |||
115 | /* | ||
116 | * The offset from mac_addr_base that should be used for the next port | ||
117 | * that is configured. By convention, if any mgmt ports exist on the | ||
118 | * chip, they get the first mac addresses, The ports controlled by | ||
119 | * this driver are numbered sequencially following any mgmt addresses | ||
120 | * that may exist. | ||
121 | */ | ||
122 | static unsigned int cvm_oct_mac_addr_offset; | ||
123 | |||
114 | /** | 124 | /** |
115 | * Periodic timer to check auto negotiation | 125 | * Periodic timer to check auto negotiation |
116 | */ | 126 | */ |
@@ -474,16 +484,30 @@ static int cvm_oct_common_set_mac_address(struct net_device *dev, void *addr) | |||
474 | */ | 484 | */ |
475 | int cvm_oct_common_init(struct net_device *dev) | 485 | int cvm_oct_common_init(struct net_device *dev) |
476 | { | 486 | { |
477 | static int count; | ||
478 | char mac[8] = { 0x00, 0x00, | ||
479 | octeon_bootinfo->mac_addr_base[0], | ||
480 | octeon_bootinfo->mac_addr_base[1], | ||
481 | octeon_bootinfo->mac_addr_base[2], | ||
482 | octeon_bootinfo->mac_addr_base[3], | ||
483 | octeon_bootinfo->mac_addr_base[4], | ||
484 | octeon_bootinfo->mac_addr_base[5] + count | ||
485 | }; | ||
486 | struct octeon_ethernet *priv = netdev_priv(dev); | 487 | struct octeon_ethernet *priv = netdev_priv(dev); |
488 | struct sockaddr sa; | ||
489 | u64 mac = ((u64)(octeon_bootinfo->mac_addr_base[0] & 0xff) << 40) | | ||
490 | ((u64)(octeon_bootinfo->mac_addr_base[1] & 0xff) << 32) | | ||
491 | ((u64)(octeon_bootinfo->mac_addr_base[2] & 0xff) << 24) | | ||
492 | ((u64)(octeon_bootinfo->mac_addr_base[3] & 0xff) << 16) | | ||
493 | ((u64)(octeon_bootinfo->mac_addr_base[4] & 0xff) << 8) | | ||
494 | (u64)(octeon_bootinfo->mac_addr_base[5] & 0xff); | ||
495 | |||
496 | mac += cvm_oct_mac_addr_offset; | ||
497 | sa.sa_data[0] = (mac >> 40) & 0xff; | ||
498 | sa.sa_data[1] = (mac >> 32) & 0xff; | ||
499 | sa.sa_data[2] = (mac >> 24) & 0xff; | ||
500 | sa.sa_data[3] = (mac >> 16) & 0xff; | ||
501 | sa.sa_data[4] = (mac >> 8) & 0xff; | ||
502 | sa.sa_data[5] = mac & 0xff; | ||
503 | |||
504 | if (cvm_oct_mac_addr_offset >= octeon_bootinfo->mac_addr_count) | ||
505 | printk(KERN_DEBUG "%s: Using MAC outside of the assigned range:" | ||
506 | " %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, | ||
507 | sa.sa_data[0] & 0xff, sa.sa_data[1] & 0xff, | ||
508 | sa.sa_data[2] & 0xff, sa.sa_data[3] & 0xff, | ||
509 | sa.sa_data[4] & 0xff, sa.sa_data[5] & 0xff); | ||
510 | cvm_oct_mac_addr_offset++; | ||
487 | 511 | ||
488 | /* | 512 | /* |
489 | * Force the interface to use the POW send if always_use_pow | 513 | * Force the interface to use the POW send if always_use_pow |
@@ -496,14 +520,12 @@ int cvm_oct_common_init(struct net_device *dev) | |||
496 | if (priv->queue != -1 && USE_HW_TCPUDP_CHECKSUM) | 520 | if (priv->queue != -1 && USE_HW_TCPUDP_CHECKSUM) |
497 | dev->features |= NETIF_F_IP_CSUM; | 521 | dev->features |= NETIF_F_IP_CSUM; |
498 | 522 | ||
499 | count++; | ||
500 | |||
501 | /* We do our own locking, Linux doesn't need to */ | 523 | /* We do our own locking, Linux doesn't need to */ |
502 | dev->features |= NETIF_F_LLTX; | 524 | dev->features |= NETIF_F_LLTX; |
503 | SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops); | 525 | SET_ETHTOOL_OPS(dev, &cvm_oct_ethtool_ops); |
504 | 526 | ||
505 | cvm_oct_mdio_setup_device(dev); | 527 | cvm_oct_mdio_setup_device(dev); |
506 | dev->netdev_ops->ndo_set_mac_address(dev, mac); | 528 | dev->netdev_ops->ndo_set_mac_address(dev, &sa); |
507 | dev->netdev_ops->ndo_change_mtu(dev, dev->mtu); | 529 | dev->netdev_ops->ndo_change_mtu(dev, dev->mtu); |
508 | 530 | ||
509 | /* | 531 | /* |
@@ -620,6 +642,13 @@ static int __init cvm_oct_init_module(void) | |||
620 | 642 | ||
621 | pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION); | 643 | pr_notice("cavium-ethernet %s\n", OCTEON_ETHERNET_VERSION); |
622 | 644 | ||
645 | if (OCTEON_IS_MODEL(OCTEON_CN52XX)) | ||
646 | cvm_oct_mac_addr_offset = 2; /* First two are the mgmt ports. */ | ||
647 | else if (OCTEON_IS_MODEL(OCTEON_CN56XX)) | ||
648 | cvm_oct_mac_addr_offset = 1; /* First one is the mgmt port. */ | ||
649 | else | ||
650 | cvm_oct_mac_addr_offset = 0; | ||
651 | |||
623 | cvm_oct_proc_initialize(); | 652 | cvm_oct_proc_initialize(); |
624 | cvm_oct_rx_initialize(); | 653 | cvm_oct_rx_initialize(); |
625 | cvm_oct_configure_common_hw(); | 654 | cvm_oct_configure_common_hw(); |
diff --git a/fs/9p/cache.c b/fs/9p/cache.c index 51c94e26a346..bcc5357a9069 100644 --- a/fs/9p/cache.c +++ b/fs/9p/cache.c | |||
@@ -343,18 +343,7 @@ int __v9fs_fscache_release_page(struct page *page, gfp_t gfp) | |||
343 | 343 | ||
344 | BUG_ON(!vcookie->fscache); | 344 | BUG_ON(!vcookie->fscache); |
345 | 345 | ||
346 | if (PageFsCache(page)) { | 346 | return fscache_maybe_release_page(vnode->cache, page, gfp); |
347 | if (fscache_check_page_write(vcookie->fscache, page)) { | ||
348 | if (!(gfp & __GFP_WAIT)) | ||
349 | return 0; | ||
350 | fscache_wait_on_page_write(vcookie->fscache, page); | ||
351 | } | ||
352 | |||
353 | fscache_uncache_page(vcookie->fscache, page); | ||
354 | ClearPageFsCache(page); | ||
355 | } | ||
356 | |||
357 | return 1; | ||
358 | } | 347 | } |
359 | 348 | ||
360 | void __v9fs_fscache_invalidate_page(struct page *page) | 349 | void __v9fs_fscache_invalidate_page(struct page *page) |
@@ -368,7 +357,6 @@ void __v9fs_fscache_invalidate_page(struct page *page) | |||
368 | fscache_wait_on_page_write(vcookie->fscache, page); | 357 | fscache_wait_on_page_write(vcookie->fscache, page); |
369 | BUG_ON(!PageLocked(page)); | 358 | BUG_ON(!PageLocked(page)); |
370 | fscache_uncache_page(vcookie->fscache, page); | 359 | fscache_uncache_page(vcookie->fscache, page); |
371 | ClearPageFsCache(page); | ||
372 | } | 360 | } |
373 | } | 361 | } |
374 | 362 | ||
diff --git a/fs/afs/file.c b/fs/afs/file.c index 681c2a7b013f..39b301662f22 100644 --- a/fs/afs/file.c +++ b/fs/afs/file.c | |||
@@ -315,7 +315,6 @@ static void afs_invalidatepage(struct page *page, unsigned long offset) | |||
315 | struct afs_vnode *vnode = AFS_FS_I(page->mapping->host); | 315 | struct afs_vnode *vnode = AFS_FS_I(page->mapping->host); |
316 | fscache_wait_on_page_write(vnode->cache, page); | 316 | fscache_wait_on_page_write(vnode->cache, page); |
317 | fscache_uncache_page(vnode->cache, page); | 317 | fscache_uncache_page(vnode->cache, page); |
318 | ClearPageFsCache(page); | ||
319 | } | 318 | } |
320 | #endif | 319 | #endif |
321 | 320 | ||
@@ -349,17 +348,9 @@ static int afs_releasepage(struct page *page, gfp_t gfp_flags) | |||
349 | /* deny if page is being written to the cache and the caller hasn't | 348 | /* deny if page is being written to the cache and the caller hasn't |
350 | * elected to wait */ | 349 | * elected to wait */ |
351 | #ifdef CONFIG_AFS_FSCACHE | 350 | #ifdef CONFIG_AFS_FSCACHE |
352 | if (PageFsCache(page)) { | 351 | if (!fscache_maybe_release_page(vnode->cache, page, gfp_flags)) { |
353 | if (fscache_check_page_write(vnode->cache, page)) { | 352 | _leave(" = F [cache busy]"); |
354 | if (!(gfp_flags & __GFP_WAIT)) { | 353 | return 0; |
355 | _leave(" = F [cache busy]"); | ||
356 | return 0; | ||
357 | } | ||
358 | fscache_wait_on_page_write(vnode->cache, page); | ||
359 | } | ||
360 | |||
361 | fscache_uncache_page(vnode->cache, page); | ||
362 | ClearPageFsCache(page); | ||
363 | } | 354 | } |
364 | #endif | 355 | #endif |
365 | 356 | ||
diff --git a/fs/cachefiles/interface.c b/fs/cachefiles/interface.c index 431accd475a7..27089311fbea 100644 --- a/fs/cachefiles/interface.c +++ b/fs/cachefiles/interface.c | |||
@@ -114,8 +114,9 @@ nomem_lookup_data: | |||
114 | 114 | ||
115 | /* | 115 | /* |
116 | * attempt to look up the nominated node in this cache | 116 | * attempt to look up the nominated node in this cache |
117 | * - return -ETIMEDOUT to be scheduled again | ||
117 | */ | 118 | */ |
118 | static void cachefiles_lookup_object(struct fscache_object *_object) | 119 | static int cachefiles_lookup_object(struct fscache_object *_object) |
119 | { | 120 | { |
120 | struct cachefiles_lookup_data *lookup_data; | 121 | struct cachefiles_lookup_data *lookup_data; |
121 | struct cachefiles_object *parent, *object; | 122 | struct cachefiles_object *parent, *object; |
@@ -145,13 +146,15 @@ static void cachefiles_lookup_object(struct fscache_object *_object) | |||
145 | object->fscache.cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) | 146 | object->fscache.cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) |
146 | cachefiles_attr_changed(&object->fscache); | 147 | cachefiles_attr_changed(&object->fscache); |
147 | 148 | ||
148 | if (ret < 0) { | 149 | if (ret < 0 && ret != -ETIMEDOUT) { |
149 | printk(KERN_WARNING "CacheFiles: Lookup failed error %d\n", | 150 | if (ret != -ENOBUFS) |
150 | ret); | 151 | printk(KERN_WARNING |
152 | "CacheFiles: Lookup failed error %d\n", ret); | ||
151 | fscache_object_lookup_error(&object->fscache); | 153 | fscache_object_lookup_error(&object->fscache); |
152 | } | 154 | } |
153 | 155 | ||
154 | _leave(" [%d]", ret); | 156 | _leave(" [%d]", ret); |
157 | return ret; | ||
155 | } | 158 | } |
156 | 159 | ||
157 | /* | 160 | /* |
@@ -331,6 +334,7 @@ static void cachefiles_put_object(struct fscache_object *_object) | |||
331 | } | 334 | } |
332 | 335 | ||
333 | cache = object->fscache.cache; | 336 | cache = object->fscache.cache; |
337 | fscache_object_destroy(&object->fscache); | ||
334 | kmem_cache_free(cachefiles_object_jar, object); | 338 | kmem_cache_free(cachefiles_object_jar, object); |
335 | fscache_object_destroyed(cache); | 339 | fscache_object_destroyed(cache); |
336 | } | 340 | } |
@@ -403,12 +407,26 @@ static int cachefiles_attr_changed(struct fscache_object *_object) | |||
403 | if (oi_size == ni_size) | 407 | if (oi_size == ni_size) |
404 | return 0; | 408 | return 0; |
405 | 409 | ||
406 | newattrs.ia_size = ni_size; | ||
407 | newattrs.ia_valid = ATTR_SIZE; | ||
408 | |||
409 | cachefiles_begin_secure(cache, &saved_cred); | 410 | cachefiles_begin_secure(cache, &saved_cred); |
410 | mutex_lock(&object->backer->d_inode->i_mutex); | 411 | mutex_lock(&object->backer->d_inode->i_mutex); |
412 | |||
413 | /* if there's an extension to a partial page at the end of the backing | ||
414 | * file, we need to discard the partial page so that we pick up new | ||
415 | * data after it */ | ||
416 | if (oi_size & ~PAGE_MASK && ni_size > oi_size) { | ||
417 | _debug("discard tail %llx", oi_size); | ||
418 | newattrs.ia_valid = ATTR_SIZE; | ||
419 | newattrs.ia_size = oi_size & PAGE_MASK; | ||
420 | ret = notify_change(object->backer, &newattrs); | ||
421 | if (ret < 0) | ||
422 | goto truncate_failed; | ||
423 | } | ||
424 | |||
425 | newattrs.ia_valid = ATTR_SIZE; | ||
426 | newattrs.ia_size = ni_size; | ||
411 | ret = notify_change(object->backer, &newattrs); | 427 | ret = notify_change(object->backer, &newattrs); |
428 | |||
429 | truncate_failed: | ||
412 | mutex_unlock(&object->backer->d_inode->i_mutex); | 430 | mutex_unlock(&object->backer->d_inode->i_mutex); |
413 | cachefiles_end_secure(cache, saved_cred); | 431 | cachefiles_end_secure(cache, saved_cred); |
414 | 432 | ||
diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c index 4ce818ae39ea..14ac4806e291 100644 --- a/fs/cachefiles/namei.c +++ b/fs/cachefiles/namei.c | |||
@@ -21,17 +21,81 @@ | |||
21 | #include <linux/security.h> | 21 | #include <linux/security.h> |
22 | #include "internal.h" | 22 | #include "internal.h" |
23 | 23 | ||
24 | static int cachefiles_wait_bit(void *flags) | 24 | #define CACHEFILES_KEYBUF_SIZE 512 |
25 | |||
26 | /* | ||
27 | * dump debugging info about an object | ||
28 | */ | ||
29 | static noinline | ||
30 | void __cachefiles_printk_object(struct cachefiles_object *object, | ||
31 | const char *prefix, | ||
32 | u8 *keybuf) | ||
25 | { | 33 | { |
26 | schedule(); | 34 | struct fscache_cookie *cookie; |
27 | return 0; | 35 | unsigned keylen, loop; |
36 | |||
37 | printk(KERN_ERR "%sobject: OBJ%x\n", | ||
38 | prefix, object->fscache.debug_id); | ||
39 | printk(KERN_ERR "%sobjstate=%s fl=%lx swfl=%lx ev=%lx[%lx]\n", | ||
40 | prefix, fscache_object_states[object->fscache.state], | ||
41 | object->fscache.flags, object->fscache.work.flags, | ||
42 | object->fscache.events, | ||
43 | object->fscache.event_mask & FSCACHE_OBJECT_EVENTS_MASK); | ||
44 | printk(KERN_ERR "%sops=%u inp=%u exc=%u\n", | ||
45 | prefix, object->fscache.n_ops, object->fscache.n_in_progress, | ||
46 | object->fscache.n_exclusive); | ||
47 | printk(KERN_ERR "%sparent=%p\n", | ||
48 | prefix, object->fscache.parent); | ||
49 | |||
50 | spin_lock(&object->fscache.lock); | ||
51 | cookie = object->fscache.cookie; | ||
52 | if (cookie) { | ||
53 | printk(KERN_ERR "%scookie=%p [pr=%p nd=%p fl=%lx]\n", | ||
54 | prefix, | ||
55 | object->fscache.cookie, | ||
56 | object->fscache.cookie->parent, | ||
57 | object->fscache.cookie->netfs_data, | ||
58 | object->fscache.cookie->flags); | ||
59 | if (keybuf) | ||
60 | keylen = cookie->def->get_key(cookie->netfs_data, keybuf, | ||
61 | CACHEFILES_KEYBUF_SIZE); | ||
62 | else | ||
63 | keylen = 0; | ||
64 | } else { | ||
65 | printk(KERN_ERR "%scookie=NULL\n", prefix); | ||
66 | keylen = 0; | ||
67 | } | ||
68 | spin_unlock(&object->fscache.lock); | ||
69 | |||
70 | if (keylen) { | ||
71 | printk(KERN_ERR "%skey=[%u] '", prefix, keylen); | ||
72 | for (loop = 0; loop < keylen; loop++) | ||
73 | printk("%02x", keybuf[loop]); | ||
74 | printk("'\n"); | ||
75 | } | ||
76 | } | ||
77 | |||
78 | /* | ||
79 | * dump debugging info about a pair of objects | ||
80 | */ | ||
81 | static noinline void cachefiles_printk_object(struct cachefiles_object *object, | ||
82 | struct cachefiles_object *xobject) | ||
83 | { | ||
84 | u8 *keybuf; | ||
85 | |||
86 | keybuf = kmalloc(CACHEFILES_KEYBUF_SIZE, GFP_NOIO); | ||
87 | if (object) | ||
88 | __cachefiles_printk_object(object, "", keybuf); | ||
89 | if (xobject) | ||
90 | __cachefiles_printk_object(xobject, "x", keybuf); | ||
91 | kfree(keybuf); | ||
28 | } | 92 | } |
29 | 93 | ||
30 | /* | 94 | /* |
31 | * record the fact that an object is now active | 95 | * record the fact that an object is now active |
32 | */ | 96 | */ |
33 | static void cachefiles_mark_object_active(struct cachefiles_cache *cache, | 97 | static int cachefiles_mark_object_active(struct cachefiles_cache *cache, |
34 | struct cachefiles_object *object) | 98 | struct cachefiles_object *object) |
35 | { | 99 | { |
36 | struct cachefiles_object *xobject; | 100 | struct cachefiles_object *xobject; |
37 | struct rb_node **_p, *_parent = NULL; | 101 | struct rb_node **_p, *_parent = NULL; |
@@ -42,8 +106,11 @@ static void cachefiles_mark_object_active(struct cachefiles_cache *cache, | |||
42 | try_again: | 106 | try_again: |
43 | write_lock(&cache->active_lock); | 107 | write_lock(&cache->active_lock); |
44 | 108 | ||
45 | if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) | 109 | if (test_and_set_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags)) { |
110 | printk(KERN_ERR "CacheFiles: Error: Object already active\n"); | ||
111 | cachefiles_printk_object(object, NULL); | ||
46 | BUG(); | 112 | BUG(); |
113 | } | ||
47 | 114 | ||
48 | dentry = object->dentry; | 115 | dentry = object->dentry; |
49 | _p = &cache->active_nodes.rb_node; | 116 | _p = &cache->active_nodes.rb_node; |
@@ -66,8 +133,8 @@ try_again: | |||
66 | rb_insert_color(&object->active_node, &cache->active_nodes); | 133 | rb_insert_color(&object->active_node, &cache->active_nodes); |
67 | 134 | ||
68 | write_unlock(&cache->active_lock); | 135 | write_unlock(&cache->active_lock); |
69 | _leave(""); | 136 | _leave(" = 0"); |
70 | return; | 137 | return 0; |
71 | 138 | ||
72 | /* an old object from a previous incarnation is hogging the slot - we | 139 | /* an old object from a previous incarnation is hogging the slot - we |
73 | * need to wait for it to be destroyed */ | 140 | * need to wait for it to be destroyed */ |
@@ -76,44 +143,70 @@ wait_for_old_object: | |||
76 | printk(KERN_ERR "\n"); | 143 | printk(KERN_ERR "\n"); |
77 | printk(KERN_ERR "CacheFiles: Error:" | 144 | printk(KERN_ERR "CacheFiles: Error:" |
78 | " Unexpected object collision\n"); | 145 | " Unexpected object collision\n"); |
79 | printk(KERN_ERR "xobject: OBJ%x\n", | 146 | cachefiles_printk_object(object, xobject); |
80 | xobject->fscache.debug_id); | ||
81 | printk(KERN_ERR "xobjstate=%s\n", | ||
82 | fscache_object_states[xobject->fscache.state]); | ||
83 | printk(KERN_ERR "xobjflags=%lx\n", xobject->fscache.flags); | ||
84 | printk(KERN_ERR "xobjevent=%lx [%lx]\n", | ||
85 | xobject->fscache.events, xobject->fscache.event_mask); | ||
86 | printk(KERN_ERR "xops=%u inp=%u exc=%u\n", | ||
87 | xobject->fscache.n_ops, xobject->fscache.n_in_progress, | ||
88 | xobject->fscache.n_exclusive); | ||
89 | printk(KERN_ERR "xcookie=%p [pr=%p nd=%p fl=%lx]\n", | ||
90 | xobject->fscache.cookie, | ||
91 | xobject->fscache.cookie->parent, | ||
92 | xobject->fscache.cookie->netfs_data, | ||
93 | xobject->fscache.cookie->flags); | ||
94 | printk(KERN_ERR "xparent=%p\n", | ||
95 | xobject->fscache.parent); | ||
96 | printk(KERN_ERR "object: OBJ%x\n", | ||
97 | object->fscache.debug_id); | ||
98 | printk(KERN_ERR "cookie=%p [pr=%p nd=%p fl=%lx]\n", | ||
99 | object->fscache.cookie, | ||
100 | object->fscache.cookie->parent, | ||
101 | object->fscache.cookie->netfs_data, | ||
102 | object->fscache.cookie->flags); | ||
103 | printk(KERN_ERR "parent=%p\n", | ||
104 | object->fscache.parent); | ||
105 | BUG(); | 147 | BUG(); |
106 | } | 148 | } |
107 | atomic_inc(&xobject->usage); | 149 | atomic_inc(&xobject->usage); |
108 | write_unlock(&cache->active_lock); | 150 | write_unlock(&cache->active_lock); |
109 | 151 | ||
110 | _debug(">>> wait"); | 152 | if (test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)) { |
111 | wait_on_bit(&xobject->flags, CACHEFILES_OBJECT_ACTIVE, | 153 | wait_queue_head_t *wq; |
112 | cachefiles_wait_bit, TASK_UNINTERRUPTIBLE); | 154 | |
113 | _debug("<<< waited"); | 155 | signed long timeout = 60 * HZ; |
156 | wait_queue_t wait; | ||
157 | bool requeue; | ||
158 | |||
159 | /* if the object we're waiting for is queued for processing, | ||
160 | * then just put ourselves on the queue behind it */ | ||
161 | if (slow_work_is_queued(&xobject->fscache.work)) { | ||
162 | _debug("queue OBJ%x behind OBJ%x immediately", | ||
163 | object->fscache.debug_id, | ||
164 | xobject->fscache.debug_id); | ||
165 | goto requeue; | ||
166 | } | ||
167 | |||
168 | /* otherwise we sleep until either the object we're waiting for | ||
169 | * is done, or the slow-work facility wants the thread back to | ||
170 | * do other work */ | ||
171 | wq = bit_waitqueue(&xobject->flags, CACHEFILES_OBJECT_ACTIVE); | ||
172 | init_wait(&wait); | ||
173 | requeue = false; | ||
174 | do { | ||
175 | prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE); | ||
176 | if (!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)) | ||
177 | break; | ||
178 | requeue = slow_work_sleep_till_thread_needed( | ||
179 | &object->fscache.work, &timeout); | ||
180 | } while (timeout > 0 && !requeue); | ||
181 | finish_wait(wq, &wait); | ||
182 | |||
183 | if (requeue && | ||
184 | test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)) { | ||
185 | _debug("queue OBJ%x behind OBJ%x after wait", | ||
186 | object->fscache.debug_id, | ||
187 | xobject->fscache.debug_id); | ||
188 | goto requeue; | ||
189 | } | ||
190 | |||
191 | if (timeout <= 0) { | ||
192 | printk(KERN_ERR "\n"); | ||
193 | printk(KERN_ERR "CacheFiles: Error: Overlong" | ||
194 | " wait for old active object to go away\n"); | ||
195 | cachefiles_printk_object(object, xobject); | ||
196 | goto requeue; | ||
197 | } | ||
198 | } | ||
199 | |||
200 | ASSERT(!test_bit(CACHEFILES_OBJECT_ACTIVE, &xobject->flags)); | ||
114 | 201 | ||
115 | cache->cache.ops->put_object(&xobject->fscache); | 202 | cache->cache.ops->put_object(&xobject->fscache); |
116 | goto try_again; | 203 | goto try_again; |
204 | |||
205 | requeue: | ||
206 | clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); | ||
207 | cache->cache.ops->put_object(&xobject->fscache); | ||
208 | _leave(" = -ETIMEDOUT"); | ||
209 | return -ETIMEDOUT; | ||
117 | } | 210 | } |
118 | 211 | ||
119 | /* | 212 | /* |
@@ -254,7 +347,7 @@ int cachefiles_delete_object(struct cachefiles_cache *cache, | |||
254 | 347 | ||
255 | dir = dget_parent(object->dentry); | 348 | dir = dget_parent(object->dentry); |
256 | 349 | ||
257 | mutex_lock(&dir->d_inode->i_mutex); | 350 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); |
258 | ret = cachefiles_bury_object(cache, dir, object->dentry); | 351 | ret = cachefiles_bury_object(cache, dir, object->dentry); |
259 | 352 | ||
260 | dput(dir); | 353 | dput(dir); |
@@ -307,7 +400,7 @@ lookup_again: | |||
307 | /* search the current directory for the element name */ | 400 | /* search the current directory for the element name */ |
308 | _debug("lookup '%s'", name); | 401 | _debug("lookup '%s'", name); |
309 | 402 | ||
310 | mutex_lock(&dir->d_inode->i_mutex); | 403 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT); |
311 | 404 | ||
312 | start = jiffies; | 405 | start = jiffies; |
313 | next = lookup_one_len(name, dir, nlen); | 406 | next = lookup_one_len(name, dir, nlen); |
@@ -418,12 +511,15 @@ lookup_again: | |||
418 | } | 511 | } |
419 | 512 | ||
420 | /* note that we're now using this object */ | 513 | /* note that we're now using this object */ |
421 | cachefiles_mark_object_active(cache, object); | 514 | ret = cachefiles_mark_object_active(cache, object); |
422 | 515 | ||
423 | mutex_unlock(&dir->d_inode->i_mutex); | 516 | mutex_unlock(&dir->d_inode->i_mutex); |
424 | dput(dir); | 517 | dput(dir); |
425 | dir = NULL; | 518 | dir = NULL; |
426 | 519 | ||
520 | if (ret == -ETIMEDOUT) | ||
521 | goto mark_active_timed_out; | ||
522 | |||
427 | _debug("=== OBTAINED_OBJECT ==="); | 523 | _debug("=== OBTAINED_OBJECT ==="); |
428 | 524 | ||
429 | if (object->new) { | 525 | if (object->new) { |
@@ -467,6 +563,10 @@ create_error: | |||
467 | cachefiles_io_error(cache, "Create/mkdir failed"); | 563 | cachefiles_io_error(cache, "Create/mkdir failed"); |
468 | goto error; | 564 | goto error; |
469 | 565 | ||
566 | mark_active_timed_out: | ||
567 | _debug("mark active timed out"); | ||
568 | goto release_dentry; | ||
569 | |||
470 | check_error: | 570 | check_error: |
471 | _debug("check error %d", ret); | 571 | _debug("check error %d", ret); |
472 | write_lock(&cache->active_lock); | 572 | write_lock(&cache->active_lock); |
@@ -474,7 +574,7 @@ check_error: | |||
474 | clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); | 574 | clear_bit(CACHEFILES_OBJECT_ACTIVE, &object->flags); |
475 | wake_up_bit(&object->flags, CACHEFILES_OBJECT_ACTIVE); | 575 | wake_up_bit(&object->flags, CACHEFILES_OBJECT_ACTIVE); |
476 | write_unlock(&cache->active_lock); | 576 | write_unlock(&cache->active_lock); |
477 | 577 | release_dentry: | |
478 | dput(object->dentry); | 578 | dput(object->dentry); |
479 | object->dentry = NULL; | 579 | object->dentry = NULL; |
480 | goto error_out; | 580 | goto error_out; |
@@ -495,9 +595,6 @@ error: | |||
495 | error_out2: | 595 | error_out2: |
496 | dput(dir); | 596 | dput(dir); |
497 | error_out: | 597 | error_out: |
498 | if (ret == -ENOSPC) | ||
499 | ret = -ENOBUFS; | ||
500 | |||
501 | _leave(" = error %d", -ret); | 598 | _leave(" = error %d", -ret); |
502 | return ret; | 599 | return ret; |
503 | } | 600 | } |
diff --git a/fs/cachefiles/rdwr.c b/fs/cachefiles/rdwr.c index a69787e7dd96..1d8332563863 100644 --- a/fs/cachefiles/rdwr.c +++ b/fs/cachefiles/rdwr.c | |||
@@ -40,8 +40,10 @@ static int cachefiles_read_waiter(wait_queue_t *wait, unsigned mode, | |||
40 | 40 | ||
41 | _debug("--- monitor %p %lx ---", page, page->flags); | 41 | _debug("--- monitor %p %lx ---", page, page->flags); |
42 | 42 | ||
43 | if (!PageUptodate(page) && !PageError(page)) | 43 | if (!PageUptodate(page) && !PageError(page)) { |
44 | dump_stack(); | 44 | /* unlocked, not uptodate and not erronous? */ |
45 | _debug("page probably truncated"); | ||
46 | } | ||
45 | 47 | ||
46 | /* remove from the waitqueue */ | 48 | /* remove from the waitqueue */ |
47 | list_del(&wait->task_list); | 49 | list_del(&wait->task_list); |
@@ -61,6 +63,84 @@ static int cachefiles_read_waiter(wait_queue_t *wait, unsigned mode, | |||
61 | } | 63 | } |
62 | 64 | ||
63 | /* | 65 | /* |
66 | * handle a probably truncated page | ||
67 | * - check to see if the page is still relevant and reissue the read if | ||
68 | * possible | ||
69 | * - return -EIO on error, -ENODATA if the page is gone, -EINPROGRESS if we | ||
70 | * must wait again and 0 if successful | ||
71 | */ | ||
72 | static int cachefiles_read_reissue(struct cachefiles_object *object, | ||
73 | struct cachefiles_one_read *monitor) | ||
74 | { | ||
75 | struct address_space *bmapping = object->backer->d_inode->i_mapping; | ||
76 | struct page *backpage = monitor->back_page, *backpage2; | ||
77 | int ret; | ||
78 | |||
79 | kenter("{ino=%lx},{%lx,%lx}", | ||
80 | object->backer->d_inode->i_ino, | ||
81 | backpage->index, backpage->flags); | ||
82 | |||
83 | /* skip if the page was truncated away completely */ | ||
84 | if (backpage->mapping != bmapping) { | ||
85 | kleave(" = -ENODATA [mapping]"); | ||
86 | return -ENODATA; | ||
87 | } | ||
88 | |||
89 | backpage2 = find_get_page(bmapping, backpage->index); | ||
90 | if (!backpage2) { | ||
91 | kleave(" = -ENODATA [gone]"); | ||
92 | return -ENODATA; | ||
93 | } | ||
94 | |||
95 | if (backpage != backpage2) { | ||
96 | put_page(backpage2); | ||
97 | kleave(" = -ENODATA [different]"); | ||
98 | return -ENODATA; | ||
99 | } | ||
100 | |||
101 | /* the page is still there and we already have a ref on it, so we don't | ||
102 | * need a second */ | ||
103 | put_page(backpage2); | ||
104 | |||
105 | INIT_LIST_HEAD(&monitor->op_link); | ||
106 | add_page_wait_queue(backpage, &monitor->monitor); | ||
107 | |||
108 | if (trylock_page(backpage)) { | ||
109 | ret = -EIO; | ||
110 | if (PageError(backpage)) | ||
111 | goto unlock_discard; | ||
112 | ret = 0; | ||
113 | if (PageUptodate(backpage)) | ||
114 | goto unlock_discard; | ||
115 | |||
116 | kdebug("reissue read"); | ||
117 | ret = bmapping->a_ops->readpage(NULL, backpage); | ||
118 | if (ret < 0) | ||
119 | goto unlock_discard; | ||
120 | } | ||
121 | |||
122 | /* but the page may have been read before the monitor was installed, so | ||
123 | * the monitor may miss the event - so we have to ensure that we do get | ||
124 | * one in such a case */ | ||
125 | if (trylock_page(backpage)) { | ||
126 | _debug("jumpstart %p {%lx}", backpage, backpage->flags); | ||
127 | unlock_page(backpage); | ||
128 | } | ||
129 | |||
130 | /* it'll reappear on the todo list */ | ||
131 | kleave(" = -EINPROGRESS"); | ||
132 | return -EINPROGRESS; | ||
133 | |||
134 | unlock_discard: | ||
135 | unlock_page(backpage); | ||
136 | spin_lock_irq(&object->work_lock); | ||
137 | list_del(&monitor->op_link); | ||
138 | spin_unlock_irq(&object->work_lock); | ||
139 | kleave(" = %d", ret); | ||
140 | return ret; | ||
141 | } | ||
142 | |||
143 | /* | ||
64 | * copy data from backing pages to netfs pages to complete a read operation | 144 | * copy data from backing pages to netfs pages to complete a read operation |
65 | * - driven by FS-Cache's thread pool | 145 | * - driven by FS-Cache's thread pool |
66 | */ | 146 | */ |
@@ -92,20 +172,26 @@ static void cachefiles_read_copier(struct fscache_operation *_op) | |||
92 | 172 | ||
93 | _debug("- copy {%lu}", monitor->back_page->index); | 173 | _debug("- copy {%lu}", monitor->back_page->index); |
94 | 174 | ||
95 | error = -EIO; | 175 | recheck: |
96 | if (PageUptodate(monitor->back_page)) { | 176 | if (PageUptodate(monitor->back_page)) { |
97 | copy_highpage(monitor->netfs_page, monitor->back_page); | 177 | copy_highpage(monitor->netfs_page, monitor->back_page); |
98 | 178 | ||
99 | pagevec_add(&pagevec, monitor->netfs_page); | 179 | pagevec_add(&pagevec, monitor->netfs_page); |
100 | fscache_mark_pages_cached(monitor->op, &pagevec); | 180 | fscache_mark_pages_cached(monitor->op, &pagevec); |
101 | error = 0; | 181 | error = 0; |
102 | } | 182 | } else if (!PageError(monitor->back_page)) { |
103 | 183 | /* the page has probably been truncated */ | |
104 | if (error) | 184 | error = cachefiles_read_reissue(object, monitor); |
185 | if (error == -EINPROGRESS) | ||
186 | goto next; | ||
187 | goto recheck; | ||
188 | } else { | ||
105 | cachefiles_io_error_obj( | 189 | cachefiles_io_error_obj( |
106 | object, | 190 | object, |
107 | "Readpage failed on backing file %lx", | 191 | "Readpage failed on backing file %lx", |
108 | (unsigned long) monitor->back_page->flags); | 192 | (unsigned long) monitor->back_page->flags); |
193 | error = -EIO; | ||
194 | } | ||
109 | 195 | ||
110 | page_cache_release(monitor->back_page); | 196 | page_cache_release(monitor->back_page); |
111 | 197 | ||
@@ -114,6 +200,7 @@ static void cachefiles_read_copier(struct fscache_operation *_op) | |||
114 | fscache_put_retrieval(op); | 200 | fscache_put_retrieval(op); |
115 | kfree(monitor); | 201 | kfree(monitor); |
116 | 202 | ||
203 | next: | ||
117 | /* let the thread pool have some air occasionally */ | 204 | /* let the thread pool have some air occasionally */ |
118 | max--; | 205 | max--; |
119 | if (max < 0 || need_resched()) { | 206 | if (max < 0 || need_resched()) { |
@@ -333,7 +420,8 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op, | |||
333 | 420 | ||
334 | shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits; | 421 | shift = PAGE_SHIFT - inode->i_sb->s_blocksize_bits; |
335 | 422 | ||
336 | op->op.flags = FSCACHE_OP_FAST; | 423 | op->op.flags &= FSCACHE_OP_KEEP_FLAGS; |
424 | op->op.flags |= FSCACHE_OP_FAST; | ||
337 | op->op.processor = cachefiles_read_copier; | 425 | op->op.processor = cachefiles_read_copier; |
338 | 426 | ||
339 | pagevec_init(&pagevec, 0); | 427 | pagevec_init(&pagevec, 0); |
@@ -639,7 +727,8 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op, | |||
639 | 727 | ||
640 | pagevec_init(&pagevec, 0); | 728 | pagevec_init(&pagevec, 0); |
641 | 729 | ||
642 | op->op.flags = FSCACHE_OP_FAST; | 730 | op->op.flags &= FSCACHE_OP_KEEP_FLAGS; |
731 | op->op.flags |= FSCACHE_OP_FAST; | ||
643 | op->op.processor = cachefiles_read_copier; | 732 | op->op.processor = cachefiles_read_copier; |
644 | 733 | ||
645 | INIT_LIST_HEAD(&backpages); | 734 | INIT_LIST_HEAD(&backpages); |
@@ -801,7 +890,8 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page) | |||
801 | struct cachefiles_cache *cache; | 890 | struct cachefiles_cache *cache; |
802 | mm_segment_t old_fs; | 891 | mm_segment_t old_fs; |
803 | struct file *file; | 892 | struct file *file; |
804 | loff_t pos; | 893 | loff_t pos, eof; |
894 | size_t len; | ||
805 | void *data; | 895 | void *data; |
806 | int ret; | 896 | int ret; |
807 | 897 | ||
@@ -835,15 +925,29 @@ int cachefiles_write_page(struct fscache_storage *op, struct page *page) | |||
835 | ret = -EIO; | 925 | ret = -EIO; |
836 | if (file->f_op->write) { | 926 | if (file->f_op->write) { |
837 | pos = (loff_t) page->index << PAGE_SHIFT; | 927 | pos = (loff_t) page->index << PAGE_SHIFT; |
928 | |||
929 | /* we mustn't write more data than we have, so we have | ||
930 | * to beware of a partial page at EOF */ | ||
931 | eof = object->fscache.store_limit_l; | ||
932 | len = PAGE_SIZE; | ||
933 | if (eof & ~PAGE_MASK) { | ||
934 | ASSERTCMP(pos, <, eof); | ||
935 | if (eof - pos < PAGE_SIZE) { | ||
936 | _debug("cut short %llx to %llx", | ||
937 | pos, eof); | ||
938 | len = eof - pos; | ||
939 | ASSERTCMP(pos + len, ==, eof); | ||
940 | } | ||
941 | } | ||
942 | |||
838 | data = kmap(page); | 943 | data = kmap(page); |
839 | old_fs = get_fs(); | 944 | old_fs = get_fs(); |
840 | set_fs(KERNEL_DS); | 945 | set_fs(KERNEL_DS); |
841 | ret = file->f_op->write( | 946 | ret = file->f_op->write( |
842 | file, (const void __user *) data, PAGE_SIZE, | 947 | file, (const void __user *) data, len, &pos); |
843 | &pos); | ||
844 | set_fs(old_fs); | 948 | set_fs(old_fs); |
845 | kunmap(page); | 949 | kunmap(page); |
846 | if (ret != PAGE_SIZE) | 950 | if (ret != len) |
847 | ret = -EIO; | 951 | ret = -EIO; |
848 | } | 952 | } |
849 | fput(file); | 953 | fput(file); |
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 145540a316ab..094ea65afc85 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
@@ -1,3 +1,12 @@ | |||
1 | Version 1.61 | ||
2 | ------------ | ||
3 | Fix append problem to Samba servers (files opened with O_APPEND could | ||
4 | have duplicated data). Fix oops in cifs_lookup. Workaround problem | ||
5 | mounting to OS/400 Netserve. Fix oops in cifs_get_tcp_session. | ||
6 | Disable use of server inode numbers when server only | ||
7 | partially supports them (e.g. for one server querying inode numbers on | ||
8 | FindFirst fails but QPathInfo queries works). | ||
9 | |||
1 | Version 1.60 | 10 | Version 1.60 |
2 | ------------- | 11 | ------------- |
3 | Fix memory leak in reconnect. Fix oops in DFS mount error path. | 12 | Fix memory leak in reconnect. Fix oops in DFS mount error path. |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 9a5e4f5f3122..29f1da761bbf 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -1037,7 +1037,7 @@ init_cifs(void) | |||
1037 | if (rc) | 1037 | if (rc) |
1038 | goto out_unregister_key_type; | 1038 | goto out_unregister_key_type; |
1039 | #endif | 1039 | #endif |
1040 | rc = slow_work_register_user(); | 1040 | rc = slow_work_register_user(THIS_MODULE); |
1041 | if (rc) | 1041 | if (rc) |
1042 | goto out_unregister_resolver_key; | 1042 | goto out_unregister_resolver_key; |
1043 | 1043 | ||
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 627a60a6c1b1..1f42f772865a 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -214,8 +214,6 @@ int cifs_posix_open(char *full_path, struct inode **pinode, | |||
214 | posix_flags |= SMB_O_EXCL; | 214 | posix_flags |= SMB_O_EXCL; |
215 | if (oflags & O_TRUNC) | 215 | if (oflags & O_TRUNC) |
216 | posix_flags |= SMB_O_TRUNC; | 216 | posix_flags |= SMB_O_TRUNC; |
217 | if (oflags & O_APPEND) | ||
218 | posix_flags |= SMB_O_APPEND; | ||
219 | if (oflags & O_SYNC) | 217 | if (oflags & O_SYNC) |
220 | posix_flags |= SMB_O_SYNC; | 218 | posix_flags |= SMB_O_SYNC; |
221 | if (oflags & O_DIRECTORY) | 219 | if (oflags & O_DIRECTORY) |
@@ -643,9 +641,9 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
643 | * O_EXCL: optimize away the lookup, but don't hash the dentry. Let | 641 | * O_EXCL: optimize away the lookup, but don't hash the dentry. Let |
644 | * the VFS handle the create. | 642 | * the VFS handle the create. |
645 | */ | 643 | */ |
646 | if (nd->flags & LOOKUP_EXCL) { | 644 | if (nd && (nd->flags & LOOKUP_EXCL)) { |
647 | d_instantiate(direntry, NULL); | 645 | d_instantiate(direntry, NULL); |
648 | return 0; | 646 | return NULL; |
649 | } | 647 | } |
650 | 648 | ||
651 | /* can not grab the rename sem here since it would | 649 | /* can not grab the rename sem here since it would |
@@ -675,7 +673,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
675 | * reduction in network traffic in the other paths. | 673 | * reduction in network traffic in the other paths. |
676 | */ | 674 | */ |
677 | if (pTcon->unix_ext) { | 675 | if (pTcon->unix_ext) { |
678 | if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) && | 676 | if (nd && !(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) && |
679 | (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open && | 677 | (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open && |
680 | (nd->intent.open.flags & O_CREAT)) { | 678 | (nd->intent.open.flags & O_CREAT)) { |
681 | rc = cifs_posix_open(full_path, &newInode, nd->path.mnt, | 679 | rc = cifs_posix_open(full_path, &newInode, nd->path.mnt, |
diff --git a/fs/fscache/Kconfig b/fs/fscache/Kconfig index 9bbb8ce7bea0..864dac20a242 100644 --- a/fs/fscache/Kconfig +++ b/fs/fscache/Kconfig | |||
@@ -54,3 +54,10 @@ config FSCACHE_DEBUG | |||
54 | enabled by setting bits in /sys/modules/fscache/parameter/debug. | 54 | enabled by setting bits in /sys/modules/fscache/parameter/debug. |
55 | 55 | ||
56 | See Documentation/filesystems/caching/fscache.txt for more information. | 56 | See Documentation/filesystems/caching/fscache.txt for more information. |
57 | |||
58 | config FSCACHE_OBJECT_LIST | ||
59 | bool "Maintain global object list for debugging purposes" | ||
60 | depends on FSCACHE && PROC_FS | ||
61 | help | ||
62 | Maintain a global list of active fscache objects that can be | ||
63 | retrieved through /proc/fs/fscache/objects for debugging purposes | ||
diff --git a/fs/fscache/Makefile b/fs/fscache/Makefile index 91571b95aacc..6d561531cb36 100644 --- a/fs/fscache/Makefile +++ b/fs/fscache/Makefile | |||
@@ -15,5 +15,6 @@ fscache-y := \ | |||
15 | fscache-$(CONFIG_PROC_FS) += proc.o | 15 | fscache-$(CONFIG_PROC_FS) += proc.o |
16 | fscache-$(CONFIG_FSCACHE_STATS) += stats.o | 16 | fscache-$(CONFIG_FSCACHE_STATS) += stats.o |
17 | fscache-$(CONFIG_FSCACHE_HISTOGRAM) += histogram.o | 17 | fscache-$(CONFIG_FSCACHE_HISTOGRAM) += histogram.o |
18 | fscache-$(CONFIG_FSCACHE_OBJECT_LIST) += object-list.o | ||
18 | 19 | ||
19 | obj-$(CONFIG_FSCACHE) := fscache.o | 20 | obj-$(CONFIG_FSCACHE) := fscache.o |
diff --git a/fs/fscache/cache.c b/fs/fscache/cache.c index e21985bbb1fb..6a3c48abd677 100644 --- a/fs/fscache/cache.c +++ b/fs/fscache/cache.c | |||
@@ -263,6 +263,7 @@ int fscache_add_cache(struct fscache_cache *cache, | |||
263 | spin_lock(&cache->object_list_lock); | 263 | spin_lock(&cache->object_list_lock); |
264 | list_add_tail(&ifsdef->cache_link, &cache->object_list); | 264 | list_add_tail(&ifsdef->cache_link, &cache->object_list); |
265 | spin_unlock(&cache->object_list_lock); | 265 | spin_unlock(&cache->object_list_lock); |
266 | fscache_objlist_add(ifsdef); | ||
266 | 267 | ||
267 | /* add the cache's netfs definition index object to the top level index | 268 | /* add the cache's netfs definition index object to the top level index |
268 | * cookie as a known backing object */ | 269 | * cookie as a known backing object */ |
@@ -380,11 +381,15 @@ void fscache_withdraw_cache(struct fscache_cache *cache) | |||
380 | 381 | ||
381 | /* make sure all pages pinned by operations on behalf of the netfs are | 382 | /* make sure all pages pinned by operations on behalf of the netfs are |
382 | * written to disk */ | 383 | * written to disk */ |
384 | fscache_stat(&fscache_n_cop_sync_cache); | ||
383 | cache->ops->sync_cache(cache); | 385 | cache->ops->sync_cache(cache); |
386 | fscache_stat_d(&fscache_n_cop_sync_cache); | ||
384 | 387 | ||
385 | /* dissociate all the netfs pages backed by this cache from the block | 388 | /* dissociate all the netfs pages backed by this cache from the block |
386 | * mappings in the cache */ | 389 | * mappings in the cache */ |
390 | fscache_stat(&fscache_n_cop_dissociate_pages); | ||
387 | cache->ops->dissociate_pages(cache); | 391 | cache->ops->dissociate_pages(cache); |
392 | fscache_stat_d(&fscache_n_cop_dissociate_pages); | ||
388 | 393 | ||
389 | /* we now have to destroy all the active objects pertaining to this | 394 | /* we now have to destroy all the active objects pertaining to this |
390 | * cache - which we do by passing them off to thread pool to be | 395 | * cache - which we do by passing them off to thread pool to be |
diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index 72fd18f6c71f..990535071a8a 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c | |||
@@ -36,6 +36,7 @@ void fscache_cookie_init_once(void *_cookie) | |||
36 | 36 | ||
37 | memset(cookie, 0, sizeof(*cookie)); | 37 | memset(cookie, 0, sizeof(*cookie)); |
38 | spin_lock_init(&cookie->lock); | 38 | spin_lock_init(&cookie->lock); |
39 | spin_lock_init(&cookie->stores_lock); | ||
39 | INIT_HLIST_HEAD(&cookie->backing_objects); | 40 | INIT_HLIST_HEAD(&cookie->backing_objects); |
40 | } | 41 | } |
41 | 42 | ||
@@ -102,7 +103,9 @@ struct fscache_cookie *__fscache_acquire_cookie( | |||
102 | cookie->netfs_data = netfs_data; | 103 | cookie->netfs_data = netfs_data; |
103 | cookie->flags = 0; | 104 | cookie->flags = 0; |
104 | 105 | ||
105 | INIT_RADIX_TREE(&cookie->stores, GFP_NOFS); | 106 | /* radix tree insertion won't use the preallocation pool unless it's |
107 | * told it may not wait */ | ||
108 | INIT_RADIX_TREE(&cookie->stores, GFP_NOFS & ~__GFP_WAIT); | ||
106 | 109 | ||
107 | switch (cookie->def->type) { | 110 | switch (cookie->def->type) { |
108 | case FSCACHE_COOKIE_TYPE_INDEX: | 111 | case FSCACHE_COOKIE_TYPE_INDEX: |
@@ -249,7 +252,9 @@ static int fscache_alloc_object(struct fscache_cache *cache, | |||
249 | 252 | ||
250 | /* ask the cache to allocate an object (we may end up with duplicate | 253 | /* ask the cache to allocate an object (we may end up with duplicate |
251 | * objects at this stage, but we sort that out later) */ | 254 | * objects at this stage, but we sort that out later) */ |
255 | fscache_stat(&fscache_n_cop_alloc_object); | ||
252 | object = cache->ops->alloc_object(cache, cookie); | 256 | object = cache->ops->alloc_object(cache, cookie); |
257 | fscache_stat_d(&fscache_n_cop_alloc_object); | ||
253 | if (IS_ERR(object)) { | 258 | if (IS_ERR(object)) { |
254 | fscache_stat(&fscache_n_object_no_alloc); | 259 | fscache_stat(&fscache_n_object_no_alloc); |
255 | ret = PTR_ERR(object); | 260 | ret = PTR_ERR(object); |
@@ -270,8 +275,11 @@ static int fscache_alloc_object(struct fscache_cache *cache, | |||
270 | /* only attach if we managed to allocate all we needed, otherwise | 275 | /* only attach if we managed to allocate all we needed, otherwise |
271 | * discard the object we just allocated and instead use the one | 276 | * discard the object we just allocated and instead use the one |
272 | * attached to the cookie */ | 277 | * attached to the cookie */ |
273 | if (fscache_attach_object(cookie, object) < 0) | 278 | if (fscache_attach_object(cookie, object) < 0) { |
279 | fscache_stat(&fscache_n_cop_put_object); | ||
274 | cache->ops->put_object(object); | 280 | cache->ops->put_object(object); |
281 | fscache_stat_d(&fscache_n_cop_put_object); | ||
282 | } | ||
275 | 283 | ||
276 | _leave(" = 0"); | 284 | _leave(" = 0"); |
277 | return 0; | 285 | return 0; |
@@ -287,7 +295,9 @@ object_already_extant: | |||
287 | return 0; | 295 | return 0; |
288 | 296 | ||
289 | error_put: | 297 | error_put: |
298 | fscache_stat(&fscache_n_cop_put_object); | ||
290 | cache->ops->put_object(object); | 299 | cache->ops->put_object(object); |
300 | fscache_stat_d(&fscache_n_cop_put_object); | ||
291 | error: | 301 | error: |
292 | _leave(" = %d", ret); | 302 | _leave(" = %d", ret); |
293 | return ret; | 303 | return ret; |
@@ -349,6 +359,8 @@ static int fscache_attach_object(struct fscache_cookie *cookie, | |||
349 | object->cookie = cookie; | 359 | object->cookie = cookie; |
350 | atomic_inc(&cookie->usage); | 360 | atomic_inc(&cookie->usage); |
351 | hlist_add_head(&object->cookie_link, &cookie->backing_objects); | 361 | hlist_add_head(&object->cookie_link, &cookie->backing_objects); |
362 | |||
363 | fscache_objlist_add(object); | ||
352 | ret = 0; | 364 | ret = 0; |
353 | 365 | ||
354 | cant_attach_object: | 366 | cant_attach_object: |
@@ -403,6 +415,8 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire) | |||
403 | unsigned long event; | 415 | unsigned long event; |
404 | 416 | ||
405 | fscache_stat(&fscache_n_relinquishes); | 417 | fscache_stat(&fscache_n_relinquishes); |
418 | if (retire) | ||
419 | fscache_stat(&fscache_n_relinquishes_retire); | ||
406 | 420 | ||
407 | if (!cookie) { | 421 | if (!cookie) { |
408 | fscache_stat(&fscache_n_relinquishes_null); | 422 | fscache_stat(&fscache_n_relinquishes_null); |
@@ -428,12 +442,8 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire) | |||
428 | 442 | ||
429 | event = retire ? FSCACHE_OBJECT_EV_RETIRE : FSCACHE_OBJECT_EV_RELEASE; | 443 | event = retire ? FSCACHE_OBJECT_EV_RETIRE : FSCACHE_OBJECT_EV_RELEASE; |
430 | 444 | ||
431 | /* detach pointers back to the netfs */ | ||
432 | spin_lock(&cookie->lock); | 445 | spin_lock(&cookie->lock); |
433 | 446 | ||
434 | cookie->netfs_data = NULL; | ||
435 | cookie->def = NULL; | ||
436 | |||
437 | /* break links with all the active objects */ | 447 | /* break links with all the active objects */ |
438 | while (!hlist_empty(&cookie->backing_objects)) { | 448 | while (!hlist_empty(&cookie->backing_objects)) { |
439 | object = hlist_entry(cookie->backing_objects.first, | 449 | object = hlist_entry(cookie->backing_objects.first, |
@@ -456,6 +466,10 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire) | |||
456 | BUG(); | 466 | BUG(); |
457 | } | 467 | } |
458 | 468 | ||
469 | /* detach pointers back to the netfs */ | ||
470 | cookie->netfs_data = NULL; | ||
471 | cookie->def = NULL; | ||
472 | |||
459 | spin_unlock(&cookie->lock); | 473 | spin_unlock(&cookie->lock); |
460 | 474 | ||
461 | if (cookie->parent) { | 475 | if (cookie->parent) { |
diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h index 1c341304621f..edd7434ab6e5 100644 --- a/fs/fscache/internal.h +++ b/fs/fscache/internal.h | |||
@@ -17,6 +17,7 @@ | |||
17 | * - cache->object_list_lock | 17 | * - cache->object_list_lock |
18 | * - object->lock | 18 | * - object->lock |
19 | * - object->parent->lock | 19 | * - object->parent->lock |
20 | * - cookie->stores_lock | ||
20 | * - fscache_thread_lock | 21 | * - fscache_thread_lock |
21 | * | 22 | * |
22 | */ | 23 | */ |
@@ -88,17 +89,31 @@ extern int fscache_wait_bit_interruptible(void *); | |||
88 | /* | 89 | /* |
89 | * object.c | 90 | * object.c |
90 | */ | 91 | */ |
92 | extern const char fscache_object_states_short[FSCACHE_OBJECT__NSTATES][5]; | ||
93 | |||
91 | extern void fscache_withdrawing_object(struct fscache_cache *, | 94 | extern void fscache_withdrawing_object(struct fscache_cache *, |
92 | struct fscache_object *); | 95 | struct fscache_object *); |
93 | extern void fscache_enqueue_object(struct fscache_object *); | 96 | extern void fscache_enqueue_object(struct fscache_object *); |
94 | 97 | ||
95 | /* | 98 | /* |
99 | * object-list.c | ||
100 | */ | ||
101 | #ifdef CONFIG_FSCACHE_OBJECT_LIST | ||
102 | extern const struct file_operations fscache_objlist_fops; | ||
103 | |||
104 | extern void fscache_objlist_add(struct fscache_object *); | ||
105 | #else | ||
106 | #define fscache_objlist_add(object) do {} while(0) | ||
107 | #endif | ||
108 | |||
109 | /* | ||
96 | * operation.c | 110 | * operation.c |
97 | */ | 111 | */ |
98 | extern int fscache_submit_exclusive_op(struct fscache_object *, | 112 | extern int fscache_submit_exclusive_op(struct fscache_object *, |
99 | struct fscache_operation *); | 113 | struct fscache_operation *); |
100 | extern int fscache_submit_op(struct fscache_object *, | 114 | extern int fscache_submit_op(struct fscache_object *, |
101 | struct fscache_operation *); | 115 | struct fscache_operation *); |
116 | extern int fscache_cancel_op(struct fscache_operation *); | ||
102 | extern void fscache_abort_object(struct fscache_object *); | 117 | extern void fscache_abort_object(struct fscache_object *); |
103 | extern void fscache_start_operations(struct fscache_object *); | 118 | extern void fscache_start_operations(struct fscache_object *); |
104 | extern void fscache_operation_gc(struct work_struct *); | 119 | extern void fscache_operation_gc(struct work_struct *); |
@@ -127,6 +142,8 @@ extern atomic_t fscache_n_op_enqueue; | |||
127 | extern atomic_t fscache_n_op_deferred_release; | 142 | extern atomic_t fscache_n_op_deferred_release; |
128 | extern atomic_t fscache_n_op_release; | 143 | extern atomic_t fscache_n_op_release; |
129 | extern atomic_t fscache_n_op_gc; | 144 | extern atomic_t fscache_n_op_gc; |
145 | extern atomic_t fscache_n_op_cancelled; | ||
146 | extern atomic_t fscache_n_op_rejected; | ||
130 | 147 | ||
131 | extern atomic_t fscache_n_attr_changed; | 148 | extern atomic_t fscache_n_attr_changed; |
132 | extern atomic_t fscache_n_attr_changed_ok; | 149 | extern atomic_t fscache_n_attr_changed_ok; |
@@ -138,6 +155,8 @@ extern atomic_t fscache_n_allocs; | |||
138 | extern atomic_t fscache_n_allocs_ok; | 155 | extern atomic_t fscache_n_allocs_ok; |
139 | extern atomic_t fscache_n_allocs_wait; | 156 | extern atomic_t fscache_n_allocs_wait; |
140 | extern atomic_t fscache_n_allocs_nobufs; | 157 | extern atomic_t fscache_n_allocs_nobufs; |
158 | extern atomic_t fscache_n_allocs_intr; | ||
159 | extern atomic_t fscache_n_allocs_object_dead; | ||
141 | extern atomic_t fscache_n_alloc_ops; | 160 | extern atomic_t fscache_n_alloc_ops; |
142 | extern atomic_t fscache_n_alloc_op_waits; | 161 | extern atomic_t fscache_n_alloc_op_waits; |
143 | 162 | ||
@@ -148,6 +167,7 @@ extern atomic_t fscache_n_retrievals_nodata; | |||
148 | extern atomic_t fscache_n_retrievals_nobufs; | 167 | extern atomic_t fscache_n_retrievals_nobufs; |
149 | extern atomic_t fscache_n_retrievals_intr; | 168 | extern atomic_t fscache_n_retrievals_intr; |
150 | extern atomic_t fscache_n_retrievals_nomem; | 169 | extern atomic_t fscache_n_retrievals_nomem; |
170 | extern atomic_t fscache_n_retrievals_object_dead; | ||
151 | extern atomic_t fscache_n_retrieval_ops; | 171 | extern atomic_t fscache_n_retrieval_ops; |
152 | extern atomic_t fscache_n_retrieval_op_waits; | 172 | extern atomic_t fscache_n_retrieval_op_waits; |
153 | 173 | ||
@@ -158,6 +178,14 @@ extern atomic_t fscache_n_stores_nobufs; | |||
158 | extern atomic_t fscache_n_stores_oom; | 178 | extern atomic_t fscache_n_stores_oom; |
159 | extern atomic_t fscache_n_store_ops; | 179 | extern atomic_t fscache_n_store_ops; |
160 | extern atomic_t fscache_n_store_calls; | 180 | extern atomic_t fscache_n_store_calls; |
181 | extern atomic_t fscache_n_store_pages; | ||
182 | extern atomic_t fscache_n_store_radix_deletes; | ||
183 | extern atomic_t fscache_n_store_pages_over_limit; | ||
184 | |||
185 | extern atomic_t fscache_n_store_vmscan_not_storing; | ||
186 | extern atomic_t fscache_n_store_vmscan_gone; | ||
187 | extern atomic_t fscache_n_store_vmscan_busy; | ||
188 | extern atomic_t fscache_n_store_vmscan_cancelled; | ||
161 | 189 | ||
162 | extern atomic_t fscache_n_marks; | 190 | extern atomic_t fscache_n_marks; |
163 | extern atomic_t fscache_n_uncaches; | 191 | extern atomic_t fscache_n_uncaches; |
@@ -176,6 +204,7 @@ extern atomic_t fscache_n_updates_run; | |||
176 | extern atomic_t fscache_n_relinquishes; | 204 | extern atomic_t fscache_n_relinquishes; |
177 | extern atomic_t fscache_n_relinquishes_null; | 205 | extern atomic_t fscache_n_relinquishes_null; |
178 | extern atomic_t fscache_n_relinquishes_waitcrt; | 206 | extern atomic_t fscache_n_relinquishes_waitcrt; |
207 | extern atomic_t fscache_n_relinquishes_retire; | ||
179 | 208 | ||
180 | extern atomic_t fscache_n_cookie_index; | 209 | extern atomic_t fscache_n_cookie_index; |
181 | extern atomic_t fscache_n_cookie_data; | 210 | extern atomic_t fscache_n_cookie_data; |
@@ -186,6 +215,7 @@ extern atomic_t fscache_n_object_no_alloc; | |||
186 | extern atomic_t fscache_n_object_lookups; | 215 | extern atomic_t fscache_n_object_lookups; |
187 | extern atomic_t fscache_n_object_lookups_negative; | 216 | extern atomic_t fscache_n_object_lookups_negative; |
188 | extern atomic_t fscache_n_object_lookups_positive; | 217 | extern atomic_t fscache_n_object_lookups_positive; |
218 | extern atomic_t fscache_n_object_lookups_timed_out; | ||
189 | extern atomic_t fscache_n_object_created; | 219 | extern atomic_t fscache_n_object_created; |
190 | extern atomic_t fscache_n_object_avail; | 220 | extern atomic_t fscache_n_object_avail; |
191 | extern atomic_t fscache_n_object_dead; | 221 | extern atomic_t fscache_n_object_dead; |
@@ -195,15 +225,41 @@ extern atomic_t fscache_n_checkaux_okay; | |||
195 | extern atomic_t fscache_n_checkaux_update; | 225 | extern atomic_t fscache_n_checkaux_update; |
196 | extern atomic_t fscache_n_checkaux_obsolete; | 226 | extern atomic_t fscache_n_checkaux_obsolete; |
197 | 227 | ||
228 | extern atomic_t fscache_n_cop_alloc_object; | ||
229 | extern atomic_t fscache_n_cop_lookup_object; | ||
230 | extern atomic_t fscache_n_cop_lookup_complete; | ||
231 | extern atomic_t fscache_n_cop_grab_object; | ||
232 | extern atomic_t fscache_n_cop_update_object; | ||
233 | extern atomic_t fscache_n_cop_drop_object; | ||
234 | extern atomic_t fscache_n_cop_put_object; | ||
235 | extern atomic_t fscache_n_cop_sync_cache; | ||
236 | extern atomic_t fscache_n_cop_attr_changed; | ||
237 | extern atomic_t fscache_n_cop_read_or_alloc_page; | ||
238 | extern atomic_t fscache_n_cop_read_or_alloc_pages; | ||
239 | extern atomic_t fscache_n_cop_allocate_page; | ||
240 | extern atomic_t fscache_n_cop_allocate_pages; | ||
241 | extern atomic_t fscache_n_cop_write_page; | ||
242 | extern atomic_t fscache_n_cop_uncache_page; | ||
243 | extern atomic_t fscache_n_cop_dissociate_pages; | ||
244 | |||
198 | static inline void fscache_stat(atomic_t *stat) | 245 | static inline void fscache_stat(atomic_t *stat) |
199 | { | 246 | { |
200 | atomic_inc(stat); | 247 | atomic_inc(stat); |
201 | } | 248 | } |
202 | 249 | ||
250 | static inline void fscache_stat_d(atomic_t *stat) | ||
251 | { | ||
252 | atomic_dec(stat); | ||
253 | } | ||
254 | |||
255 | #define __fscache_stat(stat) (stat) | ||
256 | |||
203 | extern const struct file_operations fscache_stats_fops; | 257 | extern const struct file_operations fscache_stats_fops; |
204 | #else | 258 | #else |
205 | 259 | ||
260 | #define __fscache_stat(stat) (NULL) | ||
206 | #define fscache_stat(stat) do {} while (0) | 261 | #define fscache_stat(stat) do {} while (0) |
262 | #define fscache_stat_d(stat) do {} while (0) | ||
207 | #endif | 263 | #endif |
208 | 264 | ||
209 | /* | 265 | /* |
diff --git a/fs/fscache/main.c b/fs/fscache/main.c index 4de41b597499..add6bdb53f04 100644 --- a/fs/fscache/main.c +++ b/fs/fscache/main.c | |||
@@ -48,7 +48,7 @@ static int __init fscache_init(void) | |||
48 | { | 48 | { |
49 | int ret; | 49 | int ret; |
50 | 50 | ||
51 | ret = slow_work_register_user(); | 51 | ret = slow_work_register_user(THIS_MODULE); |
52 | if (ret < 0) | 52 | if (ret < 0) |
53 | goto error_slow_work; | 53 | goto error_slow_work; |
54 | 54 | ||
@@ -80,7 +80,7 @@ error_kobj: | |||
80 | error_cookie_jar: | 80 | error_cookie_jar: |
81 | fscache_proc_cleanup(); | 81 | fscache_proc_cleanup(); |
82 | error_proc: | 82 | error_proc: |
83 | slow_work_unregister_user(); | 83 | slow_work_unregister_user(THIS_MODULE); |
84 | error_slow_work: | 84 | error_slow_work: |
85 | return ret; | 85 | return ret; |
86 | } | 86 | } |
@@ -97,7 +97,7 @@ static void __exit fscache_exit(void) | |||
97 | kobject_put(fscache_root); | 97 | kobject_put(fscache_root); |
98 | kmem_cache_destroy(fscache_cookie_jar); | 98 | kmem_cache_destroy(fscache_cookie_jar); |
99 | fscache_proc_cleanup(); | 99 | fscache_proc_cleanup(); |
100 | slow_work_unregister_user(); | 100 | slow_work_unregister_user(THIS_MODULE); |
101 | printk(KERN_NOTICE "FS-Cache: Unloaded\n"); | 101 | printk(KERN_NOTICE "FS-Cache: Unloaded\n"); |
102 | } | 102 | } |
103 | 103 | ||
diff --git a/fs/fscache/object-list.c b/fs/fscache/object-list.c new file mode 100644 index 000000000000..e590242fa41a --- /dev/null +++ b/fs/fscache/object-list.c | |||
@@ -0,0 +1,432 @@ | |||
1 | /* Global fscache object list maintainer and viewer | ||
2 | * | ||
3 | * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #define FSCACHE_DEBUG_LEVEL COOKIE | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/seq_file.h> | ||
15 | #include <linux/key.h> | ||
16 | #include <keys/user-type.h> | ||
17 | #include "internal.h" | ||
18 | |||
19 | static struct rb_root fscache_object_list; | ||
20 | static DEFINE_RWLOCK(fscache_object_list_lock); | ||
21 | |||
22 | struct fscache_objlist_data { | ||
23 | unsigned long config; /* display configuration */ | ||
24 | #define FSCACHE_OBJLIST_CONFIG_KEY 0x00000001 /* show object keys */ | ||
25 | #define FSCACHE_OBJLIST_CONFIG_AUX 0x00000002 /* show object auxdata */ | ||
26 | #define FSCACHE_OBJLIST_CONFIG_COOKIE 0x00000004 /* show objects with cookies */ | ||
27 | #define FSCACHE_OBJLIST_CONFIG_NOCOOKIE 0x00000008 /* show objects without cookies */ | ||
28 | #define FSCACHE_OBJLIST_CONFIG_BUSY 0x00000010 /* show busy objects */ | ||
29 | #define FSCACHE_OBJLIST_CONFIG_IDLE 0x00000020 /* show idle objects */ | ||
30 | #define FSCACHE_OBJLIST_CONFIG_PENDWR 0x00000040 /* show objects with pending writes */ | ||
31 | #define FSCACHE_OBJLIST_CONFIG_NOPENDWR 0x00000080 /* show objects without pending writes */ | ||
32 | #define FSCACHE_OBJLIST_CONFIG_READS 0x00000100 /* show objects with active reads */ | ||
33 | #define FSCACHE_OBJLIST_CONFIG_NOREADS 0x00000200 /* show objects without active reads */ | ||
34 | #define FSCACHE_OBJLIST_CONFIG_EVENTS 0x00000400 /* show objects with events */ | ||
35 | #define FSCACHE_OBJLIST_CONFIG_NOEVENTS 0x00000800 /* show objects without no events */ | ||
36 | #define FSCACHE_OBJLIST_CONFIG_WORK 0x00001000 /* show objects with slow work */ | ||
37 | #define FSCACHE_OBJLIST_CONFIG_NOWORK 0x00002000 /* show objects without slow work */ | ||
38 | |||
39 | u8 buf[512]; /* key and aux data buffer */ | ||
40 | }; | ||
41 | |||
42 | /* | ||
43 | * Add an object to the object list | ||
44 | * - we use the address of the fscache_object structure as the key into the | ||
45 | * tree | ||
46 | */ | ||
47 | void fscache_objlist_add(struct fscache_object *obj) | ||
48 | { | ||
49 | struct fscache_object *xobj; | ||
50 | struct rb_node **p = &fscache_object_list.rb_node, *parent = NULL; | ||
51 | |||
52 | write_lock(&fscache_object_list_lock); | ||
53 | |||
54 | while (*p) { | ||
55 | parent = *p; | ||
56 | xobj = rb_entry(parent, struct fscache_object, objlist_link); | ||
57 | |||
58 | if (obj < xobj) | ||
59 | p = &(*p)->rb_left; | ||
60 | else if (obj > xobj) | ||
61 | p = &(*p)->rb_right; | ||
62 | else | ||
63 | BUG(); | ||
64 | } | ||
65 | |||
66 | rb_link_node(&obj->objlist_link, parent, p); | ||
67 | rb_insert_color(&obj->objlist_link, &fscache_object_list); | ||
68 | |||
69 | write_unlock(&fscache_object_list_lock); | ||
70 | } | ||
71 | |||
72 | /** | ||
73 | * fscache_object_destroy - Note that a cache object is about to be destroyed | ||
74 | * @object: The object to be destroyed | ||
75 | * | ||
76 | * Note the imminent destruction and deallocation of a cache object record. | ||
77 | */ | ||
78 | void fscache_object_destroy(struct fscache_object *obj) | ||
79 | { | ||
80 | write_lock(&fscache_object_list_lock); | ||
81 | |||
82 | BUG_ON(RB_EMPTY_ROOT(&fscache_object_list)); | ||
83 | rb_erase(&obj->objlist_link, &fscache_object_list); | ||
84 | |||
85 | write_unlock(&fscache_object_list_lock); | ||
86 | } | ||
87 | EXPORT_SYMBOL(fscache_object_destroy); | ||
88 | |||
89 | /* | ||
90 | * find the object in the tree on or after the specified index | ||
91 | */ | ||
92 | static struct fscache_object *fscache_objlist_lookup(loff_t *_pos) | ||
93 | { | ||
94 | struct fscache_object *pobj, *obj, *minobj = NULL; | ||
95 | struct rb_node *p; | ||
96 | unsigned long pos; | ||
97 | |||
98 | if (*_pos >= (unsigned long) ERR_PTR(-ENOENT)) | ||
99 | return NULL; | ||
100 | pos = *_pos; | ||
101 | |||
102 | /* banners (can't represent line 0 by pos 0 as that would involve | ||
103 | * returning a NULL pointer) */ | ||
104 | if (pos == 0) | ||
105 | return (struct fscache_object *) ++(*_pos); | ||
106 | if (pos < 3) | ||
107 | return (struct fscache_object *)pos; | ||
108 | |||
109 | pobj = (struct fscache_object *)pos; | ||
110 | p = fscache_object_list.rb_node; | ||
111 | while (p) { | ||
112 | obj = rb_entry(p, struct fscache_object, objlist_link); | ||
113 | if (pobj < obj) { | ||
114 | if (!minobj || minobj > obj) | ||
115 | minobj = obj; | ||
116 | p = p->rb_left; | ||
117 | } else if (pobj > obj) { | ||
118 | p = p->rb_right; | ||
119 | } else { | ||
120 | minobj = obj; | ||
121 | break; | ||
122 | } | ||
123 | obj = NULL; | ||
124 | } | ||
125 | |||
126 | if (!minobj) | ||
127 | *_pos = (unsigned long) ERR_PTR(-ENOENT); | ||
128 | else if (minobj != obj) | ||
129 | *_pos = (unsigned long) minobj; | ||
130 | return minobj; | ||
131 | } | ||
132 | |||
133 | /* | ||
134 | * set up the iterator to start reading from the first line | ||
135 | */ | ||
136 | static void *fscache_objlist_start(struct seq_file *m, loff_t *_pos) | ||
137 | __acquires(&fscache_object_list_lock) | ||
138 | { | ||
139 | read_lock(&fscache_object_list_lock); | ||
140 | return fscache_objlist_lookup(_pos); | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * move to the next line | ||
145 | */ | ||
146 | static void *fscache_objlist_next(struct seq_file *m, void *v, loff_t *_pos) | ||
147 | { | ||
148 | (*_pos)++; | ||
149 | return fscache_objlist_lookup(_pos); | ||
150 | } | ||
151 | |||
152 | /* | ||
153 | * clean up after reading | ||
154 | */ | ||
155 | static void fscache_objlist_stop(struct seq_file *m, void *v) | ||
156 | __releases(&fscache_object_list_lock) | ||
157 | { | ||
158 | read_unlock(&fscache_object_list_lock); | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * display an object | ||
163 | */ | ||
164 | static int fscache_objlist_show(struct seq_file *m, void *v) | ||
165 | { | ||
166 | struct fscache_objlist_data *data = m->private; | ||
167 | struct fscache_object *obj = v; | ||
168 | unsigned long config = data->config; | ||
169 | uint16_t keylen, auxlen; | ||
170 | char _type[3], *type; | ||
171 | bool no_cookie; | ||
172 | u8 *buf = data->buf, *p; | ||
173 | |||
174 | if ((unsigned long) v == 1) { | ||
175 | seq_puts(m, "OBJECT PARENT STAT CHLDN OPS OOP IPR EX READS" | ||
176 | " EM EV F S" | ||
177 | " | NETFS_COOKIE_DEF TY FL NETFS_DATA"); | ||
178 | if (config & (FSCACHE_OBJLIST_CONFIG_KEY | | ||
179 | FSCACHE_OBJLIST_CONFIG_AUX)) | ||
180 | seq_puts(m, " "); | ||
181 | if (config & FSCACHE_OBJLIST_CONFIG_KEY) | ||
182 | seq_puts(m, "OBJECT_KEY"); | ||
183 | if ((config & (FSCACHE_OBJLIST_CONFIG_KEY | | ||
184 | FSCACHE_OBJLIST_CONFIG_AUX)) == | ||
185 | (FSCACHE_OBJLIST_CONFIG_KEY | FSCACHE_OBJLIST_CONFIG_AUX)) | ||
186 | seq_puts(m, ", "); | ||
187 | if (config & FSCACHE_OBJLIST_CONFIG_AUX) | ||
188 | seq_puts(m, "AUX_DATA"); | ||
189 | seq_puts(m, "\n"); | ||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | if ((unsigned long) v == 2) { | ||
194 | seq_puts(m, "======== ======== ==== ===== === === === == =====" | ||
195 | " == == = =" | ||
196 | " | ================ == == ================"); | ||
197 | if (config & (FSCACHE_OBJLIST_CONFIG_KEY | | ||
198 | FSCACHE_OBJLIST_CONFIG_AUX)) | ||
199 | seq_puts(m, " ================"); | ||
200 | seq_puts(m, "\n"); | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | /* filter out any unwanted objects */ | ||
205 | #define FILTER(criterion, _yes, _no) \ | ||
206 | do { \ | ||
207 | unsigned long yes = FSCACHE_OBJLIST_CONFIG_##_yes; \ | ||
208 | unsigned long no = FSCACHE_OBJLIST_CONFIG_##_no; \ | ||
209 | if (criterion) { \ | ||
210 | if (!(config & yes)) \ | ||
211 | return 0; \ | ||
212 | } else { \ | ||
213 | if (!(config & no)) \ | ||
214 | return 0; \ | ||
215 | } \ | ||
216 | } while(0) | ||
217 | |||
218 | if (~config) { | ||
219 | FILTER(obj->cookie, | ||
220 | COOKIE, NOCOOKIE); | ||
221 | FILTER(obj->state != FSCACHE_OBJECT_ACTIVE || | ||
222 | obj->n_ops != 0 || | ||
223 | obj->n_obj_ops != 0 || | ||
224 | obj->flags || | ||
225 | !list_empty(&obj->dependents), | ||
226 | BUSY, IDLE); | ||
227 | FILTER(test_bit(FSCACHE_OBJECT_PENDING_WRITE, &obj->flags), | ||
228 | PENDWR, NOPENDWR); | ||
229 | FILTER(atomic_read(&obj->n_reads), | ||
230 | READS, NOREADS); | ||
231 | FILTER(obj->events & obj->event_mask, | ||
232 | EVENTS, NOEVENTS); | ||
233 | FILTER(obj->work.flags & ~(1UL << SLOW_WORK_VERY_SLOW), | ||
234 | WORK, NOWORK); | ||
235 | } | ||
236 | |||
237 | seq_printf(m, | ||
238 | "%8x %8x %s %5u %3u %3u %3u %2u %5u %2lx %2lx %1lx %1lx | ", | ||
239 | obj->debug_id, | ||
240 | obj->parent ? obj->parent->debug_id : -1, | ||
241 | fscache_object_states_short[obj->state], | ||
242 | obj->n_children, | ||
243 | obj->n_ops, | ||
244 | obj->n_obj_ops, | ||
245 | obj->n_in_progress, | ||
246 | obj->n_exclusive, | ||
247 | atomic_read(&obj->n_reads), | ||
248 | obj->event_mask & FSCACHE_OBJECT_EVENTS_MASK, | ||
249 | obj->events, | ||
250 | obj->flags, | ||
251 | obj->work.flags); | ||
252 | |||
253 | no_cookie = true; | ||
254 | keylen = auxlen = 0; | ||
255 | if (obj->cookie) { | ||
256 | spin_lock(&obj->lock); | ||
257 | if (obj->cookie) { | ||
258 | switch (obj->cookie->def->type) { | ||
259 | case 0: | ||
260 | type = "IX"; | ||
261 | break; | ||
262 | case 1: | ||
263 | type = "DT"; | ||
264 | break; | ||
265 | default: | ||
266 | sprintf(_type, "%02u", | ||
267 | obj->cookie->def->type); | ||
268 | type = _type; | ||
269 | break; | ||
270 | } | ||
271 | |||
272 | seq_printf(m, "%-16s %s %2lx %16p", | ||
273 | obj->cookie->def->name, | ||
274 | type, | ||
275 | obj->cookie->flags, | ||
276 | obj->cookie->netfs_data); | ||
277 | |||
278 | if (obj->cookie->def->get_key && | ||
279 | config & FSCACHE_OBJLIST_CONFIG_KEY) | ||
280 | keylen = obj->cookie->def->get_key( | ||
281 | obj->cookie->netfs_data, | ||
282 | buf, 400); | ||
283 | |||
284 | if (obj->cookie->def->get_aux && | ||
285 | config & FSCACHE_OBJLIST_CONFIG_AUX) | ||
286 | auxlen = obj->cookie->def->get_aux( | ||
287 | obj->cookie->netfs_data, | ||
288 | buf + keylen, 512 - keylen); | ||
289 | |||
290 | no_cookie = false; | ||
291 | } | ||
292 | spin_unlock(&obj->lock); | ||
293 | |||
294 | if (!no_cookie && (keylen > 0 || auxlen > 0)) { | ||
295 | seq_printf(m, " "); | ||
296 | for (p = buf; keylen > 0; keylen--) | ||
297 | seq_printf(m, "%02x", *p++); | ||
298 | if (auxlen > 0) { | ||
299 | if (config & FSCACHE_OBJLIST_CONFIG_KEY) | ||
300 | seq_printf(m, ", "); | ||
301 | for (; auxlen > 0; auxlen--) | ||
302 | seq_printf(m, "%02x", *p++); | ||
303 | } | ||
304 | } | ||
305 | } | ||
306 | |||
307 | if (no_cookie) | ||
308 | seq_printf(m, "<no_cookie>\n"); | ||
309 | else | ||
310 | seq_printf(m, "\n"); | ||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | static const struct seq_operations fscache_objlist_ops = { | ||
315 | .start = fscache_objlist_start, | ||
316 | .stop = fscache_objlist_stop, | ||
317 | .next = fscache_objlist_next, | ||
318 | .show = fscache_objlist_show, | ||
319 | }; | ||
320 | |||
321 | /* | ||
322 | * get the configuration for filtering the list | ||
323 | */ | ||
324 | static void fscache_objlist_config(struct fscache_objlist_data *data) | ||
325 | { | ||
326 | #ifdef CONFIG_KEYS | ||
327 | struct user_key_payload *confkey; | ||
328 | unsigned long config; | ||
329 | struct key *key; | ||
330 | const char *buf; | ||
331 | int len; | ||
332 | |||
333 | key = request_key(&key_type_user, "fscache:objlist", NULL); | ||
334 | if (IS_ERR(key)) | ||
335 | goto no_config; | ||
336 | |||
337 | config = 0; | ||
338 | rcu_read_lock(); | ||
339 | |||
340 | confkey = key->payload.data; | ||
341 | buf = confkey->data; | ||
342 | |||
343 | for (len = confkey->datalen - 1; len >= 0; len--) { | ||
344 | switch (buf[len]) { | ||
345 | case 'K': config |= FSCACHE_OBJLIST_CONFIG_KEY; break; | ||
346 | case 'A': config |= FSCACHE_OBJLIST_CONFIG_AUX; break; | ||
347 | case 'C': config |= FSCACHE_OBJLIST_CONFIG_COOKIE; break; | ||
348 | case 'c': config |= FSCACHE_OBJLIST_CONFIG_NOCOOKIE; break; | ||
349 | case 'B': config |= FSCACHE_OBJLIST_CONFIG_BUSY; break; | ||
350 | case 'b': config |= FSCACHE_OBJLIST_CONFIG_IDLE; break; | ||
351 | case 'W': config |= FSCACHE_OBJLIST_CONFIG_PENDWR; break; | ||
352 | case 'w': config |= FSCACHE_OBJLIST_CONFIG_NOPENDWR; break; | ||
353 | case 'R': config |= FSCACHE_OBJLIST_CONFIG_READS; break; | ||
354 | case 'r': config |= FSCACHE_OBJLIST_CONFIG_NOREADS; break; | ||
355 | case 'S': config |= FSCACHE_OBJLIST_CONFIG_WORK; break; | ||
356 | case 's': config |= FSCACHE_OBJLIST_CONFIG_NOWORK; break; | ||
357 | } | ||
358 | } | ||
359 | |||
360 | rcu_read_unlock(); | ||
361 | key_put(key); | ||
362 | |||
363 | if (!(config & (FSCACHE_OBJLIST_CONFIG_COOKIE | FSCACHE_OBJLIST_CONFIG_NOCOOKIE))) | ||
364 | config |= FSCACHE_OBJLIST_CONFIG_COOKIE | FSCACHE_OBJLIST_CONFIG_NOCOOKIE; | ||
365 | if (!(config & (FSCACHE_OBJLIST_CONFIG_BUSY | FSCACHE_OBJLIST_CONFIG_IDLE))) | ||
366 | config |= FSCACHE_OBJLIST_CONFIG_BUSY | FSCACHE_OBJLIST_CONFIG_IDLE; | ||
367 | if (!(config & (FSCACHE_OBJLIST_CONFIG_PENDWR | FSCACHE_OBJLIST_CONFIG_NOPENDWR))) | ||
368 | config |= FSCACHE_OBJLIST_CONFIG_PENDWR | FSCACHE_OBJLIST_CONFIG_NOPENDWR; | ||
369 | if (!(config & (FSCACHE_OBJLIST_CONFIG_READS | FSCACHE_OBJLIST_CONFIG_NOREADS))) | ||
370 | config |= FSCACHE_OBJLIST_CONFIG_READS | FSCACHE_OBJLIST_CONFIG_NOREADS; | ||
371 | if (!(config & (FSCACHE_OBJLIST_CONFIG_EVENTS | FSCACHE_OBJLIST_CONFIG_NOEVENTS))) | ||
372 | config |= FSCACHE_OBJLIST_CONFIG_EVENTS | FSCACHE_OBJLIST_CONFIG_NOEVENTS; | ||
373 | if (!(config & (FSCACHE_OBJLIST_CONFIG_WORK | FSCACHE_OBJLIST_CONFIG_NOWORK))) | ||
374 | config |= FSCACHE_OBJLIST_CONFIG_WORK | FSCACHE_OBJLIST_CONFIG_NOWORK; | ||
375 | |||
376 | data->config = config; | ||
377 | return; | ||
378 | |||
379 | no_config: | ||
380 | #endif | ||
381 | data->config = ULONG_MAX; | ||
382 | } | ||
383 | |||
384 | /* | ||
385 | * open "/proc/fs/fscache/objects" to provide a list of active objects | ||
386 | * - can be configured by a user-defined key added to the caller's keyrings | ||
387 | */ | ||
388 | static int fscache_objlist_open(struct inode *inode, struct file *file) | ||
389 | { | ||
390 | struct fscache_objlist_data *data; | ||
391 | struct seq_file *m; | ||
392 | int ret; | ||
393 | |||
394 | ret = seq_open(file, &fscache_objlist_ops); | ||
395 | if (ret < 0) | ||
396 | return ret; | ||
397 | |||
398 | m = file->private_data; | ||
399 | |||
400 | /* buffer for key extraction */ | ||
401 | data = kmalloc(sizeof(struct fscache_objlist_data), GFP_KERNEL); | ||
402 | if (!data) { | ||
403 | seq_release(inode, file); | ||
404 | return -ENOMEM; | ||
405 | } | ||
406 | |||
407 | /* get the configuration key */ | ||
408 | fscache_objlist_config(data); | ||
409 | |||
410 | m->private = data; | ||
411 | return 0; | ||
412 | } | ||
413 | |||
414 | /* | ||
415 | * clean up on close | ||
416 | */ | ||
417 | static int fscache_objlist_release(struct inode *inode, struct file *file) | ||
418 | { | ||
419 | struct seq_file *m = file->private_data; | ||
420 | |||
421 | kfree(m->private); | ||
422 | m->private = NULL; | ||
423 | return seq_release(inode, file); | ||
424 | } | ||
425 | |||
426 | const struct file_operations fscache_objlist_fops = { | ||
427 | .owner = THIS_MODULE, | ||
428 | .open = fscache_objlist_open, | ||
429 | .read = seq_read, | ||
430 | .llseek = seq_lseek, | ||
431 | .release = fscache_objlist_release, | ||
432 | }; | ||
diff --git a/fs/fscache/object.c b/fs/fscache/object.c index 392a41b1b79d..e513ac599c8e 100644 --- a/fs/fscache/object.c +++ b/fs/fscache/object.c | |||
@@ -14,9 +14,10 @@ | |||
14 | 14 | ||
15 | #define FSCACHE_DEBUG_LEVEL COOKIE | 15 | #define FSCACHE_DEBUG_LEVEL COOKIE |
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
17 | #include <linux/seq_file.h> | ||
17 | #include "internal.h" | 18 | #include "internal.h" |
18 | 19 | ||
19 | const char *fscache_object_states[] = { | 20 | const char *fscache_object_states[FSCACHE_OBJECT__NSTATES] = { |
20 | [FSCACHE_OBJECT_INIT] = "OBJECT_INIT", | 21 | [FSCACHE_OBJECT_INIT] = "OBJECT_INIT", |
21 | [FSCACHE_OBJECT_LOOKING_UP] = "OBJECT_LOOKING_UP", | 22 | [FSCACHE_OBJECT_LOOKING_UP] = "OBJECT_LOOKING_UP", |
22 | [FSCACHE_OBJECT_CREATING] = "OBJECT_CREATING", | 23 | [FSCACHE_OBJECT_CREATING] = "OBJECT_CREATING", |
@@ -33,9 +34,28 @@ const char *fscache_object_states[] = { | |||
33 | }; | 34 | }; |
34 | EXPORT_SYMBOL(fscache_object_states); | 35 | EXPORT_SYMBOL(fscache_object_states); |
35 | 36 | ||
37 | const char fscache_object_states_short[FSCACHE_OBJECT__NSTATES][5] = { | ||
38 | [FSCACHE_OBJECT_INIT] = "INIT", | ||
39 | [FSCACHE_OBJECT_LOOKING_UP] = "LOOK", | ||
40 | [FSCACHE_OBJECT_CREATING] = "CRTN", | ||
41 | [FSCACHE_OBJECT_AVAILABLE] = "AVBL", | ||
42 | [FSCACHE_OBJECT_ACTIVE] = "ACTV", | ||
43 | [FSCACHE_OBJECT_UPDATING] = "UPDT", | ||
44 | [FSCACHE_OBJECT_DYING] = "DYNG", | ||
45 | [FSCACHE_OBJECT_LC_DYING] = "LCDY", | ||
46 | [FSCACHE_OBJECT_ABORT_INIT] = "ABTI", | ||
47 | [FSCACHE_OBJECT_RELEASING] = "RELS", | ||
48 | [FSCACHE_OBJECT_RECYCLING] = "RCYC", | ||
49 | [FSCACHE_OBJECT_WITHDRAWING] = "WTHD", | ||
50 | [FSCACHE_OBJECT_DEAD] = "DEAD", | ||
51 | }; | ||
52 | |||
36 | static void fscache_object_slow_work_put_ref(struct slow_work *); | 53 | static void fscache_object_slow_work_put_ref(struct slow_work *); |
37 | static int fscache_object_slow_work_get_ref(struct slow_work *); | 54 | static int fscache_object_slow_work_get_ref(struct slow_work *); |
38 | static void fscache_object_slow_work_execute(struct slow_work *); | 55 | static void fscache_object_slow_work_execute(struct slow_work *); |
56 | #ifdef CONFIG_SLOW_WORK_PROC | ||
57 | static void fscache_object_slow_work_desc(struct slow_work *, struct seq_file *); | ||
58 | #endif | ||
39 | static void fscache_initialise_object(struct fscache_object *); | 59 | static void fscache_initialise_object(struct fscache_object *); |
40 | static void fscache_lookup_object(struct fscache_object *); | 60 | static void fscache_lookup_object(struct fscache_object *); |
41 | static void fscache_object_available(struct fscache_object *); | 61 | static void fscache_object_available(struct fscache_object *); |
@@ -45,9 +65,13 @@ static void fscache_enqueue_dependents(struct fscache_object *); | |||
45 | static void fscache_dequeue_object(struct fscache_object *); | 65 | static void fscache_dequeue_object(struct fscache_object *); |
46 | 66 | ||
47 | const struct slow_work_ops fscache_object_slow_work_ops = { | 67 | const struct slow_work_ops fscache_object_slow_work_ops = { |
68 | .owner = THIS_MODULE, | ||
48 | .get_ref = fscache_object_slow_work_get_ref, | 69 | .get_ref = fscache_object_slow_work_get_ref, |
49 | .put_ref = fscache_object_slow_work_put_ref, | 70 | .put_ref = fscache_object_slow_work_put_ref, |
50 | .execute = fscache_object_slow_work_execute, | 71 | .execute = fscache_object_slow_work_execute, |
72 | #ifdef CONFIG_SLOW_WORK_PROC | ||
73 | .desc = fscache_object_slow_work_desc, | ||
74 | #endif | ||
51 | }; | 75 | }; |
52 | EXPORT_SYMBOL(fscache_object_slow_work_ops); | 76 | EXPORT_SYMBOL(fscache_object_slow_work_ops); |
53 | 77 | ||
@@ -81,6 +105,7 @@ static inline void fscache_done_parent_op(struct fscache_object *object) | |||
81 | static void fscache_object_state_machine(struct fscache_object *object) | 105 | static void fscache_object_state_machine(struct fscache_object *object) |
82 | { | 106 | { |
83 | enum fscache_object_state new_state; | 107 | enum fscache_object_state new_state; |
108 | struct fscache_cookie *cookie; | ||
84 | 109 | ||
85 | ASSERT(object != NULL); | 110 | ASSERT(object != NULL); |
86 | 111 | ||
@@ -120,20 +145,31 @@ static void fscache_object_state_machine(struct fscache_object *object) | |||
120 | case FSCACHE_OBJECT_UPDATING: | 145 | case FSCACHE_OBJECT_UPDATING: |
121 | clear_bit(FSCACHE_OBJECT_EV_UPDATE, &object->events); | 146 | clear_bit(FSCACHE_OBJECT_EV_UPDATE, &object->events); |
122 | fscache_stat(&fscache_n_updates_run); | 147 | fscache_stat(&fscache_n_updates_run); |
148 | fscache_stat(&fscache_n_cop_update_object); | ||
123 | object->cache->ops->update_object(object); | 149 | object->cache->ops->update_object(object); |
150 | fscache_stat_d(&fscache_n_cop_update_object); | ||
124 | goto active_transit; | 151 | goto active_transit; |
125 | 152 | ||
126 | /* handle an object dying during lookup or creation */ | 153 | /* handle an object dying during lookup or creation */ |
127 | case FSCACHE_OBJECT_LC_DYING: | 154 | case FSCACHE_OBJECT_LC_DYING: |
128 | object->event_mask &= ~(1 << FSCACHE_OBJECT_EV_UPDATE); | 155 | object->event_mask &= ~(1 << FSCACHE_OBJECT_EV_UPDATE); |
156 | fscache_stat(&fscache_n_cop_lookup_complete); | ||
129 | object->cache->ops->lookup_complete(object); | 157 | object->cache->ops->lookup_complete(object); |
158 | fscache_stat_d(&fscache_n_cop_lookup_complete); | ||
130 | 159 | ||
131 | spin_lock(&object->lock); | 160 | spin_lock(&object->lock); |
132 | object->state = FSCACHE_OBJECT_DYING; | 161 | object->state = FSCACHE_OBJECT_DYING; |
133 | if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, | 162 | cookie = object->cookie; |
134 | &object->cookie->flags)) | 163 | if (cookie) { |
135 | wake_up_bit(&object->cookie->flags, | 164 | if (test_and_clear_bit(FSCACHE_COOKIE_LOOKING_UP, |
136 | FSCACHE_COOKIE_CREATING); | 165 | &cookie->flags)) |
166 | wake_up_bit(&cookie->flags, | ||
167 | FSCACHE_COOKIE_LOOKING_UP); | ||
168 | if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, | ||
169 | &cookie->flags)) | ||
170 | wake_up_bit(&cookie->flags, | ||
171 | FSCACHE_COOKIE_CREATING); | ||
172 | } | ||
137 | spin_unlock(&object->lock); | 173 | spin_unlock(&object->lock); |
138 | 174 | ||
139 | fscache_done_parent_op(object); | 175 | fscache_done_parent_op(object); |
@@ -165,6 +201,7 @@ static void fscache_object_state_machine(struct fscache_object *object) | |||
165 | } | 201 | } |
166 | spin_unlock(&object->lock); | 202 | spin_unlock(&object->lock); |
167 | fscache_enqueue_dependents(object); | 203 | fscache_enqueue_dependents(object); |
204 | fscache_start_operations(object); | ||
168 | goto terminal_transit; | 205 | goto terminal_transit; |
169 | 206 | ||
170 | /* handle an abort during initialisation */ | 207 | /* handle an abort during initialisation */ |
@@ -316,14 +353,29 @@ static void fscache_object_slow_work_execute(struct slow_work *work) | |||
316 | 353 | ||
317 | _enter("{OBJ%x}", object->debug_id); | 354 | _enter("{OBJ%x}", object->debug_id); |
318 | 355 | ||
319 | clear_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events); | ||
320 | |||
321 | start = jiffies; | 356 | start = jiffies; |
322 | fscache_object_state_machine(object); | 357 | fscache_object_state_machine(object); |
323 | fscache_hist(fscache_objs_histogram, start); | 358 | fscache_hist(fscache_objs_histogram, start); |
324 | if (object->events & object->event_mask) | 359 | if (object->events & object->event_mask) |
325 | fscache_enqueue_object(object); | 360 | fscache_enqueue_object(object); |
361 | clear_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events); | ||
362 | } | ||
363 | |||
364 | /* | ||
365 | * describe an object for slow-work debugging | ||
366 | */ | ||
367 | #ifdef CONFIG_SLOW_WORK_PROC | ||
368 | static void fscache_object_slow_work_desc(struct slow_work *work, | ||
369 | struct seq_file *m) | ||
370 | { | ||
371 | struct fscache_object *object = | ||
372 | container_of(work, struct fscache_object, work); | ||
373 | |||
374 | seq_printf(m, "FSC: OBJ%x: %s", | ||
375 | object->debug_id, | ||
376 | fscache_object_states_short[object->state]); | ||
326 | } | 377 | } |
378 | #endif | ||
327 | 379 | ||
328 | /* | 380 | /* |
329 | * initialise an object | 381 | * initialise an object |
@@ -376,7 +428,9 @@ static void fscache_initialise_object(struct fscache_object *object) | |||
376 | * binding on to us, so we need to make sure we don't | 428 | * binding on to us, so we need to make sure we don't |
377 | * add ourself to the list multiple times */ | 429 | * add ourself to the list multiple times */ |
378 | if (list_empty(&object->dep_link)) { | 430 | if (list_empty(&object->dep_link)) { |
431 | fscache_stat(&fscache_n_cop_grab_object); | ||
379 | object->cache->ops->grab_object(object); | 432 | object->cache->ops->grab_object(object); |
433 | fscache_stat_d(&fscache_n_cop_grab_object); | ||
380 | list_add(&object->dep_link, | 434 | list_add(&object->dep_link, |
381 | &parent->dependents); | 435 | &parent->dependents); |
382 | 436 | ||
@@ -414,6 +468,7 @@ static void fscache_lookup_object(struct fscache_object *object) | |||
414 | { | 468 | { |
415 | struct fscache_cookie *cookie = object->cookie; | 469 | struct fscache_cookie *cookie = object->cookie; |
416 | struct fscache_object *parent; | 470 | struct fscache_object *parent; |
471 | int ret; | ||
417 | 472 | ||
418 | _enter(""); | 473 | _enter(""); |
419 | 474 | ||
@@ -438,11 +493,20 @@ static void fscache_lookup_object(struct fscache_object *object) | |||
438 | object->cache->tag->name); | 493 | object->cache->tag->name); |
439 | 494 | ||
440 | fscache_stat(&fscache_n_object_lookups); | 495 | fscache_stat(&fscache_n_object_lookups); |
441 | object->cache->ops->lookup_object(object); | 496 | fscache_stat(&fscache_n_cop_lookup_object); |
497 | ret = object->cache->ops->lookup_object(object); | ||
498 | fscache_stat_d(&fscache_n_cop_lookup_object); | ||
442 | 499 | ||
443 | if (test_bit(FSCACHE_OBJECT_EV_ERROR, &object->events)) | 500 | if (test_bit(FSCACHE_OBJECT_EV_ERROR, &object->events)) |
444 | set_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags); | 501 | set_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags); |
445 | 502 | ||
503 | if (ret == -ETIMEDOUT) { | ||
504 | /* probably stuck behind another object, so move this one to | ||
505 | * the back of the queue */ | ||
506 | fscache_stat(&fscache_n_object_lookups_timed_out); | ||
507 | set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events); | ||
508 | } | ||
509 | |||
446 | _leave(""); | 510 | _leave(""); |
447 | } | 511 | } |
448 | 512 | ||
@@ -546,7 +610,8 @@ static void fscache_object_available(struct fscache_object *object) | |||
546 | 610 | ||
547 | spin_lock(&object->lock); | 611 | spin_lock(&object->lock); |
548 | 612 | ||
549 | if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, &object->cookie->flags)) | 613 | if (object->cookie && |
614 | test_and_clear_bit(FSCACHE_COOKIE_CREATING, &object->cookie->flags)) | ||
550 | wake_up_bit(&object->cookie->flags, FSCACHE_COOKIE_CREATING); | 615 | wake_up_bit(&object->cookie->flags, FSCACHE_COOKIE_CREATING); |
551 | 616 | ||
552 | fscache_done_parent_op(object); | 617 | fscache_done_parent_op(object); |
@@ -562,7 +627,9 @@ static void fscache_object_available(struct fscache_object *object) | |||
562 | } | 627 | } |
563 | spin_unlock(&object->lock); | 628 | spin_unlock(&object->lock); |
564 | 629 | ||
630 | fscache_stat(&fscache_n_cop_lookup_complete); | ||
565 | object->cache->ops->lookup_complete(object); | 631 | object->cache->ops->lookup_complete(object); |
632 | fscache_stat_d(&fscache_n_cop_lookup_complete); | ||
566 | fscache_enqueue_dependents(object); | 633 | fscache_enqueue_dependents(object); |
567 | 634 | ||
568 | fscache_hist(fscache_obj_instantiate_histogram, object->lookup_jif); | 635 | fscache_hist(fscache_obj_instantiate_histogram, object->lookup_jif); |
@@ -581,11 +648,16 @@ static void fscache_drop_object(struct fscache_object *object) | |||
581 | 648 | ||
582 | _enter("{OBJ%x,%d}", object->debug_id, object->n_children); | 649 | _enter("{OBJ%x,%d}", object->debug_id, object->n_children); |
583 | 650 | ||
651 | ASSERTCMP(object->cookie, ==, NULL); | ||
652 | ASSERT(hlist_unhashed(&object->cookie_link)); | ||
653 | |||
584 | spin_lock(&cache->object_list_lock); | 654 | spin_lock(&cache->object_list_lock); |
585 | list_del_init(&object->cache_link); | 655 | list_del_init(&object->cache_link); |
586 | spin_unlock(&cache->object_list_lock); | 656 | spin_unlock(&cache->object_list_lock); |
587 | 657 | ||
658 | fscache_stat(&fscache_n_cop_drop_object); | ||
588 | cache->ops->drop_object(object); | 659 | cache->ops->drop_object(object); |
660 | fscache_stat_d(&fscache_n_cop_drop_object); | ||
589 | 661 | ||
590 | if (parent) { | 662 | if (parent) { |
591 | _debug("release parent OBJ%x {%d}", | 663 | _debug("release parent OBJ%x {%d}", |
@@ -600,7 +672,9 @@ static void fscache_drop_object(struct fscache_object *object) | |||
600 | } | 672 | } |
601 | 673 | ||
602 | /* this just shifts the object release to the slow work processor */ | 674 | /* this just shifts the object release to the slow work processor */ |
675 | fscache_stat(&fscache_n_cop_put_object); | ||
603 | object->cache->ops->put_object(object); | 676 | object->cache->ops->put_object(object); |
677 | fscache_stat_d(&fscache_n_cop_put_object); | ||
604 | 678 | ||
605 | _leave(""); | 679 | _leave(""); |
606 | } | 680 | } |
@@ -690,8 +764,12 @@ static int fscache_object_slow_work_get_ref(struct slow_work *work) | |||
690 | { | 764 | { |
691 | struct fscache_object *object = | 765 | struct fscache_object *object = |
692 | container_of(work, struct fscache_object, work); | 766 | container_of(work, struct fscache_object, work); |
767 | int ret; | ||
693 | 768 | ||
694 | return object->cache->ops->grab_object(object) ? 0 : -EAGAIN; | 769 | fscache_stat(&fscache_n_cop_grab_object); |
770 | ret = object->cache->ops->grab_object(object) ? 0 : -EAGAIN; | ||
771 | fscache_stat_d(&fscache_n_cop_grab_object); | ||
772 | return ret; | ||
695 | } | 773 | } |
696 | 774 | ||
697 | /* | 775 | /* |
@@ -702,7 +780,9 @@ static void fscache_object_slow_work_put_ref(struct slow_work *work) | |||
702 | struct fscache_object *object = | 780 | struct fscache_object *object = |
703 | container_of(work, struct fscache_object, work); | 781 | container_of(work, struct fscache_object, work); |
704 | 782 | ||
705 | return object->cache->ops->put_object(object); | 783 | fscache_stat(&fscache_n_cop_put_object); |
784 | object->cache->ops->put_object(object); | ||
785 | fscache_stat_d(&fscache_n_cop_put_object); | ||
706 | } | 786 | } |
707 | 787 | ||
708 | /* | 788 | /* |
@@ -739,7 +819,9 @@ static void fscache_enqueue_dependents(struct fscache_object *object) | |||
739 | 819 | ||
740 | /* sort onto appropriate lists */ | 820 | /* sort onto appropriate lists */ |
741 | fscache_enqueue_object(dep); | 821 | fscache_enqueue_object(dep); |
822 | fscache_stat(&fscache_n_cop_put_object); | ||
742 | dep->cache->ops->put_object(dep); | 823 | dep->cache->ops->put_object(dep); |
824 | fscache_stat_d(&fscache_n_cop_put_object); | ||
743 | 825 | ||
744 | if (!list_empty(&object->dependents)) | 826 | if (!list_empty(&object->dependents)) |
745 | cond_resched_lock(&object->lock); | 827 | cond_resched_lock(&object->lock); |
diff --git a/fs/fscache/operation.c b/fs/fscache/operation.c index e7f8d53b8b6b..313e79a14266 100644 --- a/fs/fscache/operation.c +++ b/fs/fscache/operation.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #define FSCACHE_DEBUG_LEVEL OPERATION | 14 | #define FSCACHE_DEBUG_LEVEL OPERATION |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/seq_file.h> | ||
16 | #include "internal.h" | 17 | #include "internal.h" |
17 | 18 | ||
18 | atomic_t fscache_op_debug_id; | 19 | atomic_t fscache_op_debug_id; |
@@ -31,32 +32,33 @@ void fscache_enqueue_operation(struct fscache_operation *op) | |||
31 | _enter("{OBJ%x OP%x,%u}", | 32 | _enter("{OBJ%x OP%x,%u}", |
32 | op->object->debug_id, op->debug_id, atomic_read(&op->usage)); | 33 | op->object->debug_id, op->debug_id, atomic_read(&op->usage)); |
33 | 34 | ||
35 | fscache_set_op_state(op, "EnQ"); | ||
36 | |||
37 | ASSERT(list_empty(&op->pend_link)); | ||
34 | ASSERT(op->processor != NULL); | 38 | ASSERT(op->processor != NULL); |
35 | ASSERTCMP(op->object->state, >=, FSCACHE_OBJECT_AVAILABLE); | 39 | ASSERTCMP(op->object->state, >=, FSCACHE_OBJECT_AVAILABLE); |
36 | ASSERTCMP(atomic_read(&op->usage), >, 0); | 40 | ASSERTCMP(atomic_read(&op->usage), >, 0); |
37 | 41 | ||
38 | if (list_empty(&op->pend_link)) { | 42 | fscache_stat(&fscache_n_op_enqueue); |
39 | switch (op->flags & FSCACHE_OP_TYPE) { | 43 | switch (op->flags & FSCACHE_OP_TYPE) { |
40 | case FSCACHE_OP_FAST: | 44 | case FSCACHE_OP_FAST: |
41 | _debug("queue fast"); | 45 | _debug("queue fast"); |
42 | atomic_inc(&op->usage); | 46 | atomic_inc(&op->usage); |
43 | if (!schedule_work(&op->fast_work)) | 47 | if (!schedule_work(&op->fast_work)) |
44 | fscache_put_operation(op); | 48 | fscache_put_operation(op); |
45 | break; | 49 | break; |
46 | case FSCACHE_OP_SLOW: | 50 | case FSCACHE_OP_SLOW: |
47 | _debug("queue slow"); | 51 | _debug("queue slow"); |
48 | slow_work_enqueue(&op->slow_work); | 52 | slow_work_enqueue(&op->slow_work); |
49 | break; | 53 | break; |
50 | case FSCACHE_OP_MYTHREAD: | 54 | case FSCACHE_OP_MYTHREAD: |
51 | _debug("queue for caller's attention"); | 55 | _debug("queue for caller's attention"); |
52 | break; | 56 | break; |
53 | default: | 57 | default: |
54 | printk(KERN_ERR "FS-Cache: Unexpected op type %lx", | 58 | printk(KERN_ERR "FS-Cache: Unexpected op type %lx", |
55 | op->flags); | 59 | op->flags); |
56 | BUG(); | 60 | BUG(); |
57 | break; | 61 | break; |
58 | } | ||
59 | fscache_stat(&fscache_n_op_enqueue); | ||
60 | } | 62 | } |
61 | } | 63 | } |
62 | EXPORT_SYMBOL(fscache_enqueue_operation); | 64 | EXPORT_SYMBOL(fscache_enqueue_operation); |
@@ -67,6 +69,8 @@ EXPORT_SYMBOL(fscache_enqueue_operation); | |||
67 | static void fscache_run_op(struct fscache_object *object, | 69 | static void fscache_run_op(struct fscache_object *object, |
68 | struct fscache_operation *op) | 70 | struct fscache_operation *op) |
69 | { | 71 | { |
72 | fscache_set_op_state(op, "Run"); | ||
73 | |||
70 | object->n_in_progress++; | 74 | object->n_in_progress++; |
71 | if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags)) | 75 | if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags)) |
72 | wake_up_bit(&op->flags, FSCACHE_OP_WAITING); | 76 | wake_up_bit(&op->flags, FSCACHE_OP_WAITING); |
@@ -87,9 +91,12 @@ int fscache_submit_exclusive_op(struct fscache_object *object, | |||
87 | 91 | ||
88 | _enter("{OBJ%x OP%x},", object->debug_id, op->debug_id); | 92 | _enter("{OBJ%x OP%x},", object->debug_id, op->debug_id); |
89 | 93 | ||
94 | fscache_set_op_state(op, "SubmitX"); | ||
95 | |||
90 | spin_lock(&object->lock); | 96 | spin_lock(&object->lock); |
91 | ASSERTCMP(object->n_ops, >=, object->n_in_progress); | 97 | ASSERTCMP(object->n_ops, >=, object->n_in_progress); |
92 | ASSERTCMP(object->n_ops, >=, object->n_exclusive); | 98 | ASSERTCMP(object->n_ops, >=, object->n_exclusive); |
99 | ASSERT(list_empty(&op->pend_link)); | ||
93 | 100 | ||
94 | ret = -ENOBUFS; | 101 | ret = -ENOBUFS; |
95 | if (fscache_object_is_active(object)) { | 102 | if (fscache_object_is_active(object)) { |
@@ -190,9 +197,12 @@ int fscache_submit_op(struct fscache_object *object, | |||
190 | 197 | ||
191 | ASSERTCMP(atomic_read(&op->usage), >, 0); | 198 | ASSERTCMP(atomic_read(&op->usage), >, 0); |
192 | 199 | ||
200 | fscache_set_op_state(op, "Submit"); | ||
201 | |||
193 | spin_lock(&object->lock); | 202 | spin_lock(&object->lock); |
194 | ASSERTCMP(object->n_ops, >=, object->n_in_progress); | 203 | ASSERTCMP(object->n_ops, >=, object->n_in_progress); |
195 | ASSERTCMP(object->n_ops, >=, object->n_exclusive); | 204 | ASSERTCMP(object->n_ops, >=, object->n_exclusive); |
205 | ASSERT(list_empty(&op->pend_link)); | ||
196 | 206 | ||
197 | ostate = object->state; | 207 | ostate = object->state; |
198 | smp_rmb(); | 208 | smp_rmb(); |
@@ -222,6 +232,11 @@ int fscache_submit_op(struct fscache_object *object, | |||
222 | list_add_tail(&op->pend_link, &object->pending_ops); | 232 | list_add_tail(&op->pend_link, &object->pending_ops); |
223 | fscache_stat(&fscache_n_op_pend); | 233 | fscache_stat(&fscache_n_op_pend); |
224 | ret = 0; | 234 | ret = 0; |
235 | } else if (object->state == FSCACHE_OBJECT_DYING || | ||
236 | object->state == FSCACHE_OBJECT_LC_DYING || | ||
237 | object->state == FSCACHE_OBJECT_WITHDRAWING) { | ||
238 | fscache_stat(&fscache_n_op_rejected); | ||
239 | ret = -ENOBUFS; | ||
225 | } else if (!test_bit(FSCACHE_IOERROR, &object->cache->flags)) { | 240 | } else if (!test_bit(FSCACHE_IOERROR, &object->cache->flags)) { |
226 | fscache_report_unexpected_submission(object, op, ostate); | 241 | fscache_report_unexpected_submission(object, op, ostate); |
227 | ASSERT(!fscache_object_is_active(object)); | 242 | ASSERT(!fscache_object_is_active(object)); |
@@ -264,12 +279,7 @@ void fscache_start_operations(struct fscache_object *object) | |||
264 | stop = true; | 279 | stop = true; |
265 | } | 280 | } |
266 | list_del_init(&op->pend_link); | 281 | list_del_init(&op->pend_link); |
267 | object->n_in_progress++; | 282 | fscache_run_op(object, op); |
268 | |||
269 | if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags)) | ||
270 | wake_up_bit(&op->flags, FSCACHE_OP_WAITING); | ||
271 | if (op->processor) | ||
272 | fscache_enqueue_operation(op); | ||
273 | 283 | ||
274 | /* the pending queue was holding a ref on the object */ | 284 | /* the pending queue was holding a ref on the object */ |
275 | fscache_put_operation(op); | 285 | fscache_put_operation(op); |
@@ -282,6 +292,36 @@ void fscache_start_operations(struct fscache_object *object) | |||
282 | } | 292 | } |
283 | 293 | ||
284 | /* | 294 | /* |
295 | * cancel an operation that's pending on an object | ||
296 | */ | ||
297 | int fscache_cancel_op(struct fscache_operation *op) | ||
298 | { | ||
299 | struct fscache_object *object = op->object; | ||
300 | int ret; | ||
301 | |||
302 | _enter("OBJ%x OP%x}", op->object->debug_id, op->debug_id); | ||
303 | |||
304 | spin_lock(&object->lock); | ||
305 | |||
306 | ret = -EBUSY; | ||
307 | if (!list_empty(&op->pend_link)) { | ||
308 | fscache_stat(&fscache_n_op_cancelled); | ||
309 | list_del_init(&op->pend_link); | ||
310 | object->n_ops--; | ||
311 | if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags)) | ||
312 | object->n_exclusive--; | ||
313 | if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags)) | ||
314 | wake_up_bit(&op->flags, FSCACHE_OP_WAITING); | ||
315 | fscache_put_operation(op); | ||
316 | ret = 0; | ||
317 | } | ||
318 | |||
319 | spin_unlock(&object->lock); | ||
320 | _leave(" = %d", ret); | ||
321 | return ret; | ||
322 | } | ||
323 | |||
324 | /* | ||
285 | * release an operation | 325 | * release an operation |
286 | * - queues pending ops if this is the last in-progress op | 326 | * - queues pending ops if this is the last in-progress op |
287 | */ | 327 | */ |
@@ -298,6 +338,8 @@ void fscache_put_operation(struct fscache_operation *op) | |||
298 | if (!atomic_dec_and_test(&op->usage)) | 338 | if (!atomic_dec_and_test(&op->usage)) |
299 | return; | 339 | return; |
300 | 340 | ||
341 | fscache_set_op_state(op, "Put"); | ||
342 | |||
301 | _debug("PUT OP"); | 343 | _debug("PUT OP"); |
302 | if (test_and_set_bit(FSCACHE_OP_DEAD, &op->flags)) | 344 | if (test_and_set_bit(FSCACHE_OP_DEAD, &op->flags)) |
303 | BUG(); | 345 | BUG(); |
@@ -311,6 +353,9 @@ void fscache_put_operation(struct fscache_operation *op) | |||
311 | 353 | ||
312 | object = op->object; | 354 | object = op->object; |
313 | 355 | ||
356 | if (test_bit(FSCACHE_OP_DEC_READ_CNT, &op->flags)) | ||
357 | atomic_dec(&object->n_reads); | ||
358 | |||
314 | /* now... we may get called with the object spinlock held, so we | 359 | /* now... we may get called with the object spinlock held, so we |
315 | * complete the cleanup here only if we can immediately acquire the | 360 | * complete the cleanup here only if we can immediately acquire the |
316 | * lock, and defer it otherwise */ | 361 | * lock, and defer it otherwise */ |
@@ -452,8 +497,27 @@ static void fscache_op_execute(struct slow_work *work) | |||
452 | _leave(""); | 497 | _leave(""); |
453 | } | 498 | } |
454 | 499 | ||
500 | /* | ||
501 | * describe an operation for slow-work debugging | ||
502 | */ | ||
503 | #ifdef CONFIG_SLOW_WORK_PROC | ||
504 | static void fscache_op_desc(struct slow_work *work, struct seq_file *m) | ||
505 | { | ||
506 | struct fscache_operation *op = | ||
507 | container_of(work, struct fscache_operation, slow_work); | ||
508 | |||
509 | seq_printf(m, "FSC: OBJ%x OP%x: %s/%s fl=%lx", | ||
510 | op->object->debug_id, op->debug_id, | ||
511 | op->name, op->state, op->flags); | ||
512 | } | ||
513 | #endif | ||
514 | |||
455 | const struct slow_work_ops fscache_op_slow_work_ops = { | 515 | const struct slow_work_ops fscache_op_slow_work_ops = { |
516 | .owner = THIS_MODULE, | ||
456 | .get_ref = fscache_op_get_ref, | 517 | .get_ref = fscache_op_get_ref, |
457 | .put_ref = fscache_op_put_ref, | 518 | .put_ref = fscache_op_put_ref, |
458 | .execute = fscache_op_execute, | 519 | .execute = fscache_op_execute, |
520 | #ifdef CONFIG_SLOW_WORK_PROC | ||
521 | .desc = fscache_op_desc, | ||
522 | #endif | ||
459 | }; | 523 | }; |
diff --git a/fs/fscache/page.c b/fs/fscache/page.c index 2568e0eb644f..c598ea4c4e7d 100644 --- a/fs/fscache/page.c +++ b/fs/fscache/page.c | |||
@@ -43,18 +43,102 @@ void __fscache_wait_on_page_write(struct fscache_cookie *cookie, struct page *pa | |||
43 | EXPORT_SYMBOL(__fscache_wait_on_page_write); | 43 | EXPORT_SYMBOL(__fscache_wait_on_page_write); |
44 | 44 | ||
45 | /* | 45 | /* |
46 | * note that a page has finished being written to the cache | 46 | * decide whether a page can be released, possibly by cancelling a store to it |
47 | * - we're allowed to sleep if __GFP_WAIT is flagged | ||
47 | */ | 48 | */ |
48 | static void fscache_end_page_write(struct fscache_cookie *cookie, struct page *page) | 49 | bool __fscache_maybe_release_page(struct fscache_cookie *cookie, |
50 | struct page *page, | ||
51 | gfp_t gfp) | ||
49 | { | 52 | { |
50 | struct page *xpage; | 53 | struct page *xpage; |
54 | void *val; | ||
55 | |||
56 | _enter("%p,%p,%x", cookie, page, gfp); | ||
57 | |||
58 | rcu_read_lock(); | ||
59 | val = radix_tree_lookup(&cookie->stores, page->index); | ||
60 | if (!val) { | ||
61 | rcu_read_unlock(); | ||
62 | fscache_stat(&fscache_n_store_vmscan_not_storing); | ||
63 | __fscache_uncache_page(cookie, page); | ||
64 | return true; | ||
65 | } | ||
66 | |||
67 | /* see if the page is actually undergoing storage - if so we can't get | ||
68 | * rid of it till the cache has finished with it */ | ||
69 | if (radix_tree_tag_get(&cookie->stores, page->index, | ||
70 | FSCACHE_COOKIE_STORING_TAG)) { | ||
71 | rcu_read_unlock(); | ||
72 | goto page_busy; | ||
73 | } | ||
74 | |||
75 | /* the page is pending storage, so we attempt to cancel the store and | ||
76 | * discard the store request so that the page can be reclaimed */ | ||
77 | spin_lock(&cookie->stores_lock); | ||
78 | rcu_read_unlock(); | ||
79 | |||
80 | if (radix_tree_tag_get(&cookie->stores, page->index, | ||
81 | FSCACHE_COOKIE_STORING_TAG)) { | ||
82 | /* the page started to undergo storage whilst we were looking, | ||
83 | * so now we can only wait or return */ | ||
84 | spin_unlock(&cookie->stores_lock); | ||
85 | goto page_busy; | ||
86 | } | ||
51 | 87 | ||
52 | spin_lock(&cookie->lock); | ||
53 | xpage = radix_tree_delete(&cookie->stores, page->index); | 88 | xpage = radix_tree_delete(&cookie->stores, page->index); |
54 | spin_unlock(&cookie->lock); | 89 | spin_unlock(&cookie->stores_lock); |
55 | ASSERT(xpage != NULL); | 90 | |
91 | if (xpage) { | ||
92 | fscache_stat(&fscache_n_store_vmscan_cancelled); | ||
93 | fscache_stat(&fscache_n_store_radix_deletes); | ||
94 | ASSERTCMP(xpage, ==, page); | ||
95 | } else { | ||
96 | fscache_stat(&fscache_n_store_vmscan_gone); | ||
97 | } | ||
56 | 98 | ||
57 | wake_up_bit(&cookie->flags, 0); | 99 | wake_up_bit(&cookie->flags, 0); |
100 | if (xpage) | ||
101 | page_cache_release(xpage); | ||
102 | __fscache_uncache_page(cookie, page); | ||
103 | return true; | ||
104 | |||
105 | page_busy: | ||
106 | /* we might want to wait here, but that could deadlock the allocator as | ||
107 | * the slow-work threads writing to the cache may all end up sleeping | ||
108 | * on memory allocation */ | ||
109 | fscache_stat(&fscache_n_store_vmscan_busy); | ||
110 | return false; | ||
111 | } | ||
112 | EXPORT_SYMBOL(__fscache_maybe_release_page); | ||
113 | |||
114 | /* | ||
115 | * note that a page has finished being written to the cache | ||
116 | */ | ||
117 | static void fscache_end_page_write(struct fscache_object *object, | ||
118 | struct page *page) | ||
119 | { | ||
120 | struct fscache_cookie *cookie; | ||
121 | struct page *xpage = NULL; | ||
122 | |||
123 | spin_lock(&object->lock); | ||
124 | cookie = object->cookie; | ||
125 | if (cookie) { | ||
126 | /* delete the page from the tree if it is now no longer | ||
127 | * pending */ | ||
128 | spin_lock(&cookie->stores_lock); | ||
129 | radix_tree_tag_clear(&cookie->stores, page->index, | ||
130 | FSCACHE_COOKIE_STORING_TAG); | ||
131 | if (!radix_tree_tag_get(&cookie->stores, page->index, | ||
132 | FSCACHE_COOKIE_PENDING_TAG)) { | ||
133 | fscache_stat(&fscache_n_store_radix_deletes); | ||
134 | xpage = radix_tree_delete(&cookie->stores, page->index); | ||
135 | } | ||
136 | spin_unlock(&cookie->stores_lock); | ||
137 | wake_up_bit(&cookie->flags, 0); | ||
138 | } | ||
139 | spin_unlock(&object->lock); | ||
140 | if (xpage) | ||
141 | page_cache_release(xpage); | ||
58 | } | 142 | } |
59 | 143 | ||
60 | /* | 144 | /* |
@@ -63,14 +147,21 @@ static void fscache_end_page_write(struct fscache_cookie *cookie, struct page *p | |||
63 | static void fscache_attr_changed_op(struct fscache_operation *op) | 147 | static void fscache_attr_changed_op(struct fscache_operation *op) |
64 | { | 148 | { |
65 | struct fscache_object *object = op->object; | 149 | struct fscache_object *object = op->object; |
150 | int ret; | ||
66 | 151 | ||
67 | _enter("{OBJ%x OP%x}", object->debug_id, op->debug_id); | 152 | _enter("{OBJ%x OP%x}", object->debug_id, op->debug_id); |
68 | 153 | ||
69 | fscache_stat(&fscache_n_attr_changed_calls); | 154 | fscache_stat(&fscache_n_attr_changed_calls); |
70 | 155 | ||
71 | if (fscache_object_is_active(object) && | 156 | if (fscache_object_is_active(object)) { |
72 | object->cache->ops->attr_changed(object) < 0) | 157 | fscache_set_op_state(op, "CallFS"); |
73 | fscache_abort_object(object); | 158 | fscache_stat(&fscache_n_cop_attr_changed); |
159 | ret = object->cache->ops->attr_changed(object); | ||
160 | fscache_stat_d(&fscache_n_cop_attr_changed); | ||
161 | fscache_set_op_state(op, "Done"); | ||
162 | if (ret < 0) | ||
163 | fscache_abort_object(object); | ||
164 | } | ||
74 | 165 | ||
75 | _leave(""); | 166 | _leave(""); |
76 | } | 167 | } |
@@ -99,6 +190,7 @@ int __fscache_attr_changed(struct fscache_cookie *cookie) | |||
99 | fscache_operation_init(op, NULL); | 190 | fscache_operation_init(op, NULL); |
100 | fscache_operation_init_slow(op, fscache_attr_changed_op); | 191 | fscache_operation_init_slow(op, fscache_attr_changed_op); |
101 | op->flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_EXCLUSIVE); | 192 | op->flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_EXCLUSIVE); |
193 | fscache_set_op_name(op, "Attr"); | ||
102 | 194 | ||
103 | spin_lock(&cookie->lock); | 195 | spin_lock(&cookie->lock); |
104 | 196 | ||
@@ -184,6 +276,7 @@ static struct fscache_retrieval *fscache_alloc_retrieval( | |||
184 | op->start_time = jiffies; | 276 | op->start_time = jiffies; |
185 | INIT_WORK(&op->op.fast_work, fscache_retrieval_work); | 277 | INIT_WORK(&op->op.fast_work, fscache_retrieval_work); |
186 | INIT_LIST_HEAD(&op->to_do); | 278 | INIT_LIST_HEAD(&op->to_do); |
279 | fscache_set_op_name(&op->op, "Retr"); | ||
187 | return op; | 280 | return op; |
188 | } | 281 | } |
189 | 282 | ||
@@ -221,6 +314,43 @@ static int fscache_wait_for_deferred_lookup(struct fscache_cookie *cookie) | |||
221 | } | 314 | } |
222 | 315 | ||
223 | /* | 316 | /* |
317 | * wait for an object to become active (or dead) | ||
318 | */ | ||
319 | static int fscache_wait_for_retrieval_activation(struct fscache_object *object, | ||
320 | struct fscache_retrieval *op, | ||
321 | atomic_t *stat_op_waits, | ||
322 | atomic_t *stat_object_dead) | ||
323 | { | ||
324 | int ret; | ||
325 | |||
326 | if (!test_bit(FSCACHE_OP_WAITING, &op->op.flags)) | ||
327 | goto check_if_dead; | ||
328 | |||
329 | _debug(">>> WT"); | ||
330 | fscache_stat(stat_op_waits); | ||
331 | if (wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING, | ||
332 | fscache_wait_bit_interruptible, | ||
333 | TASK_INTERRUPTIBLE) < 0) { | ||
334 | ret = fscache_cancel_op(&op->op); | ||
335 | if (ret == 0) | ||
336 | return -ERESTARTSYS; | ||
337 | |||
338 | /* it's been removed from the pending queue by another party, | ||
339 | * so we should get to run shortly */ | ||
340 | wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING, | ||
341 | fscache_wait_bit, TASK_UNINTERRUPTIBLE); | ||
342 | } | ||
343 | _debug("<<< GO"); | ||
344 | |||
345 | check_if_dead: | ||
346 | if (unlikely(fscache_object_is_dead(object))) { | ||
347 | fscache_stat(stat_object_dead); | ||
348 | return -ENOBUFS; | ||
349 | } | ||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | /* | ||
224 | * read a page from the cache or allocate a block in which to store it | 354 | * read a page from the cache or allocate a block in which to store it |
225 | * - we return: | 355 | * - we return: |
226 | * -ENOMEM - out of memory, nothing done | 356 | * -ENOMEM - out of memory, nothing done |
@@ -257,6 +387,7 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie, | |||
257 | _leave(" = -ENOMEM"); | 387 | _leave(" = -ENOMEM"); |
258 | return -ENOMEM; | 388 | return -ENOMEM; |
259 | } | 389 | } |
390 | fscache_set_op_name(&op->op, "RetrRA1"); | ||
260 | 391 | ||
261 | spin_lock(&cookie->lock); | 392 | spin_lock(&cookie->lock); |
262 | 393 | ||
@@ -267,6 +398,9 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie, | |||
267 | 398 | ||
268 | ASSERTCMP(object->state, >, FSCACHE_OBJECT_LOOKING_UP); | 399 | ASSERTCMP(object->state, >, FSCACHE_OBJECT_LOOKING_UP); |
269 | 400 | ||
401 | atomic_inc(&object->n_reads); | ||
402 | set_bit(FSCACHE_OP_DEC_READ_CNT, &op->op.flags); | ||
403 | |||
270 | if (fscache_submit_op(object, &op->op) < 0) | 404 | if (fscache_submit_op(object, &op->op) < 0) |
271 | goto nobufs_unlock; | 405 | goto nobufs_unlock; |
272 | spin_unlock(&cookie->lock); | 406 | spin_unlock(&cookie->lock); |
@@ -279,23 +413,27 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie, | |||
279 | 413 | ||
280 | /* we wait for the operation to become active, and then process it | 414 | /* we wait for the operation to become active, and then process it |
281 | * *here*, in this thread, and not in the thread pool */ | 415 | * *here*, in this thread, and not in the thread pool */ |
282 | if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) { | 416 | ret = fscache_wait_for_retrieval_activation( |
283 | _debug(">>> WT"); | 417 | object, op, |
284 | fscache_stat(&fscache_n_retrieval_op_waits); | 418 | __fscache_stat(&fscache_n_retrieval_op_waits), |
285 | wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING, | 419 | __fscache_stat(&fscache_n_retrievals_object_dead)); |
286 | fscache_wait_bit, TASK_UNINTERRUPTIBLE); | 420 | if (ret < 0) |
287 | _debug("<<< GO"); | 421 | goto error; |
288 | } | ||
289 | 422 | ||
290 | /* ask the cache to honour the operation */ | 423 | /* ask the cache to honour the operation */ |
291 | if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) { | 424 | if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) { |
425 | fscache_stat(&fscache_n_cop_allocate_page); | ||
292 | ret = object->cache->ops->allocate_page(op, page, gfp); | 426 | ret = object->cache->ops->allocate_page(op, page, gfp); |
427 | fscache_stat_d(&fscache_n_cop_allocate_page); | ||
293 | if (ret == 0) | 428 | if (ret == 0) |
294 | ret = -ENODATA; | 429 | ret = -ENODATA; |
295 | } else { | 430 | } else { |
431 | fscache_stat(&fscache_n_cop_read_or_alloc_page); | ||
296 | ret = object->cache->ops->read_or_alloc_page(op, page, gfp); | 432 | ret = object->cache->ops->read_or_alloc_page(op, page, gfp); |
433 | fscache_stat_d(&fscache_n_cop_read_or_alloc_page); | ||
297 | } | 434 | } |
298 | 435 | ||
436 | error: | ||
299 | if (ret == -ENOMEM) | 437 | if (ret == -ENOMEM) |
300 | fscache_stat(&fscache_n_retrievals_nomem); | 438 | fscache_stat(&fscache_n_retrievals_nomem); |
301 | else if (ret == -ERESTARTSYS) | 439 | else if (ret == -ERESTARTSYS) |
@@ -347,7 +485,6 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie, | |||
347 | void *context, | 485 | void *context, |
348 | gfp_t gfp) | 486 | gfp_t gfp) |
349 | { | 487 | { |
350 | fscache_pages_retrieval_func_t func; | ||
351 | struct fscache_retrieval *op; | 488 | struct fscache_retrieval *op; |
352 | struct fscache_object *object; | 489 | struct fscache_object *object; |
353 | int ret; | 490 | int ret; |
@@ -369,6 +506,7 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie, | |||
369 | op = fscache_alloc_retrieval(mapping, end_io_func, context); | 506 | op = fscache_alloc_retrieval(mapping, end_io_func, context); |
370 | if (!op) | 507 | if (!op) |
371 | return -ENOMEM; | 508 | return -ENOMEM; |
509 | fscache_set_op_name(&op->op, "RetrRAN"); | ||
372 | 510 | ||
373 | spin_lock(&cookie->lock); | 511 | spin_lock(&cookie->lock); |
374 | 512 | ||
@@ -377,6 +515,9 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie, | |||
377 | object = hlist_entry(cookie->backing_objects.first, | 515 | object = hlist_entry(cookie->backing_objects.first, |
378 | struct fscache_object, cookie_link); | 516 | struct fscache_object, cookie_link); |
379 | 517 | ||
518 | atomic_inc(&object->n_reads); | ||
519 | set_bit(FSCACHE_OP_DEC_READ_CNT, &op->op.flags); | ||
520 | |||
380 | if (fscache_submit_op(object, &op->op) < 0) | 521 | if (fscache_submit_op(object, &op->op) < 0) |
381 | goto nobufs_unlock; | 522 | goto nobufs_unlock; |
382 | spin_unlock(&cookie->lock); | 523 | spin_unlock(&cookie->lock); |
@@ -389,21 +530,27 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie, | |||
389 | 530 | ||
390 | /* we wait for the operation to become active, and then process it | 531 | /* we wait for the operation to become active, and then process it |
391 | * *here*, in this thread, and not in the thread pool */ | 532 | * *here*, in this thread, and not in the thread pool */ |
392 | if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) { | 533 | ret = fscache_wait_for_retrieval_activation( |
393 | _debug(">>> WT"); | 534 | object, op, |
394 | fscache_stat(&fscache_n_retrieval_op_waits); | 535 | __fscache_stat(&fscache_n_retrieval_op_waits), |
395 | wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING, | 536 | __fscache_stat(&fscache_n_retrievals_object_dead)); |
396 | fscache_wait_bit, TASK_UNINTERRUPTIBLE); | 537 | if (ret < 0) |
397 | _debug("<<< GO"); | 538 | goto error; |
398 | } | ||
399 | 539 | ||
400 | /* ask the cache to honour the operation */ | 540 | /* ask the cache to honour the operation */ |
401 | if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) | 541 | if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) { |
402 | func = object->cache->ops->allocate_pages; | 542 | fscache_stat(&fscache_n_cop_allocate_pages); |
403 | else | 543 | ret = object->cache->ops->allocate_pages( |
404 | func = object->cache->ops->read_or_alloc_pages; | 544 | op, pages, nr_pages, gfp); |
405 | ret = func(op, pages, nr_pages, gfp); | 545 | fscache_stat_d(&fscache_n_cop_allocate_pages); |
546 | } else { | ||
547 | fscache_stat(&fscache_n_cop_read_or_alloc_pages); | ||
548 | ret = object->cache->ops->read_or_alloc_pages( | ||
549 | op, pages, nr_pages, gfp); | ||
550 | fscache_stat_d(&fscache_n_cop_read_or_alloc_pages); | ||
551 | } | ||
406 | 552 | ||
553 | error: | ||
407 | if (ret == -ENOMEM) | 554 | if (ret == -ENOMEM) |
408 | fscache_stat(&fscache_n_retrievals_nomem); | 555 | fscache_stat(&fscache_n_retrievals_nomem); |
409 | else if (ret == -ERESTARTSYS) | 556 | else if (ret == -ERESTARTSYS) |
@@ -461,6 +608,7 @@ int __fscache_alloc_page(struct fscache_cookie *cookie, | |||
461 | op = fscache_alloc_retrieval(page->mapping, NULL, NULL); | 608 | op = fscache_alloc_retrieval(page->mapping, NULL, NULL); |
462 | if (!op) | 609 | if (!op) |
463 | return -ENOMEM; | 610 | return -ENOMEM; |
611 | fscache_set_op_name(&op->op, "RetrAL1"); | ||
464 | 612 | ||
465 | spin_lock(&cookie->lock); | 613 | spin_lock(&cookie->lock); |
466 | 614 | ||
@@ -475,18 +623,22 @@ int __fscache_alloc_page(struct fscache_cookie *cookie, | |||
475 | 623 | ||
476 | fscache_stat(&fscache_n_alloc_ops); | 624 | fscache_stat(&fscache_n_alloc_ops); |
477 | 625 | ||
478 | if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) { | 626 | ret = fscache_wait_for_retrieval_activation( |
479 | _debug(">>> WT"); | 627 | object, op, |
480 | fscache_stat(&fscache_n_alloc_op_waits); | 628 | __fscache_stat(&fscache_n_alloc_op_waits), |
481 | wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING, | 629 | __fscache_stat(&fscache_n_allocs_object_dead)); |
482 | fscache_wait_bit, TASK_UNINTERRUPTIBLE); | 630 | if (ret < 0) |
483 | _debug("<<< GO"); | 631 | goto error; |
484 | } | ||
485 | 632 | ||
486 | /* ask the cache to honour the operation */ | 633 | /* ask the cache to honour the operation */ |
634 | fscache_stat(&fscache_n_cop_allocate_page); | ||
487 | ret = object->cache->ops->allocate_page(op, page, gfp); | 635 | ret = object->cache->ops->allocate_page(op, page, gfp); |
636 | fscache_stat_d(&fscache_n_cop_allocate_page); | ||
488 | 637 | ||
489 | if (ret < 0) | 638 | error: |
639 | if (ret == -ERESTARTSYS) | ||
640 | fscache_stat(&fscache_n_allocs_intr); | ||
641 | else if (ret < 0) | ||
490 | fscache_stat(&fscache_n_allocs_nobufs); | 642 | fscache_stat(&fscache_n_allocs_nobufs); |
491 | else | 643 | else |
492 | fscache_stat(&fscache_n_allocs_ok); | 644 | fscache_stat(&fscache_n_allocs_ok); |
@@ -521,7 +673,7 @@ static void fscache_write_op(struct fscache_operation *_op) | |||
521 | struct fscache_storage *op = | 673 | struct fscache_storage *op = |
522 | container_of(_op, struct fscache_storage, op); | 674 | container_of(_op, struct fscache_storage, op); |
523 | struct fscache_object *object = op->op.object; | 675 | struct fscache_object *object = op->op.object; |
524 | struct fscache_cookie *cookie = object->cookie; | 676 | struct fscache_cookie *cookie; |
525 | struct page *page; | 677 | struct page *page; |
526 | unsigned n; | 678 | unsigned n; |
527 | void *results[1]; | 679 | void *results[1]; |
@@ -529,16 +681,19 @@ static void fscache_write_op(struct fscache_operation *_op) | |||
529 | 681 | ||
530 | _enter("{OP%x,%d}", op->op.debug_id, atomic_read(&op->op.usage)); | 682 | _enter("{OP%x,%d}", op->op.debug_id, atomic_read(&op->op.usage)); |
531 | 683 | ||
532 | spin_lock(&cookie->lock); | 684 | fscache_set_op_state(&op->op, "GetPage"); |
685 | |||
533 | spin_lock(&object->lock); | 686 | spin_lock(&object->lock); |
687 | cookie = object->cookie; | ||
534 | 688 | ||
535 | if (!fscache_object_is_active(object)) { | 689 | if (!fscache_object_is_active(object) || !cookie) { |
536 | spin_unlock(&object->lock); | 690 | spin_unlock(&object->lock); |
537 | spin_unlock(&cookie->lock); | ||
538 | _leave(""); | 691 | _leave(""); |
539 | return; | 692 | return; |
540 | } | 693 | } |
541 | 694 | ||
695 | spin_lock(&cookie->stores_lock); | ||
696 | |||
542 | fscache_stat(&fscache_n_store_calls); | 697 | fscache_stat(&fscache_n_store_calls); |
543 | 698 | ||
544 | /* find a page to store */ | 699 | /* find a page to store */ |
@@ -549,23 +704,35 @@ static void fscache_write_op(struct fscache_operation *_op) | |||
549 | goto superseded; | 704 | goto superseded; |
550 | page = results[0]; | 705 | page = results[0]; |
551 | _debug("gang %d [%lx]", n, page->index); | 706 | _debug("gang %d [%lx]", n, page->index); |
552 | if (page->index > op->store_limit) | 707 | if (page->index > op->store_limit) { |
708 | fscache_stat(&fscache_n_store_pages_over_limit); | ||
553 | goto superseded; | 709 | goto superseded; |
710 | } | ||
554 | 711 | ||
555 | radix_tree_tag_clear(&cookie->stores, page->index, | 712 | if (page) { |
556 | FSCACHE_COOKIE_PENDING_TAG); | 713 | radix_tree_tag_set(&cookie->stores, page->index, |
714 | FSCACHE_COOKIE_STORING_TAG); | ||
715 | radix_tree_tag_clear(&cookie->stores, page->index, | ||
716 | FSCACHE_COOKIE_PENDING_TAG); | ||
717 | } | ||
557 | 718 | ||
719 | spin_unlock(&cookie->stores_lock); | ||
558 | spin_unlock(&object->lock); | 720 | spin_unlock(&object->lock); |
559 | spin_unlock(&cookie->lock); | ||
560 | 721 | ||
561 | if (page) { | 722 | if (page) { |
723 | fscache_set_op_state(&op->op, "Store"); | ||
724 | fscache_stat(&fscache_n_store_pages); | ||
725 | fscache_stat(&fscache_n_cop_write_page); | ||
562 | ret = object->cache->ops->write_page(op, page); | 726 | ret = object->cache->ops->write_page(op, page); |
563 | fscache_end_page_write(cookie, page); | 727 | fscache_stat_d(&fscache_n_cop_write_page); |
564 | page_cache_release(page); | 728 | fscache_set_op_state(&op->op, "EndWrite"); |
565 | if (ret < 0) | 729 | fscache_end_page_write(object, page); |
730 | if (ret < 0) { | ||
731 | fscache_set_op_state(&op->op, "Abort"); | ||
566 | fscache_abort_object(object); | 732 | fscache_abort_object(object); |
567 | else | 733 | } else { |
568 | fscache_enqueue_operation(&op->op); | 734 | fscache_enqueue_operation(&op->op); |
735 | } | ||
569 | } | 736 | } |
570 | 737 | ||
571 | _leave(""); | 738 | _leave(""); |
@@ -575,9 +742,9 @@ superseded: | |||
575 | /* this writer is going away and there aren't any more things to | 742 | /* this writer is going away and there aren't any more things to |
576 | * write */ | 743 | * write */ |
577 | _debug("cease"); | 744 | _debug("cease"); |
745 | spin_unlock(&cookie->stores_lock); | ||
578 | clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags); | 746 | clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags); |
579 | spin_unlock(&object->lock); | 747 | spin_unlock(&object->lock); |
580 | spin_unlock(&cookie->lock); | ||
581 | _leave(""); | 748 | _leave(""); |
582 | } | 749 | } |
583 | 750 | ||
@@ -634,6 +801,7 @@ int __fscache_write_page(struct fscache_cookie *cookie, | |||
634 | fscache_operation_init(&op->op, fscache_release_write_op); | 801 | fscache_operation_init(&op->op, fscache_release_write_op); |
635 | fscache_operation_init_slow(&op->op, fscache_write_op); | 802 | fscache_operation_init_slow(&op->op, fscache_write_op); |
636 | op->op.flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_WAITING); | 803 | op->op.flags = FSCACHE_OP_SLOW | (1 << FSCACHE_OP_WAITING); |
804 | fscache_set_op_name(&op->op, "Write1"); | ||
637 | 805 | ||
638 | ret = radix_tree_preload(gfp & ~__GFP_HIGHMEM); | 806 | ret = radix_tree_preload(gfp & ~__GFP_HIGHMEM); |
639 | if (ret < 0) | 807 | if (ret < 0) |
@@ -652,6 +820,7 @@ int __fscache_write_page(struct fscache_cookie *cookie, | |||
652 | /* add the page to the pending-storage radix tree on the backing | 820 | /* add the page to the pending-storage radix tree on the backing |
653 | * object */ | 821 | * object */ |
654 | spin_lock(&object->lock); | 822 | spin_lock(&object->lock); |
823 | spin_lock(&cookie->stores_lock); | ||
655 | 824 | ||
656 | _debug("store limit %llx", (unsigned long long) object->store_limit); | 825 | _debug("store limit %llx", (unsigned long long) object->store_limit); |
657 | 826 | ||
@@ -672,6 +841,7 @@ int __fscache_write_page(struct fscache_cookie *cookie, | |||
672 | if (test_and_set_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags)) | 841 | if (test_and_set_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags)) |
673 | goto already_pending; | 842 | goto already_pending; |
674 | 843 | ||
844 | spin_unlock(&cookie->stores_lock); | ||
675 | spin_unlock(&object->lock); | 845 | spin_unlock(&object->lock); |
676 | 846 | ||
677 | op->op.debug_id = atomic_inc_return(&fscache_op_debug_id); | 847 | op->op.debug_id = atomic_inc_return(&fscache_op_debug_id); |
@@ -693,6 +863,7 @@ int __fscache_write_page(struct fscache_cookie *cookie, | |||
693 | already_queued: | 863 | already_queued: |
694 | fscache_stat(&fscache_n_stores_again); | 864 | fscache_stat(&fscache_n_stores_again); |
695 | already_pending: | 865 | already_pending: |
866 | spin_unlock(&cookie->stores_lock); | ||
696 | spin_unlock(&object->lock); | 867 | spin_unlock(&object->lock); |
697 | spin_unlock(&cookie->lock); | 868 | spin_unlock(&cookie->lock); |
698 | radix_tree_preload_end(); | 869 | radix_tree_preload_end(); |
@@ -702,7 +873,9 @@ already_pending: | |||
702 | return 0; | 873 | return 0; |
703 | 874 | ||
704 | submit_failed: | 875 | submit_failed: |
876 | spin_lock(&cookie->stores_lock); | ||
705 | radix_tree_delete(&cookie->stores, page->index); | 877 | radix_tree_delete(&cookie->stores, page->index); |
878 | spin_unlock(&cookie->stores_lock); | ||
706 | page_cache_release(page); | 879 | page_cache_release(page); |
707 | ret = -ENOBUFS; | 880 | ret = -ENOBUFS; |
708 | goto nobufs; | 881 | goto nobufs; |
@@ -763,7 +936,9 @@ void __fscache_uncache_page(struct fscache_cookie *cookie, struct page *page) | |||
763 | if (TestClearPageFsCache(page) && | 936 | if (TestClearPageFsCache(page) && |
764 | object->cache->ops->uncache_page) { | 937 | object->cache->ops->uncache_page) { |
765 | /* the cache backend releases the cookie lock */ | 938 | /* the cache backend releases the cookie lock */ |
939 | fscache_stat(&fscache_n_cop_uncache_page); | ||
766 | object->cache->ops->uncache_page(object, page); | 940 | object->cache->ops->uncache_page(object, page); |
941 | fscache_stat_d(&fscache_n_cop_uncache_page); | ||
767 | goto done; | 942 | goto done; |
768 | } | 943 | } |
769 | 944 | ||
diff --git a/fs/fscache/proc.c b/fs/fscache/proc.c index beeab44bc31a..1d9e4951a597 100644 --- a/fs/fscache/proc.c +++ b/fs/fscache/proc.c | |||
@@ -37,10 +37,20 @@ int __init fscache_proc_init(void) | |||
37 | goto error_histogram; | 37 | goto error_histogram; |
38 | #endif | 38 | #endif |
39 | 39 | ||
40 | #ifdef CONFIG_FSCACHE_OBJECT_LIST | ||
41 | if (!proc_create("fs/fscache/objects", S_IFREG | 0444, NULL, | ||
42 | &fscache_objlist_fops)) | ||
43 | goto error_objects; | ||
44 | #endif | ||
45 | |||
40 | _leave(" = 0"); | 46 | _leave(" = 0"); |
41 | return 0; | 47 | return 0; |
42 | 48 | ||
49 | #ifdef CONFIG_FSCACHE_OBJECT_LIST | ||
50 | error_objects: | ||
51 | #endif | ||
43 | #ifdef CONFIG_FSCACHE_HISTOGRAM | 52 | #ifdef CONFIG_FSCACHE_HISTOGRAM |
53 | remove_proc_entry("fs/fscache/histogram", NULL); | ||
44 | error_histogram: | 54 | error_histogram: |
45 | #endif | 55 | #endif |
46 | #ifdef CONFIG_FSCACHE_STATS | 56 | #ifdef CONFIG_FSCACHE_STATS |
@@ -58,6 +68,9 @@ error_dir: | |||
58 | */ | 68 | */ |
59 | void fscache_proc_cleanup(void) | 69 | void fscache_proc_cleanup(void) |
60 | { | 70 | { |
71 | #ifdef CONFIG_FSCACHE_OBJECT_LIST | ||
72 | remove_proc_entry("fs/fscache/objects", NULL); | ||
73 | #endif | ||
61 | #ifdef CONFIG_FSCACHE_HISTOGRAM | 74 | #ifdef CONFIG_FSCACHE_HISTOGRAM |
62 | remove_proc_entry("fs/fscache/histogram", NULL); | 75 | remove_proc_entry("fs/fscache/histogram", NULL); |
63 | #endif | 76 | #endif |
diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c index 65deb99e756b..46435f3aae68 100644 --- a/fs/fscache/stats.c +++ b/fs/fscache/stats.c | |||
@@ -25,6 +25,8 @@ atomic_t fscache_n_op_requeue; | |||
25 | atomic_t fscache_n_op_deferred_release; | 25 | atomic_t fscache_n_op_deferred_release; |
26 | atomic_t fscache_n_op_release; | 26 | atomic_t fscache_n_op_release; |
27 | atomic_t fscache_n_op_gc; | 27 | atomic_t fscache_n_op_gc; |
28 | atomic_t fscache_n_op_cancelled; | ||
29 | atomic_t fscache_n_op_rejected; | ||
28 | 30 | ||
29 | atomic_t fscache_n_attr_changed; | 31 | atomic_t fscache_n_attr_changed; |
30 | atomic_t fscache_n_attr_changed_ok; | 32 | atomic_t fscache_n_attr_changed_ok; |
@@ -36,6 +38,8 @@ atomic_t fscache_n_allocs; | |||
36 | atomic_t fscache_n_allocs_ok; | 38 | atomic_t fscache_n_allocs_ok; |
37 | atomic_t fscache_n_allocs_wait; | 39 | atomic_t fscache_n_allocs_wait; |
38 | atomic_t fscache_n_allocs_nobufs; | 40 | atomic_t fscache_n_allocs_nobufs; |
41 | atomic_t fscache_n_allocs_intr; | ||
42 | atomic_t fscache_n_allocs_object_dead; | ||
39 | atomic_t fscache_n_alloc_ops; | 43 | atomic_t fscache_n_alloc_ops; |
40 | atomic_t fscache_n_alloc_op_waits; | 44 | atomic_t fscache_n_alloc_op_waits; |
41 | 45 | ||
@@ -46,6 +50,7 @@ atomic_t fscache_n_retrievals_nodata; | |||
46 | atomic_t fscache_n_retrievals_nobufs; | 50 | atomic_t fscache_n_retrievals_nobufs; |
47 | atomic_t fscache_n_retrievals_intr; | 51 | atomic_t fscache_n_retrievals_intr; |
48 | atomic_t fscache_n_retrievals_nomem; | 52 | atomic_t fscache_n_retrievals_nomem; |
53 | atomic_t fscache_n_retrievals_object_dead; | ||
49 | atomic_t fscache_n_retrieval_ops; | 54 | atomic_t fscache_n_retrieval_ops; |
50 | atomic_t fscache_n_retrieval_op_waits; | 55 | atomic_t fscache_n_retrieval_op_waits; |
51 | 56 | ||
@@ -56,6 +61,14 @@ atomic_t fscache_n_stores_nobufs; | |||
56 | atomic_t fscache_n_stores_oom; | 61 | atomic_t fscache_n_stores_oom; |
57 | atomic_t fscache_n_store_ops; | 62 | atomic_t fscache_n_store_ops; |
58 | atomic_t fscache_n_store_calls; | 63 | atomic_t fscache_n_store_calls; |
64 | atomic_t fscache_n_store_pages; | ||
65 | atomic_t fscache_n_store_radix_deletes; | ||
66 | atomic_t fscache_n_store_pages_over_limit; | ||
67 | |||
68 | atomic_t fscache_n_store_vmscan_not_storing; | ||
69 | atomic_t fscache_n_store_vmscan_gone; | ||
70 | atomic_t fscache_n_store_vmscan_busy; | ||
71 | atomic_t fscache_n_store_vmscan_cancelled; | ||
59 | 72 | ||
60 | atomic_t fscache_n_marks; | 73 | atomic_t fscache_n_marks; |
61 | atomic_t fscache_n_uncaches; | 74 | atomic_t fscache_n_uncaches; |
@@ -74,6 +87,7 @@ atomic_t fscache_n_updates_run; | |||
74 | atomic_t fscache_n_relinquishes; | 87 | atomic_t fscache_n_relinquishes; |
75 | atomic_t fscache_n_relinquishes_null; | 88 | atomic_t fscache_n_relinquishes_null; |
76 | atomic_t fscache_n_relinquishes_waitcrt; | 89 | atomic_t fscache_n_relinquishes_waitcrt; |
90 | atomic_t fscache_n_relinquishes_retire; | ||
77 | 91 | ||
78 | atomic_t fscache_n_cookie_index; | 92 | atomic_t fscache_n_cookie_index; |
79 | atomic_t fscache_n_cookie_data; | 93 | atomic_t fscache_n_cookie_data; |
@@ -84,6 +98,7 @@ atomic_t fscache_n_object_no_alloc; | |||
84 | atomic_t fscache_n_object_lookups; | 98 | atomic_t fscache_n_object_lookups; |
85 | atomic_t fscache_n_object_lookups_negative; | 99 | atomic_t fscache_n_object_lookups_negative; |
86 | atomic_t fscache_n_object_lookups_positive; | 100 | atomic_t fscache_n_object_lookups_positive; |
101 | atomic_t fscache_n_object_lookups_timed_out; | ||
87 | atomic_t fscache_n_object_created; | 102 | atomic_t fscache_n_object_created; |
88 | atomic_t fscache_n_object_avail; | 103 | atomic_t fscache_n_object_avail; |
89 | atomic_t fscache_n_object_dead; | 104 | atomic_t fscache_n_object_dead; |
@@ -93,6 +108,23 @@ atomic_t fscache_n_checkaux_okay; | |||
93 | atomic_t fscache_n_checkaux_update; | 108 | atomic_t fscache_n_checkaux_update; |
94 | atomic_t fscache_n_checkaux_obsolete; | 109 | atomic_t fscache_n_checkaux_obsolete; |
95 | 110 | ||
111 | atomic_t fscache_n_cop_alloc_object; | ||
112 | atomic_t fscache_n_cop_lookup_object; | ||
113 | atomic_t fscache_n_cop_lookup_complete; | ||
114 | atomic_t fscache_n_cop_grab_object; | ||
115 | atomic_t fscache_n_cop_update_object; | ||
116 | atomic_t fscache_n_cop_drop_object; | ||
117 | atomic_t fscache_n_cop_put_object; | ||
118 | atomic_t fscache_n_cop_sync_cache; | ||
119 | atomic_t fscache_n_cop_attr_changed; | ||
120 | atomic_t fscache_n_cop_read_or_alloc_page; | ||
121 | atomic_t fscache_n_cop_read_or_alloc_pages; | ||
122 | atomic_t fscache_n_cop_allocate_page; | ||
123 | atomic_t fscache_n_cop_allocate_pages; | ||
124 | atomic_t fscache_n_cop_write_page; | ||
125 | atomic_t fscache_n_cop_uncache_page; | ||
126 | atomic_t fscache_n_cop_dissociate_pages; | ||
127 | |||
96 | /* | 128 | /* |
97 | * display the general statistics | 129 | * display the general statistics |
98 | */ | 130 | */ |
@@ -129,10 +161,11 @@ static int fscache_stats_show(struct seq_file *m, void *v) | |||
129 | atomic_read(&fscache_n_acquires_nobufs), | 161 | atomic_read(&fscache_n_acquires_nobufs), |
130 | atomic_read(&fscache_n_acquires_oom)); | 162 | atomic_read(&fscache_n_acquires_oom)); |
131 | 163 | ||
132 | seq_printf(m, "Lookups: n=%u neg=%u pos=%u crt=%u\n", | 164 | seq_printf(m, "Lookups: n=%u neg=%u pos=%u crt=%u tmo=%u\n", |
133 | atomic_read(&fscache_n_object_lookups), | 165 | atomic_read(&fscache_n_object_lookups), |
134 | atomic_read(&fscache_n_object_lookups_negative), | 166 | atomic_read(&fscache_n_object_lookups_negative), |
135 | atomic_read(&fscache_n_object_lookups_positive), | 167 | atomic_read(&fscache_n_object_lookups_positive), |
168 | atomic_read(&fscache_n_object_lookups_timed_out), | ||
136 | atomic_read(&fscache_n_object_created)); | 169 | atomic_read(&fscache_n_object_created)); |
137 | 170 | ||
138 | seq_printf(m, "Updates: n=%u nul=%u run=%u\n", | 171 | seq_printf(m, "Updates: n=%u nul=%u run=%u\n", |
@@ -140,10 +173,11 @@ static int fscache_stats_show(struct seq_file *m, void *v) | |||
140 | atomic_read(&fscache_n_updates_null), | 173 | atomic_read(&fscache_n_updates_null), |
141 | atomic_read(&fscache_n_updates_run)); | 174 | atomic_read(&fscache_n_updates_run)); |
142 | 175 | ||
143 | seq_printf(m, "Relinqs: n=%u nul=%u wcr=%u\n", | 176 | seq_printf(m, "Relinqs: n=%u nul=%u wcr=%u rtr=%u\n", |
144 | atomic_read(&fscache_n_relinquishes), | 177 | atomic_read(&fscache_n_relinquishes), |
145 | atomic_read(&fscache_n_relinquishes_null), | 178 | atomic_read(&fscache_n_relinquishes_null), |
146 | atomic_read(&fscache_n_relinquishes_waitcrt)); | 179 | atomic_read(&fscache_n_relinquishes_waitcrt), |
180 | atomic_read(&fscache_n_relinquishes_retire)); | ||
147 | 181 | ||
148 | seq_printf(m, "AttrChg: n=%u ok=%u nbf=%u oom=%u run=%u\n", | 182 | seq_printf(m, "AttrChg: n=%u ok=%u nbf=%u oom=%u run=%u\n", |
149 | atomic_read(&fscache_n_attr_changed), | 183 | atomic_read(&fscache_n_attr_changed), |
@@ -152,14 +186,16 @@ static int fscache_stats_show(struct seq_file *m, void *v) | |||
152 | atomic_read(&fscache_n_attr_changed_nomem), | 186 | atomic_read(&fscache_n_attr_changed_nomem), |
153 | atomic_read(&fscache_n_attr_changed_calls)); | 187 | atomic_read(&fscache_n_attr_changed_calls)); |
154 | 188 | ||
155 | seq_printf(m, "Allocs : n=%u ok=%u wt=%u nbf=%u\n", | 189 | seq_printf(m, "Allocs : n=%u ok=%u wt=%u nbf=%u int=%u\n", |
156 | atomic_read(&fscache_n_allocs), | 190 | atomic_read(&fscache_n_allocs), |
157 | atomic_read(&fscache_n_allocs_ok), | 191 | atomic_read(&fscache_n_allocs_ok), |
158 | atomic_read(&fscache_n_allocs_wait), | 192 | atomic_read(&fscache_n_allocs_wait), |
159 | atomic_read(&fscache_n_allocs_nobufs)); | 193 | atomic_read(&fscache_n_allocs_nobufs), |
160 | seq_printf(m, "Allocs : ops=%u owt=%u\n", | 194 | atomic_read(&fscache_n_allocs_intr)); |
195 | seq_printf(m, "Allocs : ops=%u owt=%u abt=%u\n", | ||
161 | atomic_read(&fscache_n_alloc_ops), | 196 | atomic_read(&fscache_n_alloc_ops), |
162 | atomic_read(&fscache_n_alloc_op_waits)); | 197 | atomic_read(&fscache_n_alloc_op_waits), |
198 | atomic_read(&fscache_n_allocs_object_dead)); | ||
163 | 199 | ||
164 | seq_printf(m, "Retrvls: n=%u ok=%u wt=%u nod=%u nbf=%u" | 200 | seq_printf(m, "Retrvls: n=%u ok=%u wt=%u nod=%u nbf=%u" |
165 | " int=%u oom=%u\n", | 201 | " int=%u oom=%u\n", |
@@ -170,9 +206,10 @@ static int fscache_stats_show(struct seq_file *m, void *v) | |||
170 | atomic_read(&fscache_n_retrievals_nobufs), | 206 | atomic_read(&fscache_n_retrievals_nobufs), |
171 | atomic_read(&fscache_n_retrievals_intr), | 207 | atomic_read(&fscache_n_retrievals_intr), |
172 | atomic_read(&fscache_n_retrievals_nomem)); | 208 | atomic_read(&fscache_n_retrievals_nomem)); |
173 | seq_printf(m, "Retrvls: ops=%u owt=%u\n", | 209 | seq_printf(m, "Retrvls: ops=%u owt=%u abt=%u\n", |
174 | atomic_read(&fscache_n_retrieval_ops), | 210 | atomic_read(&fscache_n_retrieval_ops), |
175 | atomic_read(&fscache_n_retrieval_op_waits)); | 211 | atomic_read(&fscache_n_retrieval_op_waits), |
212 | atomic_read(&fscache_n_retrievals_object_dead)); | ||
176 | 213 | ||
177 | seq_printf(m, "Stores : n=%u ok=%u agn=%u nbf=%u oom=%u\n", | 214 | seq_printf(m, "Stores : n=%u ok=%u agn=%u nbf=%u oom=%u\n", |
178 | atomic_read(&fscache_n_stores), | 215 | atomic_read(&fscache_n_stores), |
@@ -180,18 +217,49 @@ static int fscache_stats_show(struct seq_file *m, void *v) | |||
180 | atomic_read(&fscache_n_stores_again), | 217 | atomic_read(&fscache_n_stores_again), |
181 | atomic_read(&fscache_n_stores_nobufs), | 218 | atomic_read(&fscache_n_stores_nobufs), |
182 | atomic_read(&fscache_n_stores_oom)); | 219 | atomic_read(&fscache_n_stores_oom)); |
183 | seq_printf(m, "Stores : ops=%u run=%u\n", | 220 | seq_printf(m, "Stores : ops=%u run=%u pgs=%u rxd=%u olm=%u\n", |
184 | atomic_read(&fscache_n_store_ops), | 221 | atomic_read(&fscache_n_store_ops), |
185 | atomic_read(&fscache_n_store_calls)); | 222 | atomic_read(&fscache_n_store_calls), |
223 | atomic_read(&fscache_n_store_pages), | ||
224 | atomic_read(&fscache_n_store_radix_deletes), | ||
225 | atomic_read(&fscache_n_store_pages_over_limit)); | ||
186 | 226 | ||
187 | seq_printf(m, "Ops : pend=%u run=%u enq=%u\n", | 227 | seq_printf(m, "VmScan : nos=%u gon=%u bsy=%u can=%u\n", |
228 | atomic_read(&fscache_n_store_vmscan_not_storing), | ||
229 | atomic_read(&fscache_n_store_vmscan_gone), | ||
230 | atomic_read(&fscache_n_store_vmscan_busy), | ||
231 | atomic_read(&fscache_n_store_vmscan_cancelled)); | ||
232 | |||
233 | seq_printf(m, "Ops : pend=%u run=%u enq=%u can=%u rej=%u\n", | ||
188 | atomic_read(&fscache_n_op_pend), | 234 | atomic_read(&fscache_n_op_pend), |
189 | atomic_read(&fscache_n_op_run), | 235 | atomic_read(&fscache_n_op_run), |
190 | atomic_read(&fscache_n_op_enqueue)); | 236 | atomic_read(&fscache_n_op_enqueue), |
237 | atomic_read(&fscache_n_op_cancelled), | ||
238 | atomic_read(&fscache_n_op_rejected)); | ||
191 | seq_printf(m, "Ops : dfr=%u rel=%u gc=%u\n", | 239 | seq_printf(m, "Ops : dfr=%u rel=%u gc=%u\n", |
192 | atomic_read(&fscache_n_op_deferred_release), | 240 | atomic_read(&fscache_n_op_deferred_release), |
193 | atomic_read(&fscache_n_op_release), | 241 | atomic_read(&fscache_n_op_release), |
194 | atomic_read(&fscache_n_op_gc)); | 242 | atomic_read(&fscache_n_op_gc)); |
243 | |||
244 | seq_printf(m, "CacheOp: alo=%d luo=%d luc=%d gro=%d\n", | ||
245 | atomic_read(&fscache_n_cop_alloc_object), | ||
246 | atomic_read(&fscache_n_cop_lookup_object), | ||
247 | atomic_read(&fscache_n_cop_lookup_complete), | ||
248 | atomic_read(&fscache_n_cop_grab_object)); | ||
249 | seq_printf(m, "CacheOp: upo=%d dro=%d pto=%d atc=%d syn=%d\n", | ||
250 | atomic_read(&fscache_n_cop_update_object), | ||
251 | atomic_read(&fscache_n_cop_drop_object), | ||
252 | atomic_read(&fscache_n_cop_put_object), | ||
253 | atomic_read(&fscache_n_cop_attr_changed), | ||
254 | atomic_read(&fscache_n_cop_sync_cache)); | ||
255 | seq_printf(m, "CacheOp: rap=%d ras=%d alp=%d als=%d wrp=%d ucp=%d dsp=%d\n", | ||
256 | atomic_read(&fscache_n_cop_read_or_alloc_page), | ||
257 | atomic_read(&fscache_n_cop_read_or_alloc_pages), | ||
258 | atomic_read(&fscache_n_cop_allocate_page), | ||
259 | atomic_read(&fscache_n_cop_allocate_pages), | ||
260 | atomic_read(&fscache_n_cop_write_page), | ||
261 | atomic_read(&fscache_n_cop_uncache_page), | ||
262 | atomic_read(&fscache_n_cop_dissociate_pages)); | ||
195 | return 0; | 263 | return 0; |
196 | } | 264 | } |
197 | 265 | ||
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 8ada78aade58..4787ae6c5c1c 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -385,6 +385,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, | |||
385 | if (fc->no_create) | 385 | if (fc->no_create) |
386 | return -ENOSYS; | 386 | return -ENOSYS; |
387 | 387 | ||
388 | if (flags & O_DIRECT) | ||
389 | return -EINVAL; | ||
390 | |||
388 | forget_req = fuse_get_req(fc); | 391 | forget_req = fuse_get_req(fc); |
389 | if (IS_ERR(forget_req)) | 392 | if (IS_ERR(forget_req)) |
390 | return PTR_ERR(forget_req); | 393 | return PTR_ERR(forget_req); |
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index eacd78a5d082..5b31f7741a8f 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c | |||
@@ -114,7 +114,7 @@ static int __init init_gfs2_fs(void) | |||
114 | if (error) | 114 | if (error) |
115 | goto fail_unregister; | 115 | goto fail_unregister; |
116 | 116 | ||
117 | error = slow_work_register_user(); | 117 | error = slow_work_register_user(THIS_MODULE); |
118 | if (error) | 118 | if (error) |
119 | goto fail_slow; | 119 | goto fail_slow; |
120 | 120 | ||
@@ -163,7 +163,7 @@ static void __exit exit_gfs2_fs(void) | |||
163 | gfs2_unregister_debugfs(); | 163 | gfs2_unregister_debugfs(); |
164 | unregister_filesystem(&gfs2_fs_type); | 164 | unregister_filesystem(&gfs2_fs_type); |
165 | unregister_filesystem(&gfs2meta_fs_type); | 165 | unregister_filesystem(&gfs2meta_fs_type); |
166 | slow_work_unregister_user(); | 166 | slow_work_unregister_user(THIS_MODULE); |
167 | 167 | ||
168 | kmem_cache_destroy(gfs2_quotad_cachep); | 168 | kmem_cache_destroy(gfs2_quotad_cachep); |
169 | kmem_cache_destroy(gfs2_rgrpd_cachep); | 169 | kmem_cache_destroy(gfs2_rgrpd_cachep); |
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index 59d2695509d3..09fa31965576 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * of the GNU General Public License version 2. | 7 | * of the GNU General Public License version 2. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/module.h> | ||
10 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
11 | #include <linux/spinlock.h> | 12 | #include <linux/spinlock.h> |
12 | #include <linux/completion.h> | 13 | #include <linux/completion.h> |
@@ -593,6 +594,7 @@ fail: | |||
593 | } | 594 | } |
594 | 595 | ||
595 | struct slow_work_ops gfs2_recover_ops = { | 596 | struct slow_work_ops gfs2_recover_ops = { |
597 | .owner = THIS_MODULE, | ||
596 | .get_ref = gfs2_recover_get_ref, | 598 | .get_ref = gfs2_recover_get_ref, |
597 | .put_ref = gfs2_recover_put_ref, | 599 | .put_ref = gfs2_recover_put_ref, |
598 | .execute = gfs2_recover_work, | 600 | .execute = gfs2_recover_work, |
diff --git a/fs/jffs2/read.c b/fs/jffs2/read.c index cfe05c1966a5..3f39be1b0455 100644 --- a/fs/jffs2/read.c +++ b/fs/jffs2/read.c | |||
@@ -164,12 +164,15 @@ int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f, | |||
164 | 164 | ||
165 | /* XXX FIXME: Where a single physical node actually shows up in two | 165 | /* XXX FIXME: Where a single physical node actually shows up in two |
166 | frags, we read it twice. Don't do that. */ | 166 | frags, we read it twice. Don't do that. */ |
167 | /* Now we're pointing at the first frag which overlaps our page */ | 167 | /* Now we're pointing at the first frag which overlaps our page |
168 | * (or perhaps is before it, if we've been asked to read off the | ||
169 | * end of the file). */ | ||
168 | while(offset < end) { | 170 | while(offset < end) { |
169 | D2(printk(KERN_DEBUG "jffs2_read_inode_range: offset %d, end %d\n", offset, end)); | 171 | D2(printk(KERN_DEBUG "jffs2_read_inode_range: offset %d, end %d\n", offset, end)); |
170 | if (unlikely(!frag || frag->ofs > offset)) { | 172 | if (unlikely(!frag || frag->ofs > offset || |
173 | frag->ofs + frag->size <= offset)) { | ||
171 | uint32_t holesize = end - offset; | 174 | uint32_t holesize = end - offset; |
172 | if (frag) { | 175 | if (frag && frag->ofs > offset) { |
173 | D1(printk(KERN_NOTICE "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f->inocache->ino, frag->ofs, offset)); | 176 | D1(printk(KERN_NOTICE "Eep. Hole in ino #%u fraglist. frag->ofs = 0x%08x, offset = 0x%08x\n", f->inocache->ino, frag->ofs, offset)); |
174 | holesize = min(holesize, frag->ofs - offset); | 177 | holesize = min(holesize, frag->ofs - offset); |
175 | } | 178 | } |
diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c index 70fad69eb959..fa588006588d 100644 --- a/fs/nfs/fscache.c +++ b/fs/nfs/fscache.c | |||
@@ -359,17 +359,13 @@ int nfs_fscache_release_page(struct page *page, gfp_t gfp) | |||
359 | 359 | ||
360 | BUG_ON(!cookie); | 360 | BUG_ON(!cookie); |
361 | 361 | ||
362 | if (fscache_check_page_write(cookie, page)) { | ||
363 | if (!(gfp & __GFP_WAIT)) | ||
364 | return 0; | ||
365 | fscache_wait_on_page_write(cookie, page); | ||
366 | } | ||
367 | |||
368 | if (PageFsCache(page)) { | 362 | if (PageFsCache(page)) { |
369 | dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n", | 363 | dfprintk(FSCACHE, "NFS: fscache releasepage (0x%p/0x%p/0x%p)\n", |
370 | cookie, page, nfsi); | 364 | cookie, page, nfsi); |
371 | 365 | ||
372 | fscache_uncache_page(cookie, page); | 366 | if (!fscache_maybe_release_page(cookie, page, gfp)) |
367 | return 0; | ||
368 | |||
373 | nfs_add_fscache_stats(page->mapping->host, | 369 | nfs_add_fscache_stats(page->mapping->host, |
374 | NFSIOS_FSCACHE_PAGES_UNCACHED, 1); | 370 | NFSIOS_FSCACHE_PAGES_UNCACHED, 1); |
375 | } | 371 | } |
diff --git a/include/linux/fscache-cache.h b/include/linux/fscache-cache.h index 84d3532dd3ea..7be0c6fbe880 100644 --- a/include/linux/fscache-cache.h +++ b/include/linux/fscache-cache.h | |||
@@ -91,6 +91,8 @@ struct fscache_operation { | |||
91 | #define FSCACHE_OP_WAITING 4 /* cleared when op is woken */ | 91 | #define FSCACHE_OP_WAITING 4 /* cleared when op is woken */ |
92 | #define FSCACHE_OP_EXCLUSIVE 5 /* exclusive op, other ops must wait */ | 92 | #define FSCACHE_OP_EXCLUSIVE 5 /* exclusive op, other ops must wait */ |
93 | #define FSCACHE_OP_DEAD 6 /* op is now dead */ | 93 | #define FSCACHE_OP_DEAD 6 /* op is now dead */ |
94 | #define FSCACHE_OP_DEC_READ_CNT 7 /* decrement object->n_reads on destruction */ | ||
95 | #define FSCACHE_OP_KEEP_FLAGS 0xc0 /* flags to keep when repurposing an op */ | ||
94 | 96 | ||
95 | atomic_t usage; | 97 | atomic_t usage; |
96 | unsigned debug_id; /* debugging ID */ | 98 | unsigned debug_id; /* debugging ID */ |
@@ -102,6 +104,16 @@ struct fscache_operation { | |||
102 | 104 | ||
103 | /* operation releaser */ | 105 | /* operation releaser */ |
104 | fscache_operation_release_t release; | 106 | fscache_operation_release_t release; |
107 | |||
108 | #ifdef CONFIG_SLOW_WORK_PROC | ||
109 | const char *name; /* operation name */ | ||
110 | const char *state; /* operation state */ | ||
111 | #define fscache_set_op_name(OP, N) do { (OP)->name = (N); } while(0) | ||
112 | #define fscache_set_op_state(OP, S) do { (OP)->state = (S); } while(0) | ||
113 | #else | ||
114 | #define fscache_set_op_name(OP, N) do { } while(0) | ||
115 | #define fscache_set_op_state(OP, S) do { } while(0) | ||
116 | #endif | ||
105 | }; | 117 | }; |
106 | 118 | ||
107 | extern atomic_t fscache_op_debug_id; | 119 | extern atomic_t fscache_op_debug_id; |
@@ -125,6 +137,7 @@ static inline void fscache_operation_init(struct fscache_operation *op, | |||
125 | op->debug_id = atomic_inc_return(&fscache_op_debug_id); | 137 | op->debug_id = atomic_inc_return(&fscache_op_debug_id); |
126 | op->release = release; | 138 | op->release = release; |
127 | INIT_LIST_HEAD(&op->pend_link); | 139 | INIT_LIST_HEAD(&op->pend_link); |
140 | fscache_set_op_state(op, "Init"); | ||
128 | } | 141 | } |
129 | 142 | ||
130 | /** | 143 | /** |
@@ -221,8 +234,10 @@ struct fscache_cache_ops { | |||
221 | struct fscache_object *(*alloc_object)(struct fscache_cache *cache, | 234 | struct fscache_object *(*alloc_object)(struct fscache_cache *cache, |
222 | struct fscache_cookie *cookie); | 235 | struct fscache_cookie *cookie); |
223 | 236 | ||
224 | /* look up the object for a cookie */ | 237 | /* look up the object for a cookie |
225 | void (*lookup_object)(struct fscache_object *object); | 238 | * - return -ETIMEDOUT to be requeued |
239 | */ | ||
240 | int (*lookup_object)(struct fscache_object *object); | ||
226 | 241 | ||
227 | /* finished looking up */ | 242 | /* finished looking up */ |
228 | void (*lookup_complete)(struct fscache_object *object); | 243 | void (*lookup_complete)(struct fscache_object *object); |
@@ -297,12 +312,14 @@ struct fscache_cookie { | |||
297 | atomic_t usage; /* number of users of this cookie */ | 312 | atomic_t usage; /* number of users of this cookie */ |
298 | atomic_t n_children; /* number of children of this cookie */ | 313 | atomic_t n_children; /* number of children of this cookie */ |
299 | spinlock_t lock; | 314 | spinlock_t lock; |
315 | spinlock_t stores_lock; /* lock on page store tree */ | ||
300 | struct hlist_head backing_objects; /* object(s) backing this file/index */ | 316 | struct hlist_head backing_objects; /* object(s) backing this file/index */ |
301 | const struct fscache_cookie_def *def; /* definition */ | 317 | const struct fscache_cookie_def *def; /* definition */ |
302 | struct fscache_cookie *parent; /* parent of this entry */ | 318 | struct fscache_cookie *parent; /* parent of this entry */ |
303 | void *netfs_data; /* back pointer to netfs */ | 319 | void *netfs_data; /* back pointer to netfs */ |
304 | struct radix_tree_root stores; /* pages to be stored on this cookie */ | 320 | struct radix_tree_root stores; /* pages to be stored on this cookie */ |
305 | #define FSCACHE_COOKIE_PENDING_TAG 0 /* pages tag: pending write to cache */ | 321 | #define FSCACHE_COOKIE_PENDING_TAG 0 /* pages tag: pending write to cache */ |
322 | #define FSCACHE_COOKIE_STORING_TAG 1 /* pages tag: writing to cache */ | ||
306 | 323 | ||
307 | unsigned long flags; | 324 | unsigned long flags; |
308 | #define FSCACHE_COOKIE_LOOKING_UP 0 /* T if non-index cookie being looked up still */ | 325 | #define FSCACHE_COOKIE_LOOKING_UP 0 /* T if non-index cookie being looked up still */ |
@@ -337,6 +354,7 @@ struct fscache_object { | |||
337 | FSCACHE_OBJECT_RECYCLING, /* retiring object */ | 354 | FSCACHE_OBJECT_RECYCLING, /* retiring object */ |
338 | FSCACHE_OBJECT_WITHDRAWING, /* withdrawing object */ | 355 | FSCACHE_OBJECT_WITHDRAWING, /* withdrawing object */ |
339 | FSCACHE_OBJECT_DEAD, /* object is now dead */ | 356 | FSCACHE_OBJECT_DEAD, /* object is now dead */ |
357 | FSCACHE_OBJECT__NSTATES | ||
340 | } state; | 358 | } state; |
341 | 359 | ||
342 | int debug_id; /* debugging ID */ | 360 | int debug_id; /* debugging ID */ |
@@ -345,6 +363,7 @@ struct fscache_object { | |||
345 | int n_obj_ops; /* number of object ops outstanding on object */ | 363 | int n_obj_ops; /* number of object ops outstanding on object */ |
346 | int n_in_progress; /* number of ops in progress */ | 364 | int n_in_progress; /* number of ops in progress */ |
347 | int n_exclusive; /* number of exclusive ops queued */ | 365 | int n_exclusive; /* number of exclusive ops queued */ |
366 | atomic_t n_reads; /* number of read ops in progress */ | ||
348 | spinlock_t lock; /* state and operations lock */ | 367 | spinlock_t lock; /* state and operations lock */ |
349 | 368 | ||
350 | unsigned long lookup_jif; /* time at which lookup started */ | 369 | unsigned long lookup_jif; /* time at which lookup started */ |
@@ -358,6 +377,7 @@ struct fscache_object { | |||
358 | #define FSCACHE_OBJECT_EV_RELEASE 4 /* T if netfs requested object release */ | 377 | #define FSCACHE_OBJECT_EV_RELEASE 4 /* T if netfs requested object release */ |
359 | #define FSCACHE_OBJECT_EV_RETIRE 5 /* T if netfs requested object retirement */ | 378 | #define FSCACHE_OBJECT_EV_RETIRE 5 /* T if netfs requested object retirement */ |
360 | #define FSCACHE_OBJECT_EV_WITHDRAW 6 /* T if cache requested object withdrawal */ | 379 | #define FSCACHE_OBJECT_EV_WITHDRAW 6 /* T if cache requested object withdrawal */ |
380 | #define FSCACHE_OBJECT_EVENTS_MASK 0x7f /* mask of all events*/ | ||
361 | 381 | ||
362 | unsigned long flags; | 382 | unsigned long flags; |
363 | #define FSCACHE_OBJECT_LOCK 0 /* T if object is busy being processed */ | 383 | #define FSCACHE_OBJECT_LOCK 0 /* T if object is busy being processed */ |
@@ -373,7 +393,11 @@ struct fscache_object { | |||
373 | struct list_head dependents; /* FIFO of dependent objects */ | 393 | struct list_head dependents; /* FIFO of dependent objects */ |
374 | struct list_head dep_link; /* link in parent's dependents list */ | 394 | struct list_head dep_link; /* link in parent's dependents list */ |
375 | struct list_head pending_ops; /* unstarted operations on this object */ | 395 | struct list_head pending_ops; /* unstarted operations on this object */ |
396 | #ifdef CONFIG_FSCACHE_OBJECT_LIST | ||
397 | struct rb_node objlist_link; /* link in global object list */ | ||
398 | #endif | ||
376 | pgoff_t store_limit; /* current storage limit */ | 399 | pgoff_t store_limit; /* current storage limit */ |
400 | loff_t store_limit_l; /* current storage limit */ | ||
377 | }; | 401 | }; |
378 | 402 | ||
379 | extern const char *fscache_object_states[]; | 403 | extern const char *fscache_object_states[]; |
@@ -383,6 +407,10 @@ extern const char *fscache_object_states[]; | |||
383 | (obj)->state >= FSCACHE_OBJECT_AVAILABLE && \ | 407 | (obj)->state >= FSCACHE_OBJECT_AVAILABLE && \ |
384 | (obj)->state < FSCACHE_OBJECT_DYING) | 408 | (obj)->state < FSCACHE_OBJECT_DYING) |
385 | 409 | ||
410 | #define fscache_object_is_dead(obj) \ | ||
411 | (test_bit(FSCACHE_IOERROR, &(obj)->cache->flags) && \ | ||
412 | (obj)->state >= FSCACHE_OBJECT_DYING) | ||
413 | |||
386 | extern const struct slow_work_ops fscache_object_slow_work_ops; | 414 | extern const struct slow_work_ops fscache_object_slow_work_ops; |
387 | 415 | ||
388 | /** | 416 | /** |
@@ -414,6 +442,7 @@ void fscache_object_init(struct fscache_object *object, | |||
414 | object->events = object->event_mask = 0; | 442 | object->events = object->event_mask = 0; |
415 | object->flags = 0; | 443 | object->flags = 0; |
416 | object->store_limit = 0; | 444 | object->store_limit = 0; |
445 | object->store_limit_l = 0; | ||
417 | object->cache = cache; | 446 | object->cache = cache; |
418 | object->cookie = cookie; | 447 | object->cookie = cookie; |
419 | object->parent = NULL; | 448 | object->parent = NULL; |
@@ -422,6 +451,12 @@ void fscache_object_init(struct fscache_object *object, | |||
422 | extern void fscache_object_lookup_negative(struct fscache_object *object); | 451 | extern void fscache_object_lookup_negative(struct fscache_object *object); |
423 | extern void fscache_obtained_object(struct fscache_object *object); | 452 | extern void fscache_obtained_object(struct fscache_object *object); |
424 | 453 | ||
454 | #ifdef CONFIG_FSCACHE_OBJECT_LIST | ||
455 | extern void fscache_object_destroy(struct fscache_object *object); | ||
456 | #else | ||
457 | #define fscache_object_destroy(object) do {} while(0) | ||
458 | #endif | ||
459 | |||
425 | /** | 460 | /** |
426 | * fscache_object_destroyed - Note destruction of an object in a cache | 461 | * fscache_object_destroyed - Note destruction of an object in a cache |
427 | * @cache: The cache from which the object came | 462 | * @cache: The cache from which the object came |
@@ -460,6 +495,7 @@ static inline void fscache_object_lookup_error(struct fscache_object *object) | |||
460 | static inline | 495 | static inline |
461 | void fscache_set_store_limit(struct fscache_object *object, loff_t i_size) | 496 | void fscache_set_store_limit(struct fscache_object *object, loff_t i_size) |
462 | { | 497 | { |
498 | object->store_limit_l = i_size; | ||
463 | object->store_limit = i_size >> PAGE_SHIFT; | 499 | object->store_limit = i_size >> PAGE_SHIFT; |
464 | if (i_size & ~PAGE_MASK) | 500 | if (i_size & ~PAGE_MASK) |
465 | object->store_limit++; | 501 | object->store_limit++; |
diff --git a/include/linux/fscache.h b/include/linux/fscache.h index 6d8ee466e0a0..595ce49288b7 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h | |||
@@ -202,6 +202,8 @@ extern int __fscache_write_page(struct fscache_cookie *, struct page *, gfp_t); | |||
202 | extern void __fscache_uncache_page(struct fscache_cookie *, struct page *); | 202 | extern void __fscache_uncache_page(struct fscache_cookie *, struct page *); |
203 | extern bool __fscache_check_page_write(struct fscache_cookie *, struct page *); | 203 | extern bool __fscache_check_page_write(struct fscache_cookie *, struct page *); |
204 | extern void __fscache_wait_on_page_write(struct fscache_cookie *, struct page *); | 204 | extern void __fscache_wait_on_page_write(struct fscache_cookie *, struct page *); |
205 | extern bool __fscache_maybe_release_page(struct fscache_cookie *, struct page *, | ||
206 | gfp_t); | ||
205 | 207 | ||
206 | /** | 208 | /** |
207 | * fscache_register_netfs - Register a filesystem as desiring caching services | 209 | * fscache_register_netfs - Register a filesystem as desiring caching services |
@@ -615,4 +617,29 @@ void fscache_wait_on_page_write(struct fscache_cookie *cookie, | |||
615 | __fscache_wait_on_page_write(cookie, page); | 617 | __fscache_wait_on_page_write(cookie, page); |
616 | } | 618 | } |
617 | 619 | ||
620 | /** | ||
621 | * fscache_maybe_release_page - Consider releasing a page, cancelling a store | ||
622 | * @cookie: The cookie representing the cache object | ||
623 | * @page: The netfs page that is being cached. | ||
624 | * @gfp: The gfp flags passed to releasepage() | ||
625 | * | ||
626 | * Consider releasing a page for the vmscan algorithm, on behalf of the netfs's | ||
627 | * releasepage() call. A storage request on the page may cancelled if it is | ||
628 | * not currently being processed. | ||
629 | * | ||
630 | * The function returns true if the page no longer has a storage request on it, | ||
631 | * and false if a storage request is left in place. If true is returned, the | ||
632 | * page will have been passed to fscache_uncache_page(). If false is returned | ||
633 | * the page cannot be freed yet. | ||
634 | */ | ||
635 | static inline | ||
636 | bool fscache_maybe_release_page(struct fscache_cookie *cookie, | ||
637 | struct page *page, | ||
638 | gfp_t gfp) | ||
639 | { | ||
640 | if (fscache_cookie_valid(cookie) && PageFsCache(page)) | ||
641 | return __fscache_maybe_release_page(cookie, page, gfp); | ||
642 | return false; | ||
643 | } | ||
644 | |||
618 | #endif /* _LINUX_FSCACHE_H */ | 645 | #endif /* _LINUX_FSCACHE_H */ |
diff --git a/include/linux/slow-work.h b/include/linux/slow-work.h index b65c8881f07a..5035a2691739 100644 --- a/include/linux/slow-work.h +++ b/include/linux/slow-work.h | |||
@@ -17,13 +17,20 @@ | |||
17 | #ifdef CONFIG_SLOW_WORK | 17 | #ifdef CONFIG_SLOW_WORK |
18 | 18 | ||
19 | #include <linux/sysctl.h> | 19 | #include <linux/sysctl.h> |
20 | #include <linux/timer.h> | ||
20 | 21 | ||
21 | struct slow_work; | 22 | struct slow_work; |
23 | #ifdef CONFIG_SLOW_WORK_PROC | ||
24 | struct seq_file; | ||
25 | #endif | ||
22 | 26 | ||
23 | /* | 27 | /* |
24 | * The operations used to support slow work items | 28 | * The operations used to support slow work items |
25 | */ | 29 | */ |
26 | struct slow_work_ops { | 30 | struct slow_work_ops { |
31 | /* owner */ | ||
32 | struct module *owner; | ||
33 | |||
27 | /* get a ref on a work item | 34 | /* get a ref on a work item |
28 | * - return 0 if successful, -ve if not | 35 | * - return 0 if successful, -ve if not |
29 | */ | 36 | */ |
@@ -34,6 +41,11 @@ struct slow_work_ops { | |||
34 | 41 | ||
35 | /* execute a work item */ | 42 | /* execute a work item */ |
36 | void (*execute)(struct slow_work *work); | 43 | void (*execute)(struct slow_work *work); |
44 | |||
45 | #ifdef CONFIG_SLOW_WORK_PROC | ||
46 | /* describe a work item for /proc */ | ||
47 | void (*desc)(struct slow_work *work, struct seq_file *m); | ||
48 | #endif | ||
37 | }; | 49 | }; |
38 | 50 | ||
39 | /* | 51 | /* |
@@ -42,13 +54,24 @@ struct slow_work_ops { | |||
42 | * queued | 54 | * queued |
43 | */ | 55 | */ |
44 | struct slow_work { | 56 | struct slow_work { |
57 | struct module *owner; /* the owning module */ | ||
45 | unsigned long flags; | 58 | unsigned long flags; |
46 | #define SLOW_WORK_PENDING 0 /* item pending (further) execution */ | 59 | #define SLOW_WORK_PENDING 0 /* item pending (further) execution */ |
47 | #define SLOW_WORK_EXECUTING 1 /* item currently executing */ | 60 | #define SLOW_WORK_EXECUTING 1 /* item currently executing */ |
48 | #define SLOW_WORK_ENQ_DEFERRED 2 /* item enqueue deferred */ | 61 | #define SLOW_WORK_ENQ_DEFERRED 2 /* item enqueue deferred */ |
49 | #define SLOW_WORK_VERY_SLOW 3 /* item is very slow */ | 62 | #define SLOW_WORK_VERY_SLOW 3 /* item is very slow */ |
63 | #define SLOW_WORK_CANCELLING 4 /* item is being cancelled, don't enqueue */ | ||
64 | #define SLOW_WORK_DELAYED 5 /* item is struct delayed_slow_work with active timer */ | ||
50 | const struct slow_work_ops *ops; /* operations table for this item */ | 65 | const struct slow_work_ops *ops; /* operations table for this item */ |
51 | struct list_head link; /* link in queue */ | 66 | struct list_head link; /* link in queue */ |
67 | #ifdef CONFIG_SLOW_WORK_PROC | ||
68 | struct timespec mark; /* jiffies at which queued or exec begun */ | ||
69 | #endif | ||
70 | }; | ||
71 | |||
72 | struct delayed_slow_work { | ||
73 | struct slow_work work; | ||
74 | struct timer_list timer; | ||
52 | }; | 75 | }; |
53 | 76 | ||
54 | /** | 77 | /** |
@@ -67,6 +90,20 @@ static inline void slow_work_init(struct slow_work *work, | |||
67 | } | 90 | } |
68 | 91 | ||
69 | /** | 92 | /** |
93 | * slow_work_init - Initialise a delayed slow work item | ||
94 | * @work: The work item to initialise | ||
95 | * @ops: The operations to use to handle the slow work item | ||
96 | * | ||
97 | * Initialise a delayed slow work item. | ||
98 | */ | ||
99 | static inline void delayed_slow_work_init(struct delayed_slow_work *dwork, | ||
100 | const struct slow_work_ops *ops) | ||
101 | { | ||
102 | init_timer(&dwork->timer); | ||
103 | slow_work_init(&dwork->work, ops); | ||
104 | } | ||
105 | |||
106 | /** | ||
70 | * vslow_work_init - Initialise a very slow work item | 107 | * vslow_work_init - Initialise a very slow work item |
71 | * @work: The work item to initialise | 108 | * @work: The work item to initialise |
72 | * @ops: The operations to use to handle the slow work item | 109 | * @ops: The operations to use to handle the slow work item |
@@ -83,9 +120,40 @@ static inline void vslow_work_init(struct slow_work *work, | |||
83 | INIT_LIST_HEAD(&work->link); | 120 | INIT_LIST_HEAD(&work->link); |
84 | } | 121 | } |
85 | 122 | ||
123 | /** | ||
124 | * slow_work_is_queued - Determine if a slow work item is on the work queue | ||
125 | * work: The work item to test | ||
126 | * | ||
127 | * Determine if the specified slow-work item is on the work queue. This | ||
128 | * returns true if it is actually on the queue. | ||
129 | * | ||
130 | * If the item is executing and has been marked for requeue when execution | ||
131 | * finishes, then false will be returned. | ||
132 | * | ||
133 | * Anyone wishing to wait for completion of execution can wait on the | ||
134 | * SLOW_WORK_EXECUTING bit. | ||
135 | */ | ||
136 | static inline bool slow_work_is_queued(struct slow_work *work) | ||
137 | { | ||
138 | unsigned long flags = work->flags; | ||
139 | return flags & SLOW_WORK_PENDING && !(flags & SLOW_WORK_EXECUTING); | ||
140 | } | ||
141 | |||
86 | extern int slow_work_enqueue(struct slow_work *work); | 142 | extern int slow_work_enqueue(struct slow_work *work); |
87 | extern int slow_work_register_user(void); | 143 | extern void slow_work_cancel(struct slow_work *work); |
88 | extern void slow_work_unregister_user(void); | 144 | extern int slow_work_register_user(struct module *owner); |
145 | extern void slow_work_unregister_user(struct module *owner); | ||
146 | |||
147 | extern int delayed_slow_work_enqueue(struct delayed_slow_work *dwork, | ||
148 | unsigned long delay); | ||
149 | |||
150 | static inline void delayed_slow_work_cancel(struct delayed_slow_work *dwork) | ||
151 | { | ||
152 | slow_work_cancel(&dwork->work); | ||
153 | } | ||
154 | |||
155 | extern bool slow_work_sleep_till_thread_needed(struct slow_work *work, | ||
156 | signed long *_timeout); | ||
89 | 157 | ||
90 | #ifdef CONFIG_SYSCTL | 158 | #ifdef CONFIG_SYSCTL |
91 | extern ctl_table slow_work_sysctls[]; | 159 | extern ctl_table slow_work_sysctls[]; |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index c75b960c8ac8..998c30fc8981 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -1283,6 +1283,12 @@ enum ieee80211_filter_flags { | |||
1283 | * | 1283 | * |
1284 | * These flags are used with the ampdu_action() callback in | 1284 | * These flags are used with the ampdu_action() callback in |
1285 | * &struct ieee80211_ops to indicate which action is needed. | 1285 | * &struct ieee80211_ops to indicate which action is needed. |
1286 | * | ||
1287 | * Note that drivers MUST be able to deal with a TX aggregation | ||
1288 | * session being stopped even before they OK'ed starting it by | ||
1289 | * calling ieee80211_start_tx_ba_cb(_irqsafe), because the peer | ||
1290 | * might receive the addBA frame and send a delBA right away! | ||
1291 | * | ||
1286 | * @IEEE80211_AMPDU_RX_START: start Rx aggregation | 1292 | * @IEEE80211_AMPDU_RX_START: start Rx aggregation |
1287 | * @IEEE80211_AMPDU_RX_STOP: stop Rx aggregation | 1293 | * @IEEE80211_AMPDU_RX_STOP: stop Rx aggregation |
1288 | * @IEEE80211_AMPDU_TX_START: start Tx aggregation | 1294 | * @IEEE80211_AMPDU_TX_START: start Tx aggregation |
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index cd2e18778f81..0a474568b003 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h | |||
@@ -893,7 +893,6 @@ struct sctp_transport { | |||
893 | */ | 893 | */ |
894 | /* RTO : The current retransmission timeout value. */ | 894 | /* RTO : The current retransmission timeout value. */ |
895 | unsigned long rto; | 895 | unsigned long rto; |
896 | unsigned long last_rto; | ||
897 | 896 | ||
898 | __u32 rtt; /* This is the most recent RTT. */ | 897 | __u32 rtt; /* This is the most recent RTT. */ |
899 | 898 | ||
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 9af48cbf0036..f097ae340bc1 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h | |||
@@ -145,6 +145,7 @@ struct scsi_device { | |||
145 | unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */ | 145 | unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */ |
146 | unsigned last_sector_bug:1; /* do not use multisector accesses on | 146 | unsigned last_sector_bug:1; /* do not use multisector accesses on |
147 | SD_LAST_BUGGY_SECTORS */ | 147 | SD_LAST_BUGGY_SECTORS */ |
148 | unsigned is_visible:1; /* is the device visible in sysfs */ | ||
148 | 149 | ||
149 | DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */ | 150 | DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */ |
150 | struct list_head event_list; /* asserted events */ | 151 | struct list_head event_list; /* asserted events */ |
diff --git a/init/Kconfig b/init/Kconfig index 9e03ef8b311e..ab5c64801fe5 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -1098,6 +1098,16 @@ config SLOW_WORK | |||
1098 | 1098 | ||
1099 | See Documentation/slow-work.txt. | 1099 | See Documentation/slow-work.txt. |
1100 | 1100 | ||
1101 | config SLOW_WORK_PROC | ||
1102 | bool "Slow work debugging through /proc" | ||
1103 | default n | ||
1104 | depends on SLOW_WORK && PROC_FS | ||
1105 | help | ||
1106 | Display the contents of the slow work run queue through /proc, | ||
1107 | including items currently executing. | ||
1108 | |||
1109 | See Documentation/slow-work.txt. | ||
1110 | |||
1101 | endmenu # General setup | 1111 | endmenu # General setup |
1102 | 1112 | ||
1103 | config HAVE_GENERIC_DMA_COHERENT | 1113 | config HAVE_GENERIC_DMA_COHERENT |
diff --git a/kernel/Makefile b/kernel/Makefile index b8d4cd8ac0b9..776ffed1556d 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
@@ -94,6 +94,7 @@ obj-$(CONFIG_X86_DS) += trace/ | |||
94 | obj-$(CONFIG_RING_BUFFER) += trace/ | 94 | obj-$(CONFIG_RING_BUFFER) += trace/ |
95 | obj-$(CONFIG_SMP) += sched_cpupri.o | 95 | obj-$(CONFIG_SMP) += sched_cpupri.o |
96 | obj-$(CONFIG_SLOW_WORK) += slow-work.o | 96 | obj-$(CONFIG_SLOW_WORK) += slow-work.o |
97 | obj-$(CONFIG_SLOW_WORK_PROC) += slow-work-proc.o | ||
97 | obj-$(CONFIG_PERF_EVENTS) += perf_event.o | 98 | obj-$(CONFIG_PERF_EVENTS) += perf_event.o |
98 | 99 | ||
99 | ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y) | 100 | ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y) |
diff --git a/kernel/slow-work-proc.c b/kernel/slow-work-proc.c new file mode 100644 index 000000000000..3988032571f5 --- /dev/null +++ b/kernel/slow-work-proc.c | |||
@@ -0,0 +1,227 @@ | |||
1 | /* Slow work debugging | ||
2 | * | ||
3 | * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #include <linux/module.h> | ||
13 | #include <linux/slow-work.h> | ||
14 | #include <linux/fs.h> | ||
15 | #include <linux/time.h> | ||
16 | #include <linux/seq_file.h> | ||
17 | #include "slow-work.h" | ||
18 | |||
19 | #define ITERATOR_SHIFT (BITS_PER_LONG - 4) | ||
20 | #define ITERATOR_SELECTOR (0xfUL << ITERATOR_SHIFT) | ||
21 | #define ITERATOR_COUNTER (~ITERATOR_SELECTOR) | ||
22 | |||
23 | void slow_work_new_thread_desc(struct slow_work *work, struct seq_file *m) | ||
24 | { | ||
25 | seq_puts(m, "Slow-work: New thread"); | ||
26 | } | ||
27 | |||
28 | /* | ||
29 | * Render the time mark field on a work item into a 5-char time with units plus | ||
30 | * a space | ||
31 | */ | ||
32 | static void slow_work_print_mark(struct seq_file *m, struct slow_work *work) | ||
33 | { | ||
34 | struct timespec now, diff; | ||
35 | |||
36 | now = CURRENT_TIME; | ||
37 | diff = timespec_sub(now, work->mark); | ||
38 | |||
39 | if (diff.tv_sec < 0) | ||
40 | seq_puts(m, " -ve "); | ||
41 | else if (diff.tv_sec == 0 && diff.tv_nsec < 1000) | ||
42 | seq_printf(m, "%3luns ", diff.tv_nsec); | ||
43 | else if (diff.tv_sec == 0 && diff.tv_nsec < 1000000) | ||
44 | seq_printf(m, "%3luus ", diff.tv_nsec / 1000); | ||
45 | else if (diff.tv_sec == 0 && diff.tv_nsec < 1000000000) | ||
46 | seq_printf(m, "%3lums ", diff.tv_nsec / 1000000); | ||
47 | else if (diff.tv_sec <= 1) | ||
48 | seq_puts(m, " 1s "); | ||
49 | else if (diff.tv_sec < 60) | ||
50 | seq_printf(m, "%4lus ", diff.tv_sec); | ||
51 | else if (diff.tv_sec < 60 * 60) | ||
52 | seq_printf(m, "%4lum ", diff.tv_sec / 60); | ||
53 | else if (diff.tv_sec < 60 * 60 * 24) | ||
54 | seq_printf(m, "%4luh ", diff.tv_sec / 3600); | ||
55 | else | ||
56 | seq_puts(m, "exces "); | ||
57 | } | ||
58 | |||
59 | /* | ||
60 | * Describe a slow work item for /proc | ||
61 | */ | ||
62 | static int slow_work_runqueue_show(struct seq_file *m, void *v) | ||
63 | { | ||
64 | struct slow_work *work; | ||
65 | struct list_head *p = v; | ||
66 | unsigned long id; | ||
67 | |||
68 | switch ((unsigned long) v) { | ||
69 | case 1: | ||
70 | seq_puts(m, "THR PID ITEM ADDR FL MARK DESC\n"); | ||
71 | return 0; | ||
72 | case 2: | ||
73 | seq_puts(m, "=== ===== ================ == ===== ==========\n"); | ||
74 | return 0; | ||
75 | |||
76 | case 3 ... 3 + SLOW_WORK_THREAD_LIMIT - 1: | ||
77 | id = (unsigned long) v - 3; | ||
78 | |||
79 | read_lock(&slow_work_execs_lock); | ||
80 | work = slow_work_execs[id]; | ||
81 | if (work) { | ||
82 | smp_read_barrier_depends(); | ||
83 | |||
84 | seq_printf(m, "%3lu %5d %16p %2lx ", | ||
85 | id, slow_work_pids[id], work, work->flags); | ||
86 | slow_work_print_mark(m, work); | ||
87 | |||
88 | if (work->ops->desc) | ||
89 | work->ops->desc(work, m); | ||
90 | seq_putc(m, '\n'); | ||
91 | } | ||
92 | read_unlock(&slow_work_execs_lock); | ||
93 | return 0; | ||
94 | |||
95 | default: | ||
96 | work = list_entry(p, struct slow_work, link); | ||
97 | seq_printf(m, "%3s - %16p %2lx ", | ||
98 | work->flags & SLOW_WORK_VERY_SLOW ? "vsq" : "sq", | ||
99 | work, work->flags); | ||
100 | slow_work_print_mark(m, work); | ||
101 | |||
102 | if (work->ops->desc) | ||
103 | work->ops->desc(work, m); | ||
104 | seq_putc(m, '\n'); | ||
105 | return 0; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | /* | ||
110 | * map the iterator to a work item | ||
111 | */ | ||
112 | static void *slow_work_runqueue_index(struct seq_file *m, loff_t *_pos) | ||
113 | { | ||
114 | struct list_head *p; | ||
115 | unsigned long count, id; | ||
116 | |||
117 | switch (*_pos >> ITERATOR_SHIFT) { | ||
118 | case 0x0: | ||
119 | if (*_pos == 0) | ||
120 | *_pos = 1; | ||
121 | if (*_pos < 3) | ||
122 | return (void *)(unsigned long) *_pos; | ||
123 | if (*_pos < 3 + SLOW_WORK_THREAD_LIMIT) | ||
124 | for (id = *_pos - 3; | ||
125 | id < SLOW_WORK_THREAD_LIMIT; | ||
126 | id++, (*_pos)++) | ||
127 | if (slow_work_execs[id]) | ||
128 | return (void *)(unsigned long) *_pos; | ||
129 | *_pos = 0x1UL << ITERATOR_SHIFT; | ||
130 | |||
131 | case 0x1: | ||
132 | count = *_pos & ITERATOR_COUNTER; | ||
133 | list_for_each(p, &slow_work_queue) { | ||
134 | if (count == 0) | ||
135 | return p; | ||
136 | count--; | ||
137 | } | ||
138 | *_pos = 0x2UL << ITERATOR_SHIFT; | ||
139 | |||
140 | case 0x2: | ||
141 | count = *_pos & ITERATOR_COUNTER; | ||
142 | list_for_each(p, &vslow_work_queue) { | ||
143 | if (count == 0) | ||
144 | return p; | ||
145 | count--; | ||
146 | } | ||
147 | *_pos = 0x3UL << ITERATOR_SHIFT; | ||
148 | |||
149 | default: | ||
150 | return NULL; | ||
151 | } | ||
152 | } | ||
153 | |||
154 | /* | ||
155 | * set up the iterator to start reading from the first line | ||
156 | */ | ||
157 | static void *slow_work_runqueue_start(struct seq_file *m, loff_t *_pos) | ||
158 | { | ||
159 | spin_lock_irq(&slow_work_queue_lock); | ||
160 | return slow_work_runqueue_index(m, _pos); | ||
161 | } | ||
162 | |||
163 | /* | ||
164 | * move to the next line | ||
165 | */ | ||
166 | static void *slow_work_runqueue_next(struct seq_file *m, void *v, loff_t *_pos) | ||
167 | { | ||
168 | struct list_head *p = v; | ||
169 | unsigned long selector = *_pos >> ITERATOR_SHIFT; | ||
170 | |||
171 | (*_pos)++; | ||
172 | switch (selector) { | ||
173 | case 0x0: | ||
174 | return slow_work_runqueue_index(m, _pos); | ||
175 | |||
176 | case 0x1: | ||
177 | if (*_pos >> ITERATOR_SHIFT == 0x1) { | ||
178 | p = p->next; | ||
179 | if (p != &slow_work_queue) | ||
180 | return p; | ||
181 | } | ||
182 | *_pos = 0x2UL << ITERATOR_SHIFT; | ||
183 | p = &vslow_work_queue; | ||
184 | |||
185 | case 0x2: | ||
186 | if (*_pos >> ITERATOR_SHIFT == 0x2) { | ||
187 | p = p->next; | ||
188 | if (p != &vslow_work_queue) | ||
189 | return p; | ||
190 | } | ||
191 | *_pos = 0x3UL << ITERATOR_SHIFT; | ||
192 | |||
193 | default: | ||
194 | return NULL; | ||
195 | } | ||
196 | } | ||
197 | |||
198 | /* | ||
199 | * clean up after reading | ||
200 | */ | ||
201 | static void slow_work_runqueue_stop(struct seq_file *m, void *v) | ||
202 | { | ||
203 | spin_unlock_irq(&slow_work_queue_lock); | ||
204 | } | ||
205 | |||
206 | static const struct seq_operations slow_work_runqueue_ops = { | ||
207 | .start = slow_work_runqueue_start, | ||
208 | .stop = slow_work_runqueue_stop, | ||
209 | .next = slow_work_runqueue_next, | ||
210 | .show = slow_work_runqueue_show, | ||
211 | }; | ||
212 | |||
213 | /* | ||
214 | * open "/proc/slow_work_rq" to list queue contents | ||
215 | */ | ||
216 | static int slow_work_runqueue_open(struct inode *inode, struct file *file) | ||
217 | { | ||
218 | return seq_open(file, &slow_work_runqueue_ops); | ||
219 | } | ||
220 | |||
221 | const struct file_operations slow_work_runqueue_fops = { | ||
222 | .owner = THIS_MODULE, | ||
223 | .open = slow_work_runqueue_open, | ||
224 | .read = seq_read, | ||
225 | .llseek = seq_lseek, | ||
226 | .release = seq_release, | ||
227 | }; | ||
diff --git a/kernel/slow-work.c b/kernel/slow-work.c index 0d31135efbf4..da94f3c101af 100644 --- a/kernel/slow-work.c +++ b/kernel/slow-work.c | |||
@@ -16,11 +16,8 @@ | |||
16 | #include <linux/kthread.h> | 16 | #include <linux/kthread.h> |
17 | #include <linux/freezer.h> | 17 | #include <linux/freezer.h> |
18 | #include <linux/wait.h> | 18 | #include <linux/wait.h> |
19 | 19 | #include <linux/proc_fs.h> | |
20 | #define SLOW_WORK_CULL_TIMEOUT (5 * HZ) /* cull threads 5s after running out of | 20 | #include "slow-work.h" |
21 | * things to do */ | ||
22 | #define SLOW_WORK_OOM_TIMEOUT (5 * HZ) /* can't start new threads for 5s after | ||
23 | * OOM */ | ||
24 | 21 | ||
25 | static void slow_work_cull_timeout(unsigned long); | 22 | static void slow_work_cull_timeout(unsigned long); |
26 | static void slow_work_oom_timeout(unsigned long); | 23 | static void slow_work_oom_timeout(unsigned long); |
@@ -46,7 +43,7 @@ static unsigned vslow_work_proportion = 50; /* % of threads that may process | |||
46 | 43 | ||
47 | #ifdef CONFIG_SYSCTL | 44 | #ifdef CONFIG_SYSCTL |
48 | static const int slow_work_min_min_threads = 2; | 45 | static const int slow_work_min_min_threads = 2; |
49 | static int slow_work_max_max_threads = 255; | 46 | static int slow_work_max_max_threads = SLOW_WORK_THREAD_LIMIT; |
50 | static const int slow_work_min_vslow = 1; | 47 | static const int slow_work_min_vslow = 1; |
51 | static const int slow_work_max_vslow = 99; | 48 | static const int slow_work_max_vslow = 99; |
52 | 49 | ||
@@ -98,6 +95,32 @@ static DEFINE_TIMER(slow_work_oom_timer, slow_work_oom_timeout, 0, 0); | |||
98 | static struct slow_work slow_work_new_thread; /* new thread starter */ | 95 | static struct slow_work slow_work_new_thread; /* new thread starter */ |
99 | 96 | ||
100 | /* | 97 | /* |
98 | * slow work ID allocation (use slow_work_queue_lock) | ||
99 | */ | ||
100 | static DECLARE_BITMAP(slow_work_ids, SLOW_WORK_THREAD_LIMIT); | ||
101 | |||
102 | /* | ||
103 | * Unregistration tracking to prevent put_ref() from disappearing during module | ||
104 | * unload | ||
105 | */ | ||
106 | #ifdef CONFIG_MODULES | ||
107 | static struct module *slow_work_thread_processing[SLOW_WORK_THREAD_LIMIT]; | ||
108 | static struct module *slow_work_unreg_module; | ||
109 | static struct slow_work *slow_work_unreg_work_item; | ||
110 | static DECLARE_WAIT_QUEUE_HEAD(slow_work_unreg_wq); | ||
111 | static DEFINE_MUTEX(slow_work_unreg_sync_lock); | ||
112 | #endif | ||
113 | |||
114 | /* | ||
115 | * Data for tracking currently executing items for indication through /proc | ||
116 | */ | ||
117 | #ifdef CONFIG_SLOW_WORK_PROC | ||
118 | struct slow_work *slow_work_execs[SLOW_WORK_THREAD_LIMIT]; | ||
119 | pid_t slow_work_pids[SLOW_WORK_THREAD_LIMIT]; | ||
120 | DEFINE_RWLOCK(slow_work_execs_lock); | ||
121 | #endif | ||
122 | |||
123 | /* | ||
101 | * The queues of work items and the lock governing access to them. These are | 124 | * The queues of work items and the lock governing access to them. These are |
102 | * shared between all the CPUs. It doesn't make sense to have per-CPU queues | 125 | * shared between all the CPUs. It doesn't make sense to have per-CPU queues |
103 | * as the number of threads bears no relation to the number of CPUs. | 126 | * as the number of threads bears no relation to the number of CPUs. |
@@ -105,9 +128,18 @@ static struct slow_work slow_work_new_thread; /* new thread starter */ | |||
105 | * There are two queues of work items: one for slow work items, and one for | 128 | * There are two queues of work items: one for slow work items, and one for |
106 | * very slow work items. | 129 | * very slow work items. |
107 | */ | 130 | */ |
108 | static LIST_HEAD(slow_work_queue); | 131 | LIST_HEAD(slow_work_queue); |
109 | static LIST_HEAD(vslow_work_queue); | 132 | LIST_HEAD(vslow_work_queue); |
110 | static DEFINE_SPINLOCK(slow_work_queue_lock); | 133 | DEFINE_SPINLOCK(slow_work_queue_lock); |
134 | |||
135 | /* | ||
136 | * The following are two wait queues that get pinged when a work item is placed | ||
137 | * on an empty queue. These allow work items that are hogging a thread by | ||
138 | * sleeping in a way that could be deferred to yield their thread and enqueue | ||
139 | * themselves. | ||
140 | */ | ||
141 | static DECLARE_WAIT_QUEUE_HEAD(slow_work_queue_waits_for_occupation); | ||
142 | static DECLARE_WAIT_QUEUE_HEAD(vslow_work_queue_waits_for_occupation); | ||
111 | 143 | ||
112 | /* | 144 | /* |
113 | * The thread controls. A variable used to signal to the threads that they | 145 | * The thread controls. A variable used to signal to the threads that they |
@@ -126,6 +158,20 @@ static DECLARE_COMPLETION(slow_work_last_thread_exited); | |||
126 | static int slow_work_user_count; | 158 | static int slow_work_user_count; |
127 | static DEFINE_MUTEX(slow_work_user_lock); | 159 | static DEFINE_MUTEX(slow_work_user_lock); |
128 | 160 | ||
161 | static inline int slow_work_get_ref(struct slow_work *work) | ||
162 | { | ||
163 | if (work->ops->get_ref) | ||
164 | return work->ops->get_ref(work); | ||
165 | |||
166 | return 0; | ||
167 | } | ||
168 | |||
169 | static inline void slow_work_put_ref(struct slow_work *work) | ||
170 | { | ||
171 | if (work->ops->put_ref) | ||
172 | work->ops->put_ref(work); | ||
173 | } | ||
174 | |||
129 | /* | 175 | /* |
130 | * Calculate the maximum number of active threads in the pool that are | 176 | * Calculate the maximum number of active threads in the pool that are |
131 | * permitted to process very slow work items. | 177 | * permitted to process very slow work items. |
@@ -149,8 +195,11 @@ static unsigned slow_work_calc_vsmax(void) | |||
149 | * Attempt to execute stuff queued on a slow thread. Return true if we managed | 195 | * Attempt to execute stuff queued on a slow thread. Return true if we managed |
150 | * it, false if there was nothing to do. | 196 | * it, false if there was nothing to do. |
151 | */ | 197 | */ |
152 | static bool slow_work_execute(void) | 198 | static noinline bool slow_work_execute(int id) |
153 | { | 199 | { |
200 | #ifdef CONFIG_MODULES | ||
201 | struct module *module; | ||
202 | #endif | ||
154 | struct slow_work *work = NULL; | 203 | struct slow_work *work = NULL; |
155 | unsigned vsmax; | 204 | unsigned vsmax; |
156 | bool very_slow; | 205 | bool very_slow; |
@@ -186,6 +235,16 @@ static bool slow_work_execute(void) | |||
186 | } else { | 235 | } else { |
187 | very_slow = false; /* avoid the compiler warning */ | 236 | very_slow = false; /* avoid the compiler warning */ |
188 | } | 237 | } |
238 | |||
239 | #ifdef CONFIG_MODULES | ||
240 | if (work) | ||
241 | slow_work_thread_processing[id] = work->owner; | ||
242 | #endif | ||
243 | if (work) { | ||
244 | slow_work_mark_time(work); | ||
245 | slow_work_begin_exec(id, work); | ||
246 | } | ||
247 | |||
189 | spin_unlock_irq(&slow_work_queue_lock); | 248 | spin_unlock_irq(&slow_work_queue_lock); |
190 | 249 | ||
191 | if (!work) | 250 | if (!work) |
@@ -194,12 +253,19 @@ static bool slow_work_execute(void) | |||
194 | if (!test_and_clear_bit(SLOW_WORK_PENDING, &work->flags)) | 253 | if (!test_and_clear_bit(SLOW_WORK_PENDING, &work->flags)) |
195 | BUG(); | 254 | BUG(); |
196 | 255 | ||
197 | work->ops->execute(work); | 256 | /* don't execute if the work is in the process of being cancelled */ |
257 | if (!test_bit(SLOW_WORK_CANCELLING, &work->flags)) | ||
258 | work->ops->execute(work); | ||
198 | 259 | ||
199 | if (very_slow) | 260 | if (very_slow) |
200 | atomic_dec(&vslow_work_executing_count); | 261 | atomic_dec(&vslow_work_executing_count); |
201 | clear_bit_unlock(SLOW_WORK_EXECUTING, &work->flags); | 262 | clear_bit_unlock(SLOW_WORK_EXECUTING, &work->flags); |
202 | 263 | ||
264 | /* wake up anyone waiting for this work to be complete */ | ||
265 | wake_up_bit(&work->flags, SLOW_WORK_EXECUTING); | ||
266 | |||
267 | slow_work_end_exec(id, work); | ||
268 | |||
203 | /* if someone tried to enqueue the item whilst we were executing it, | 269 | /* if someone tried to enqueue the item whilst we were executing it, |
204 | * then it'll be left unenqueued to avoid multiple threads trying to | 270 | * then it'll be left unenqueued to avoid multiple threads trying to |
205 | * execute it simultaneously | 271 | * execute it simultaneously |
@@ -219,7 +285,18 @@ static bool slow_work_execute(void) | |||
219 | spin_unlock_irq(&slow_work_queue_lock); | 285 | spin_unlock_irq(&slow_work_queue_lock); |
220 | } | 286 | } |
221 | 287 | ||
222 | work->ops->put_ref(work); | 288 | /* sort out the race between module unloading and put_ref() */ |
289 | slow_work_put_ref(work); | ||
290 | |||
291 | #ifdef CONFIG_MODULES | ||
292 | module = slow_work_thread_processing[id]; | ||
293 | slow_work_thread_processing[id] = NULL; | ||
294 | smp_mb(); | ||
295 | if (slow_work_unreg_work_item == work || | ||
296 | slow_work_unreg_module == module) | ||
297 | wake_up_all(&slow_work_unreg_wq); | ||
298 | #endif | ||
299 | |||
223 | return true; | 300 | return true; |
224 | 301 | ||
225 | auto_requeue: | 302 | auto_requeue: |
@@ -227,15 +304,61 @@ auto_requeue: | |||
227 | * - we transfer our ref on the item back to the appropriate queue | 304 | * - we transfer our ref on the item back to the appropriate queue |
228 | * - don't wake another thread up as we're awake already | 305 | * - don't wake another thread up as we're awake already |
229 | */ | 306 | */ |
307 | slow_work_mark_time(work); | ||
230 | if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) | 308 | if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) |
231 | list_add_tail(&work->link, &vslow_work_queue); | 309 | list_add_tail(&work->link, &vslow_work_queue); |
232 | else | 310 | else |
233 | list_add_tail(&work->link, &slow_work_queue); | 311 | list_add_tail(&work->link, &slow_work_queue); |
234 | spin_unlock_irq(&slow_work_queue_lock); | 312 | spin_unlock_irq(&slow_work_queue_lock); |
313 | slow_work_thread_processing[id] = NULL; | ||
235 | return true; | 314 | return true; |
236 | } | 315 | } |
237 | 316 | ||
238 | /** | 317 | /** |
318 | * slow_work_sleep_till_thread_needed - Sleep till thread needed by other work | ||
319 | * work: The work item under execution that wants to sleep | ||
320 | * _timeout: Scheduler sleep timeout | ||
321 | * | ||
322 | * Allow a requeueable work item to sleep on a slow-work processor thread until | ||
323 | * that thread is needed to do some other work or the sleep is interrupted by | ||
324 | * some other event. | ||
325 | * | ||
326 | * The caller must set up a wake up event before calling this and must have set | ||
327 | * the appropriate sleep mode (such as TASK_UNINTERRUPTIBLE) and tested its own | ||
328 | * condition before calling this function as no test is made here. | ||
329 | * | ||
330 | * False is returned if there is nothing on the queue; true is returned if the | ||
331 | * work item should be requeued | ||
332 | */ | ||
333 | bool slow_work_sleep_till_thread_needed(struct slow_work *work, | ||
334 | signed long *_timeout) | ||
335 | { | ||
336 | wait_queue_head_t *wfo_wq; | ||
337 | struct list_head *queue; | ||
338 | |||
339 | DEFINE_WAIT(wait); | ||
340 | |||
341 | if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) { | ||
342 | wfo_wq = &vslow_work_queue_waits_for_occupation; | ||
343 | queue = &vslow_work_queue; | ||
344 | } else { | ||
345 | wfo_wq = &slow_work_queue_waits_for_occupation; | ||
346 | queue = &slow_work_queue; | ||
347 | } | ||
348 | |||
349 | if (!list_empty(queue)) | ||
350 | return true; | ||
351 | |||
352 | add_wait_queue_exclusive(wfo_wq, &wait); | ||
353 | if (list_empty(queue)) | ||
354 | *_timeout = schedule_timeout(*_timeout); | ||
355 | finish_wait(wfo_wq, &wait); | ||
356 | |||
357 | return !list_empty(queue); | ||
358 | } | ||
359 | EXPORT_SYMBOL(slow_work_sleep_till_thread_needed); | ||
360 | |||
361 | /** | ||
239 | * slow_work_enqueue - Schedule a slow work item for processing | 362 | * slow_work_enqueue - Schedule a slow work item for processing |
240 | * @work: The work item to queue | 363 | * @work: The work item to queue |
241 | * | 364 | * |
@@ -260,16 +383,22 @@ auto_requeue: | |||
260 | * allowed to pick items to execute. This ensures that very slow items won't | 383 | * allowed to pick items to execute. This ensures that very slow items won't |
261 | * overly block ones that are just ordinarily slow. | 384 | * overly block ones that are just ordinarily slow. |
262 | * | 385 | * |
263 | * Returns 0 if successful, -EAGAIN if not. | 386 | * Returns 0 if successful, -EAGAIN if not (or -ECANCELED if cancelled work is |
387 | * attempted queued) | ||
264 | */ | 388 | */ |
265 | int slow_work_enqueue(struct slow_work *work) | 389 | int slow_work_enqueue(struct slow_work *work) |
266 | { | 390 | { |
391 | wait_queue_head_t *wfo_wq; | ||
392 | struct list_head *queue; | ||
267 | unsigned long flags; | 393 | unsigned long flags; |
394 | int ret; | ||
395 | |||
396 | if (test_bit(SLOW_WORK_CANCELLING, &work->flags)) | ||
397 | return -ECANCELED; | ||
268 | 398 | ||
269 | BUG_ON(slow_work_user_count <= 0); | 399 | BUG_ON(slow_work_user_count <= 0); |
270 | BUG_ON(!work); | 400 | BUG_ON(!work); |
271 | BUG_ON(!work->ops); | 401 | BUG_ON(!work->ops); |
272 | BUG_ON(!work->ops->get_ref); | ||
273 | 402 | ||
274 | /* when honouring an enqueue request, we only promise that we will run | 403 | /* when honouring an enqueue request, we only promise that we will run |
275 | * the work function in the future; we do not promise to run it once | 404 | * the work function in the future; we do not promise to run it once |
@@ -280,8 +409,19 @@ int slow_work_enqueue(struct slow_work *work) | |||
280 | * maintaining our promise | 409 | * maintaining our promise |
281 | */ | 410 | */ |
282 | if (!test_and_set_bit_lock(SLOW_WORK_PENDING, &work->flags)) { | 411 | if (!test_and_set_bit_lock(SLOW_WORK_PENDING, &work->flags)) { |
412 | if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) { | ||
413 | wfo_wq = &vslow_work_queue_waits_for_occupation; | ||
414 | queue = &vslow_work_queue; | ||
415 | } else { | ||
416 | wfo_wq = &slow_work_queue_waits_for_occupation; | ||
417 | queue = &slow_work_queue; | ||
418 | } | ||
419 | |||
283 | spin_lock_irqsave(&slow_work_queue_lock, flags); | 420 | spin_lock_irqsave(&slow_work_queue_lock, flags); |
284 | 421 | ||
422 | if (unlikely(test_bit(SLOW_WORK_CANCELLING, &work->flags))) | ||
423 | goto cancelled; | ||
424 | |||
285 | /* we promise that we will not attempt to execute the work | 425 | /* we promise that we will not attempt to execute the work |
286 | * function in more than one thread simultaneously | 426 | * function in more than one thread simultaneously |
287 | * | 427 | * |
@@ -299,25 +439,221 @@ int slow_work_enqueue(struct slow_work *work) | |||
299 | if (test_bit(SLOW_WORK_EXECUTING, &work->flags)) { | 439 | if (test_bit(SLOW_WORK_EXECUTING, &work->flags)) { |
300 | set_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags); | 440 | set_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags); |
301 | } else { | 441 | } else { |
302 | if (work->ops->get_ref(work) < 0) | 442 | ret = slow_work_get_ref(work); |
303 | goto cant_get_ref; | 443 | if (ret < 0) |
304 | if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) | 444 | goto failed; |
305 | list_add_tail(&work->link, &vslow_work_queue); | 445 | slow_work_mark_time(work); |
306 | else | 446 | list_add_tail(&work->link, queue); |
307 | list_add_tail(&work->link, &slow_work_queue); | ||
308 | wake_up(&slow_work_thread_wq); | 447 | wake_up(&slow_work_thread_wq); |
448 | |||
449 | /* if someone who could be requeued is sleeping on a | ||
450 | * thread, then ask them to yield their thread */ | ||
451 | if (work->link.prev == queue) | ||
452 | wake_up(wfo_wq); | ||
309 | } | 453 | } |
310 | 454 | ||
311 | spin_unlock_irqrestore(&slow_work_queue_lock, flags); | 455 | spin_unlock_irqrestore(&slow_work_queue_lock, flags); |
312 | } | 456 | } |
313 | return 0; | 457 | return 0; |
314 | 458 | ||
315 | cant_get_ref: | 459 | cancelled: |
460 | ret = -ECANCELED; | ||
461 | failed: | ||
316 | spin_unlock_irqrestore(&slow_work_queue_lock, flags); | 462 | spin_unlock_irqrestore(&slow_work_queue_lock, flags); |
317 | return -EAGAIN; | 463 | return ret; |
318 | } | 464 | } |
319 | EXPORT_SYMBOL(slow_work_enqueue); | 465 | EXPORT_SYMBOL(slow_work_enqueue); |
320 | 466 | ||
467 | static int slow_work_wait(void *word) | ||
468 | { | ||
469 | schedule(); | ||
470 | return 0; | ||
471 | } | ||
472 | |||
473 | /** | ||
474 | * slow_work_cancel - Cancel a slow work item | ||
475 | * @work: The work item to cancel | ||
476 | * | ||
477 | * This function will cancel a previously enqueued work item. If we cannot | ||
478 | * cancel the work item, it is guarenteed to have run when this function | ||
479 | * returns. | ||
480 | */ | ||
481 | void slow_work_cancel(struct slow_work *work) | ||
482 | { | ||
483 | bool wait = true, put = false; | ||
484 | |||
485 | set_bit(SLOW_WORK_CANCELLING, &work->flags); | ||
486 | smp_mb(); | ||
487 | |||
488 | /* if the work item is a delayed work item with an active timer, we | ||
489 | * need to wait for the timer to finish _before_ getting the spinlock, | ||
490 | * lest we deadlock against the timer routine | ||
491 | * | ||
492 | * the timer routine will leave DELAYED set if it notices the | ||
493 | * CANCELLING flag in time | ||
494 | */ | ||
495 | if (test_bit(SLOW_WORK_DELAYED, &work->flags)) { | ||
496 | struct delayed_slow_work *dwork = | ||
497 | container_of(work, struct delayed_slow_work, work); | ||
498 | del_timer_sync(&dwork->timer); | ||
499 | } | ||
500 | |||
501 | spin_lock_irq(&slow_work_queue_lock); | ||
502 | |||
503 | if (test_bit(SLOW_WORK_DELAYED, &work->flags)) { | ||
504 | /* the timer routine aborted or never happened, so we are left | ||
505 | * holding the timer's reference on the item and should just | ||
506 | * drop the pending flag and wait for any ongoing execution to | ||
507 | * finish */ | ||
508 | struct delayed_slow_work *dwork = | ||
509 | container_of(work, struct delayed_slow_work, work); | ||
510 | |||
511 | BUG_ON(timer_pending(&dwork->timer)); | ||
512 | BUG_ON(!list_empty(&work->link)); | ||
513 | |||
514 | clear_bit(SLOW_WORK_DELAYED, &work->flags); | ||
515 | put = true; | ||
516 | clear_bit(SLOW_WORK_PENDING, &work->flags); | ||
517 | |||
518 | } else if (test_bit(SLOW_WORK_PENDING, &work->flags) && | ||
519 | !list_empty(&work->link)) { | ||
520 | /* the link in the pending queue holds a reference on the item | ||
521 | * that we will need to release */ | ||
522 | list_del_init(&work->link); | ||
523 | wait = false; | ||
524 | put = true; | ||
525 | clear_bit(SLOW_WORK_PENDING, &work->flags); | ||
526 | |||
527 | } else if (test_and_clear_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags)) { | ||
528 | /* the executor is holding our only reference on the item, so | ||
529 | * we merely need to wait for it to finish executing */ | ||
530 | clear_bit(SLOW_WORK_PENDING, &work->flags); | ||
531 | } | ||
532 | |||
533 | spin_unlock_irq(&slow_work_queue_lock); | ||
534 | |||
535 | /* the EXECUTING flag is set by the executor whilst the spinlock is set | ||
536 | * and before the item is dequeued - so assuming the above doesn't | ||
537 | * actually dequeue it, simply waiting for the EXECUTING flag to be | ||
538 | * released here should be sufficient */ | ||
539 | if (wait) | ||
540 | wait_on_bit(&work->flags, SLOW_WORK_EXECUTING, slow_work_wait, | ||
541 | TASK_UNINTERRUPTIBLE); | ||
542 | |||
543 | clear_bit(SLOW_WORK_CANCELLING, &work->flags); | ||
544 | if (put) | ||
545 | slow_work_put_ref(work); | ||
546 | } | ||
547 | EXPORT_SYMBOL(slow_work_cancel); | ||
548 | |||
549 | /* | ||
550 | * Handle expiry of the delay timer, indicating that a delayed slow work item | ||
551 | * should now be queued if not cancelled | ||
552 | */ | ||
553 | static void delayed_slow_work_timer(unsigned long data) | ||
554 | { | ||
555 | wait_queue_head_t *wfo_wq; | ||
556 | struct list_head *queue; | ||
557 | struct slow_work *work = (struct slow_work *) data; | ||
558 | unsigned long flags; | ||
559 | bool queued = false, put = false, first = false; | ||
560 | |||
561 | if (test_bit(SLOW_WORK_VERY_SLOW, &work->flags)) { | ||
562 | wfo_wq = &vslow_work_queue_waits_for_occupation; | ||
563 | queue = &vslow_work_queue; | ||
564 | } else { | ||
565 | wfo_wq = &slow_work_queue_waits_for_occupation; | ||
566 | queue = &slow_work_queue; | ||
567 | } | ||
568 | |||
569 | spin_lock_irqsave(&slow_work_queue_lock, flags); | ||
570 | if (likely(!test_bit(SLOW_WORK_CANCELLING, &work->flags))) { | ||
571 | clear_bit(SLOW_WORK_DELAYED, &work->flags); | ||
572 | |||
573 | if (test_bit(SLOW_WORK_EXECUTING, &work->flags)) { | ||
574 | /* we discard the reference the timer was holding in | ||
575 | * favour of the one the executor holds */ | ||
576 | set_bit(SLOW_WORK_ENQ_DEFERRED, &work->flags); | ||
577 | put = true; | ||
578 | } else { | ||
579 | slow_work_mark_time(work); | ||
580 | list_add_tail(&work->link, queue); | ||
581 | queued = true; | ||
582 | if (work->link.prev == queue) | ||
583 | first = true; | ||
584 | } | ||
585 | } | ||
586 | |||
587 | spin_unlock_irqrestore(&slow_work_queue_lock, flags); | ||
588 | if (put) | ||
589 | slow_work_put_ref(work); | ||
590 | if (first) | ||
591 | wake_up(wfo_wq); | ||
592 | if (queued) | ||
593 | wake_up(&slow_work_thread_wq); | ||
594 | } | ||
595 | |||
596 | /** | ||
597 | * delayed_slow_work_enqueue - Schedule a delayed slow work item for processing | ||
598 | * @dwork: The delayed work item to queue | ||
599 | * @delay: When to start executing the work, in jiffies from now | ||
600 | * | ||
601 | * This is similar to slow_work_enqueue(), but it adds a delay before the work | ||
602 | * is actually queued for processing. | ||
603 | * | ||
604 | * The item can have delayed processing requested on it whilst it is being | ||
605 | * executed. The delay will begin immediately, and if it expires before the | ||
606 | * item finishes executing, the item will be placed back on the queue when it | ||
607 | * has done executing. | ||
608 | */ | ||
609 | int delayed_slow_work_enqueue(struct delayed_slow_work *dwork, | ||
610 | unsigned long delay) | ||
611 | { | ||
612 | struct slow_work *work = &dwork->work; | ||
613 | unsigned long flags; | ||
614 | int ret; | ||
615 | |||
616 | if (delay == 0) | ||
617 | return slow_work_enqueue(&dwork->work); | ||
618 | |||
619 | BUG_ON(slow_work_user_count <= 0); | ||
620 | BUG_ON(!work); | ||
621 | BUG_ON(!work->ops); | ||
622 | |||
623 | if (test_bit(SLOW_WORK_CANCELLING, &work->flags)) | ||
624 | return -ECANCELED; | ||
625 | |||
626 | if (!test_and_set_bit_lock(SLOW_WORK_PENDING, &work->flags)) { | ||
627 | spin_lock_irqsave(&slow_work_queue_lock, flags); | ||
628 | |||
629 | if (test_bit(SLOW_WORK_CANCELLING, &work->flags)) | ||
630 | goto cancelled; | ||
631 | |||
632 | /* the timer holds a reference whilst it is pending */ | ||
633 | ret = work->ops->get_ref(work); | ||
634 | if (ret < 0) | ||
635 | goto cant_get_ref; | ||
636 | |||
637 | if (test_and_set_bit(SLOW_WORK_DELAYED, &work->flags)) | ||
638 | BUG(); | ||
639 | dwork->timer.expires = jiffies + delay; | ||
640 | dwork->timer.data = (unsigned long) work; | ||
641 | dwork->timer.function = delayed_slow_work_timer; | ||
642 | add_timer(&dwork->timer); | ||
643 | |||
644 | spin_unlock_irqrestore(&slow_work_queue_lock, flags); | ||
645 | } | ||
646 | |||
647 | return 0; | ||
648 | |||
649 | cancelled: | ||
650 | ret = -ECANCELED; | ||
651 | cant_get_ref: | ||
652 | spin_unlock_irqrestore(&slow_work_queue_lock, flags); | ||
653 | return ret; | ||
654 | } | ||
655 | EXPORT_SYMBOL(delayed_slow_work_enqueue); | ||
656 | |||
321 | /* | 657 | /* |
322 | * Schedule a cull of the thread pool at some time in the near future | 658 | * Schedule a cull of the thread pool at some time in the near future |
323 | */ | 659 | */ |
@@ -368,13 +704,23 @@ static inline bool slow_work_available(int vsmax) | |||
368 | */ | 704 | */ |
369 | static int slow_work_thread(void *_data) | 705 | static int slow_work_thread(void *_data) |
370 | { | 706 | { |
371 | int vsmax; | 707 | int vsmax, id; |
372 | 708 | ||
373 | DEFINE_WAIT(wait); | 709 | DEFINE_WAIT(wait); |
374 | 710 | ||
375 | set_freezable(); | 711 | set_freezable(); |
376 | set_user_nice(current, -5); | 712 | set_user_nice(current, -5); |
377 | 713 | ||
714 | /* allocate ourselves an ID */ | ||
715 | spin_lock_irq(&slow_work_queue_lock); | ||
716 | id = find_first_zero_bit(slow_work_ids, SLOW_WORK_THREAD_LIMIT); | ||
717 | BUG_ON(id < 0 || id >= SLOW_WORK_THREAD_LIMIT); | ||
718 | __set_bit(id, slow_work_ids); | ||
719 | slow_work_set_thread_pid(id, current->pid); | ||
720 | spin_unlock_irq(&slow_work_queue_lock); | ||
721 | |||
722 | sprintf(current->comm, "kslowd%03u", id); | ||
723 | |||
378 | for (;;) { | 724 | for (;;) { |
379 | vsmax = vslow_work_proportion; | 725 | vsmax = vslow_work_proportion; |
380 | vsmax *= atomic_read(&slow_work_thread_count); | 726 | vsmax *= atomic_read(&slow_work_thread_count); |
@@ -395,7 +741,7 @@ static int slow_work_thread(void *_data) | |||
395 | vsmax *= atomic_read(&slow_work_thread_count); | 741 | vsmax *= atomic_read(&slow_work_thread_count); |
396 | vsmax /= 100; | 742 | vsmax /= 100; |
397 | 743 | ||
398 | if (slow_work_available(vsmax) && slow_work_execute()) { | 744 | if (slow_work_available(vsmax) && slow_work_execute(id)) { |
399 | cond_resched(); | 745 | cond_resched(); |
400 | if (list_empty(&slow_work_queue) && | 746 | if (list_empty(&slow_work_queue) && |
401 | list_empty(&vslow_work_queue) && | 747 | list_empty(&vslow_work_queue) && |
@@ -412,6 +758,11 @@ static int slow_work_thread(void *_data) | |||
412 | break; | 758 | break; |
413 | } | 759 | } |
414 | 760 | ||
761 | spin_lock_irq(&slow_work_queue_lock); | ||
762 | slow_work_set_thread_pid(id, 0); | ||
763 | __clear_bit(id, slow_work_ids); | ||
764 | spin_unlock_irq(&slow_work_queue_lock); | ||
765 | |||
415 | if (atomic_dec_and_test(&slow_work_thread_count)) | 766 | if (atomic_dec_and_test(&slow_work_thread_count)) |
416 | complete_and_exit(&slow_work_last_thread_exited, 0); | 767 | complete_and_exit(&slow_work_last_thread_exited, 0); |
417 | return 0; | 768 | return 0; |
@@ -427,21 +778,6 @@ static void slow_work_cull_timeout(unsigned long data) | |||
427 | } | 778 | } |
428 | 779 | ||
429 | /* | 780 | /* |
430 | * Get a reference on slow work thread starter | ||
431 | */ | ||
432 | static int slow_work_new_thread_get_ref(struct slow_work *work) | ||
433 | { | ||
434 | return 0; | ||
435 | } | ||
436 | |||
437 | /* | ||
438 | * Drop a reference on slow work thread starter | ||
439 | */ | ||
440 | static void slow_work_new_thread_put_ref(struct slow_work *work) | ||
441 | { | ||
442 | } | ||
443 | |||
444 | /* | ||
445 | * Start a new slow work thread | 781 | * Start a new slow work thread |
446 | */ | 782 | */ |
447 | static void slow_work_new_thread_execute(struct slow_work *work) | 783 | static void slow_work_new_thread_execute(struct slow_work *work) |
@@ -475,9 +811,11 @@ static void slow_work_new_thread_execute(struct slow_work *work) | |||
475 | } | 811 | } |
476 | 812 | ||
477 | static const struct slow_work_ops slow_work_new_thread_ops = { | 813 | static const struct slow_work_ops slow_work_new_thread_ops = { |
478 | .get_ref = slow_work_new_thread_get_ref, | 814 | .owner = THIS_MODULE, |
479 | .put_ref = slow_work_new_thread_put_ref, | ||
480 | .execute = slow_work_new_thread_execute, | 815 | .execute = slow_work_new_thread_execute, |
816 | #ifdef CONFIG_SLOW_WORK_PROC | ||
817 | .desc = slow_work_new_thread_desc, | ||
818 | #endif | ||
481 | }; | 819 | }; |
482 | 820 | ||
483 | /* | 821 | /* |
@@ -546,12 +884,13 @@ static int slow_work_max_threads_sysctl(struct ctl_table *table, int write, | |||
546 | 884 | ||
547 | /** | 885 | /** |
548 | * slow_work_register_user - Register a user of the facility | 886 | * slow_work_register_user - Register a user of the facility |
887 | * @module: The module about to make use of the facility | ||
549 | * | 888 | * |
550 | * Register a user of the facility, starting up the initial threads if there | 889 | * Register a user of the facility, starting up the initial threads if there |
551 | * aren't any other users at this point. This will return 0 if successful, or | 890 | * aren't any other users at this point. This will return 0 if successful, or |
552 | * an error if not. | 891 | * an error if not. |
553 | */ | 892 | */ |
554 | int slow_work_register_user(void) | 893 | int slow_work_register_user(struct module *module) |
555 | { | 894 | { |
556 | struct task_struct *p; | 895 | struct task_struct *p; |
557 | int loop; | 896 | int loop; |
@@ -598,14 +937,79 @@ error: | |||
598 | } | 937 | } |
599 | EXPORT_SYMBOL(slow_work_register_user); | 938 | EXPORT_SYMBOL(slow_work_register_user); |
600 | 939 | ||
940 | /* | ||
941 | * wait for all outstanding items from the calling module to complete | ||
942 | * - note that more items may be queued whilst we're waiting | ||
943 | */ | ||
944 | static void slow_work_wait_for_items(struct module *module) | ||
945 | { | ||
946 | DECLARE_WAITQUEUE(myself, current); | ||
947 | struct slow_work *work; | ||
948 | int loop; | ||
949 | |||
950 | mutex_lock(&slow_work_unreg_sync_lock); | ||
951 | add_wait_queue(&slow_work_unreg_wq, &myself); | ||
952 | |||
953 | for (;;) { | ||
954 | spin_lock_irq(&slow_work_queue_lock); | ||
955 | |||
956 | /* first of all, we wait for the last queued item in each list | ||
957 | * to be processed */ | ||
958 | list_for_each_entry_reverse(work, &vslow_work_queue, link) { | ||
959 | if (work->owner == module) { | ||
960 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
961 | slow_work_unreg_work_item = work; | ||
962 | goto do_wait; | ||
963 | } | ||
964 | } | ||
965 | list_for_each_entry_reverse(work, &slow_work_queue, link) { | ||
966 | if (work->owner == module) { | ||
967 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
968 | slow_work_unreg_work_item = work; | ||
969 | goto do_wait; | ||
970 | } | ||
971 | } | ||
972 | |||
973 | /* then we wait for the items being processed to finish */ | ||
974 | slow_work_unreg_module = module; | ||
975 | smp_mb(); | ||
976 | for (loop = 0; loop < SLOW_WORK_THREAD_LIMIT; loop++) { | ||
977 | if (slow_work_thread_processing[loop] == module) | ||
978 | goto do_wait; | ||
979 | } | ||
980 | spin_unlock_irq(&slow_work_queue_lock); | ||
981 | break; /* okay, we're done */ | ||
982 | |||
983 | do_wait: | ||
984 | spin_unlock_irq(&slow_work_queue_lock); | ||
985 | schedule(); | ||
986 | slow_work_unreg_work_item = NULL; | ||
987 | slow_work_unreg_module = NULL; | ||
988 | } | ||
989 | |||
990 | remove_wait_queue(&slow_work_unreg_wq, &myself); | ||
991 | mutex_unlock(&slow_work_unreg_sync_lock); | ||
992 | } | ||
993 | |||
601 | /** | 994 | /** |
602 | * slow_work_unregister_user - Unregister a user of the facility | 995 | * slow_work_unregister_user - Unregister a user of the facility |
996 | * @module: The module whose items should be cleared | ||
603 | * | 997 | * |
604 | * Unregister a user of the facility, killing all the threads if this was the | 998 | * Unregister a user of the facility, killing all the threads if this was the |
605 | * last one. | 999 | * last one. |
1000 | * | ||
1001 | * This waits for all the work items belonging to the nominated module to go | ||
1002 | * away before proceeding. | ||
606 | */ | 1003 | */ |
607 | void slow_work_unregister_user(void) | 1004 | void slow_work_unregister_user(struct module *module) |
608 | { | 1005 | { |
1006 | /* first of all, wait for all outstanding items from the calling module | ||
1007 | * to complete */ | ||
1008 | if (module) | ||
1009 | slow_work_wait_for_items(module); | ||
1010 | |||
1011 | /* then we can actually go about shutting down the facility if need | ||
1012 | * be */ | ||
609 | mutex_lock(&slow_work_user_lock); | 1013 | mutex_lock(&slow_work_user_lock); |
610 | 1014 | ||
611 | BUG_ON(slow_work_user_count <= 0); | 1015 | BUG_ON(slow_work_user_count <= 0); |
@@ -639,6 +1043,10 @@ static int __init init_slow_work(void) | |||
639 | if (slow_work_max_max_threads < nr_cpus * 2) | 1043 | if (slow_work_max_max_threads < nr_cpus * 2) |
640 | slow_work_max_max_threads = nr_cpus * 2; | 1044 | slow_work_max_max_threads = nr_cpus * 2; |
641 | #endif | 1045 | #endif |
1046 | #ifdef CONFIG_SLOW_WORK_PROC | ||
1047 | proc_create("slow_work_rq", S_IFREG | 0400, NULL, | ||
1048 | &slow_work_runqueue_fops); | ||
1049 | #endif | ||
642 | return 0; | 1050 | return 0; |
643 | } | 1051 | } |
644 | 1052 | ||
diff --git a/kernel/slow-work.h b/kernel/slow-work.h new file mode 100644 index 000000000000..3c2f007f3ad6 --- /dev/null +++ b/kernel/slow-work.h | |||
@@ -0,0 +1,72 @@ | |||
1 | /* Slow work private definitions | ||
2 | * | ||
3 | * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved. | ||
4 | * Written by David Howells (dhowells@redhat.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public Licence | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the Licence, or (at your option) any later version. | ||
10 | */ | ||
11 | |||
12 | #define SLOW_WORK_CULL_TIMEOUT (5 * HZ) /* cull threads 5s after running out of | ||
13 | * things to do */ | ||
14 | #define SLOW_WORK_OOM_TIMEOUT (5 * HZ) /* can't start new threads for 5s after | ||
15 | * OOM */ | ||
16 | |||
17 | #define SLOW_WORK_THREAD_LIMIT 255 /* abs maximum number of slow-work threads */ | ||
18 | |||
19 | /* | ||
20 | * slow-work.c | ||
21 | */ | ||
22 | #ifdef CONFIG_SLOW_WORK_PROC | ||
23 | extern struct slow_work *slow_work_execs[]; | ||
24 | extern pid_t slow_work_pids[]; | ||
25 | extern rwlock_t slow_work_execs_lock; | ||
26 | #endif | ||
27 | |||
28 | extern struct list_head slow_work_queue; | ||
29 | extern struct list_head vslow_work_queue; | ||
30 | extern spinlock_t slow_work_queue_lock; | ||
31 | |||
32 | /* | ||
33 | * slow-work-proc.c | ||
34 | */ | ||
35 | #ifdef CONFIG_SLOW_WORK_PROC | ||
36 | extern const struct file_operations slow_work_runqueue_fops; | ||
37 | |||
38 | extern void slow_work_new_thread_desc(struct slow_work *, struct seq_file *); | ||
39 | #endif | ||
40 | |||
41 | /* | ||
42 | * Helper functions | ||
43 | */ | ||
44 | static inline void slow_work_set_thread_pid(int id, pid_t pid) | ||
45 | { | ||
46 | #ifdef CONFIG_SLOW_WORK_PROC | ||
47 | slow_work_pids[id] = pid; | ||
48 | #endif | ||
49 | } | ||
50 | |||
51 | static inline void slow_work_mark_time(struct slow_work *work) | ||
52 | { | ||
53 | #ifdef CONFIG_SLOW_WORK_PROC | ||
54 | work->mark = CURRENT_TIME; | ||
55 | #endif | ||
56 | } | ||
57 | |||
58 | static inline void slow_work_begin_exec(int id, struct slow_work *work) | ||
59 | { | ||
60 | #ifdef CONFIG_SLOW_WORK_PROC | ||
61 | slow_work_execs[id] = work; | ||
62 | #endif | ||
63 | } | ||
64 | |||
65 | static inline void slow_work_end_exec(int id, struct slow_work *work) | ||
66 | { | ||
67 | #ifdef CONFIG_SLOW_WORK_PROC | ||
68 | write_lock(&slow_work_execs_lock); | ||
69 | slow_work_execs[id] = NULL; | ||
70 | write_unlock(&slow_work_execs_lock); | ||
71 | #endif | ||
72 | } | ||
diff --git a/lib/radix-tree.c b/lib/radix-tree.c index 23abbd93cae1..92cdd9936e3d 100644 --- a/lib/radix-tree.c +++ b/lib/radix-tree.c | |||
@@ -200,6 +200,9 @@ radix_tree_node_free(struct radix_tree_node *node) | |||
200 | * ensure that the addition of a single element in the tree cannot fail. On | 200 | * ensure that the addition of a single element in the tree cannot fail. On |
201 | * success, return zero, with preemption disabled. On error, return -ENOMEM | 201 | * success, return zero, with preemption disabled. On error, return -ENOMEM |
202 | * with preemption not disabled. | 202 | * with preemption not disabled. |
203 | * | ||
204 | * To make use of this facility, the radix tree must be initialised without | ||
205 | * __GFP_WAIT being passed to INIT_RADIX_TREE(). | ||
203 | */ | 206 | */ |
204 | int radix_tree_preload(gfp_t gfp_mask) | 207 | int radix_tree_preload(gfp_t gfp_mask) |
205 | { | 208 | { |
@@ -543,7 +546,6 @@ out: | |||
543 | } | 546 | } |
544 | EXPORT_SYMBOL(radix_tree_tag_clear); | 547 | EXPORT_SYMBOL(radix_tree_tag_clear); |
545 | 548 | ||
546 | #ifndef __KERNEL__ /* Only the test harness uses this at present */ | ||
547 | /** | 549 | /** |
548 | * radix_tree_tag_get - get a tag on a radix tree node | 550 | * radix_tree_tag_get - get a tag on a radix tree node |
549 | * @root: radix tree root | 551 | * @root: radix tree root |
@@ -606,7 +608,6 @@ int radix_tree_tag_get(struct radix_tree_root *root, | |||
606 | } | 608 | } |
607 | } | 609 | } |
608 | EXPORT_SYMBOL(radix_tree_tag_get); | 610 | EXPORT_SYMBOL(radix_tree_tag_get); |
609 | #endif | ||
610 | 611 | ||
611 | /** | 612 | /** |
612 | * radix_tree_next_hole - find the next hole (not-present entry) | 613 | * radix_tree_next_hole - find the next hole (not-present entry) |
diff --git a/mm/backing-dev.c b/mm/backing-dev.c index 11aee09dd2a6..67a33a5a1a93 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c | |||
@@ -604,10 +604,14 @@ static void bdi_wb_shutdown(struct backing_dev_info *bdi) | |||
604 | 604 | ||
605 | /* | 605 | /* |
606 | * Finally, kill the kernel threads. We don't need to be RCU | 606 | * Finally, kill the kernel threads. We don't need to be RCU |
607 | * safe anymore, since the bdi is gone from visibility. | 607 | * safe anymore, since the bdi is gone from visibility. Force |
608 | * unfreeze of the thread before calling kthread_stop(), otherwise | ||
609 | * it would never exet if it is currently stuck in the refrigerator. | ||
608 | */ | 610 | */ |
609 | list_for_each_entry(wb, &bdi->wb_list, list) | 611 | list_for_each_entry(wb, &bdi->wb_list, list) { |
612 | wb->task->flags &= ~PF_FROZEN; | ||
610 | kthread_stop(wb->task); | 613 | kthread_stop(wb->task); |
614 | } | ||
611 | } | 615 | } |
612 | 616 | ||
613 | /* | 617 | /* |
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 6eb8d47cbf3a..6e79e96cb4f2 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -363,6 +363,7 @@ struct pktgen_dev { | |||
363 | * device name (not when the inject is | 363 | * device name (not when the inject is |
364 | * started as it used to do.) | 364 | * started as it used to do.) |
365 | */ | 365 | */ |
366 | char odevname[32]; | ||
366 | struct flow_state *flows; | 367 | struct flow_state *flows; |
367 | unsigned cflows; /* Concurrent flows (config) */ | 368 | unsigned cflows; /* Concurrent flows (config) */ |
368 | unsigned lflow; /* Flow length (config) */ | 369 | unsigned lflow; /* Flow length (config) */ |
@@ -426,7 +427,7 @@ static const char version[] = | |||
426 | static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *i); | 427 | static int pktgen_remove_device(struct pktgen_thread *t, struct pktgen_dev *i); |
427 | static int pktgen_add_device(struct pktgen_thread *t, const char *ifname); | 428 | static int pktgen_add_device(struct pktgen_thread *t, const char *ifname); |
428 | static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, | 429 | static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, |
429 | const char *ifname); | 430 | const char *ifname, bool exact); |
430 | static int pktgen_device_event(struct notifier_block *, unsigned long, void *); | 431 | static int pktgen_device_event(struct notifier_block *, unsigned long, void *); |
431 | static void pktgen_run_all_threads(void); | 432 | static void pktgen_run_all_threads(void); |
432 | static void pktgen_reset_all_threads(void); | 433 | static void pktgen_reset_all_threads(void); |
@@ -528,7 +529,7 @@ static int pktgen_if_show(struct seq_file *seq, void *v) | |||
528 | seq_printf(seq, | 529 | seq_printf(seq, |
529 | " frags: %d delay: %llu clone_skb: %d ifname: %s\n", | 530 | " frags: %d delay: %llu clone_skb: %d ifname: %s\n", |
530 | pkt_dev->nfrags, (unsigned long long) pkt_dev->delay, | 531 | pkt_dev->nfrags, (unsigned long long) pkt_dev->delay, |
531 | pkt_dev->clone_skb, pkt_dev->odev->name); | 532 | pkt_dev->clone_skb, pkt_dev->odevname); |
532 | 533 | ||
533 | seq_printf(seq, " flows: %u flowlen: %u\n", pkt_dev->cflows, | 534 | seq_printf(seq, " flows: %u flowlen: %u\n", pkt_dev->cflows, |
534 | pkt_dev->lflow); | 535 | pkt_dev->lflow); |
@@ -1688,13 +1689,13 @@ static int pktgen_thread_show(struct seq_file *seq, void *v) | |||
1688 | if_lock(t); | 1689 | if_lock(t); |
1689 | list_for_each_entry(pkt_dev, &t->if_list, list) | 1690 | list_for_each_entry(pkt_dev, &t->if_list, list) |
1690 | if (pkt_dev->running) | 1691 | if (pkt_dev->running) |
1691 | seq_printf(seq, "%s ", pkt_dev->odev->name); | 1692 | seq_printf(seq, "%s ", pkt_dev->odevname); |
1692 | 1693 | ||
1693 | seq_printf(seq, "\nStopped: "); | 1694 | seq_printf(seq, "\nStopped: "); |
1694 | 1695 | ||
1695 | list_for_each_entry(pkt_dev, &t->if_list, list) | 1696 | list_for_each_entry(pkt_dev, &t->if_list, list) |
1696 | if (!pkt_dev->running) | 1697 | if (!pkt_dev->running) |
1697 | seq_printf(seq, "%s ", pkt_dev->odev->name); | 1698 | seq_printf(seq, "%s ", pkt_dev->odevname); |
1698 | 1699 | ||
1699 | if (t->result[0]) | 1700 | if (t->result[0]) |
1700 | seq_printf(seq, "\nResult: %s\n", t->result); | 1701 | seq_printf(seq, "\nResult: %s\n", t->result); |
@@ -1817,9 +1818,10 @@ static struct pktgen_dev *__pktgen_NN_threads(const char *ifname, int remove) | |||
1817 | { | 1818 | { |
1818 | struct pktgen_thread *t; | 1819 | struct pktgen_thread *t; |
1819 | struct pktgen_dev *pkt_dev = NULL; | 1820 | struct pktgen_dev *pkt_dev = NULL; |
1821 | bool exact = (remove == FIND); | ||
1820 | 1822 | ||
1821 | list_for_each_entry(t, &pktgen_threads, th_list) { | 1823 | list_for_each_entry(t, &pktgen_threads, th_list) { |
1822 | pkt_dev = pktgen_find_dev(t, ifname); | 1824 | pkt_dev = pktgen_find_dev(t, ifname, exact); |
1823 | if (pkt_dev) { | 1825 | if (pkt_dev) { |
1824 | if (remove) { | 1826 | if (remove) { |
1825 | if_lock(t); | 1827 | if_lock(t); |
@@ -1994,7 +1996,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) | |||
1994 | "queue_map_min (zero-based) (%d) exceeds valid range " | 1996 | "queue_map_min (zero-based) (%d) exceeds valid range " |
1995 | "[0 - %d] for (%d) queues on %s, resetting\n", | 1997 | "[0 - %d] for (%d) queues on %s, resetting\n", |
1996 | pkt_dev->queue_map_min, (ntxq ?: 1) - 1, ntxq, | 1998 | pkt_dev->queue_map_min, (ntxq ?: 1) - 1, ntxq, |
1997 | pkt_dev->odev->name); | 1999 | pkt_dev->odevname); |
1998 | pkt_dev->queue_map_min = ntxq - 1; | 2000 | pkt_dev->queue_map_min = ntxq - 1; |
1999 | } | 2001 | } |
2000 | if (pkt_dev->queue_map_max >= ntxq) { | 2002 | if (pkt_dev->queue_map_max >= ntxq) { |
@@ -2002,7 +2004,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) | |||
2002 | "queue_map_max (zero-based) (%d) exceeds valid range " | 2004 | "queue_map_max (zero-based) (%d) exceeds valid range " |
2003 | "[0 - %d] for (%d) queues on %s, resetting\n", | 2005 | "[0 - %d] for (%d) queues on %s, resetting\n", |
2004 | pkt_dev->queue_map_max, (ntxq ?: 1) - 1, ntxq, | 2006 | pkt_dev->queue_map_max, (ntxq ?: 1) - 1, ntxq, |
2005 | pkt_dev->odev->name); | 2007 | pkt_dev->odevname); |
2006 | pkt_dev->queue_map_max = ntxq - 1; | 2008 | pkt_dev->queue_map_max = ntxq - 1; |
2007 | } | 2009 | } |
2008 | 2010 | ||
@@ -3262,7 +3264,7 @@ static int pktgen_stop_device(struct pktgen_dev *pkt_dev) | |||
3262 | 3264 | ||
3263 | if (!pkt_dev->running) { | 3265 | if (!pkt_dev->running) { |
3264 | printk(KERN_WARNING "pktgen: interface: %s is already " | 3266 | printk(KERN_WARNING "pktgen: interface: %s is already " |
3265 | "stopped\n", pkt_dev->odev->name); | 3267 | "stopped\n", pkt_dev->odevname); |
3266 | return -EINVAL; | 3268 | return -EINVAL; |
3267 | } | 3269 | } |
3268 | 3270 | ||
@@ -3464,7 +3466,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev) | |||
3464 | default: /* Drivers are not supposed to return other values! */ | 3466 | default: /* Drivers are not supposed to return other values! */ |
3465 | if (net_ratelimit()) | 3467 | if (net_ratelimit()) |
3466 | pr_info("pktgen: %s xmit error: %d\n", | 3468 | pr_info("pktgen: %s xmit error: %d\n", |
3467 | odev->name, ret); | 3469 | pkt_dev->odevname, ret); |
3468 | pkt_dev->errors++; | 3470 | pkt_dev->errors++; |
3469 | /* fallthru */ | 3471 | /* fallthru */ |
3470 | case NETDEV_TX_LOCKED: | 3472 | case NETDEV_TX_LOCKED: |
@@ -3566,13 +3568,18 @@ static int pktgen_thread_worker(void *arg) | |||
3566 | } | 3568 | } |
3567 | 3569 | ||
3568 | static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, | 3570 | static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t, |
3569 | const char *ifname) | 3571 | const char *ifname, bool exact) |
3570 | { | 3572 | { |
3571 | struct pktgen_dev *p, *pkt_dev = NULL; | 3573 | struct pktgen_dev *p, *pkt_dev = NULL; |
3572 | if_lock(t); | 3574 | size_t len = strlen(ifname); |
3573 | 3575 | ||
3576 | if_lock(t); | ||
3574 | list_for_each_entry(p, &t->if_list, list) | 3577 | list_for_each_entry(p, &t->if_list, list) |
3575 | if (strncmp(p->odev->name, ifname, IFNAMSIZ) == 0) { | 3578 | if (strncmp(p->odevname, ifname, len) == 0) { |
3579 | if (p->odevname[len]) { | ||
3580 | if (exact || p->odevname[len] != '@') | ||
3581 | continue; | ||
3582 | } | ||
3576 | pkt_dev = p; | 3583 | pkt_dev = p; |
3577 | break; | 3584 | break; |
3578 | } | 3585 | } |
@@ -3628,6 +3635,7 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname) | |||
3628 | if (!pkt_dev) | 3635 | if (!pkt_dev) |
3629 | return -ENOMEM; | 3636 | return -ENOMEM; |
3630 | 3637 | ||
3638 | strcpy(pkt_dev->odevname, ifname); | ||
3631 | pkt_dev->flows = vmalloc(MAX_CFLOWS * sizeof(struct flow_state)); | 3639 | pkt_dev->flows = vmalloc(MAX_CFLOWS * sizeof(struct flow_state)); |
3632 | if (pkt_dev->flows == NULL) { | 3640 | if (pkt_dev->flows == NULL) { |
3633 | kfree(pkt_dev); | 3641 | kfree(pkt_dev); |
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 575f9bd51ccd..d3fe10be7219 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
@@ -563,7 +563,7 @@ out_oversize: | |||
563 | printk(KERN_INFO "Oversized IP packet from %pI4.\n", | 563 | printk(KERN_INFO "Oversized IP packet from %pI4.\n", |
564 | &qp->saddr); | 564 | &qp->saddr); |
565 | out_fail: | 565 | out_fail: |
566 | IP_INC_STATS_BH(dev_net(dev), IPSTATS_MIB_REASMFAILS); | 566 | IP_INC_STATS_BH(net, IPSTATS_MIB_REASMFAILS); |
567 | return err; | 567 | return err; |
568 | } | 568 | } |
569 | 569 | ||
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index bc064d7933ff..ce8e0e772bab 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -85,10 +85,6 @@ void ieee80211_sta_stop_rx_ba_session(struct ieee80211_sub_if_data *sdata, u8 *r | |||
85 | struct ieee80211_local *local = sdata->local; | 85 | struct ieee80211_local *local = sdata->local; |
86 | struct sta_info *sta; | 86 | struct sta_info *sta; |
87 | 87 | ||
88 | /* stop HW Rx aggregation. ampdu_action existence | ||
89 | * already verified in session init so we add the BUG_ON */ | ||
90 | BUG_ON(!local->ops->ampdu_action); | ||
91 | |||
92 | rcu_read_lock(); | 88 | rcu_read_lock(); |
93 | 89 | ||
94 | sta = sta_info_get(local, ra); | 90 | sta = sta_info_get(local, ra); |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index b09948ceec4a..89e238b001de 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -123,13 +123,18 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1 | |||
123 | ieee80211_tx_skb(sdata, skb, 0); | 123 | ieee80211_tx_skb(sdata, skb, 0); |
124 | } | 124 | } |
125 | 125 | ||
126 | static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | 126 | int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, |
127 | enum ieee80211_back_parties initiator) | 127 | enum ieee80211_back_parties initiator) |
128 | { | 128 | { |
129 | struct ieee80211_local *local = sta->local; | 129 | struct ieee80211_local *local = sta->local; |
130 | int ret; | 130 | int ret; |
131 | u8 *state; | 131 | u8 *state; |
132 | 132 | ||
133 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
134 | printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n", | ||
135 | sta->sta.addr, tid); | ||
136 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
137 | |||
133 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 138 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
134 | 139 | ||
135 | if (*state == HT_AGG_STATE_OPERATIONAL) | 140 | if (*state == HT_AGG_STATE_OPERATIONAL) |
@@ -143,7 +148,6 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
143 | 148 | ||
144 | /* HW shall not deny going back to legacy */ | 149 | /* HW shall not deny going back to legacy */ |
145 | if (WARN_ON(ret)) { | 150 | if (WARN_ON(ret)) { |
146 | *state = HT_AGG_STATE_OPERATIONAL; | ||
147 | /* | 151 | /* |
148 | * We may have pending packets get stuck in this case... | 152 | * We may have pending packets get stuck in this case... |
149 | * Not bothering with a workaround for now. | 153 | * Not bothering with a workaround for now. |
@@ -173,12 +177,14 @@ static void sta_addba_resp_timer_expired(unsigned long data) | |||
173 | 177 | ||
174 | /* check if the TID waits for addBA response */ | 178 | /* check if the TID waits for addBA response */ |
175 | spin_lock_bh(&sta->lock); | 179 | spin_lock_bh(&sta->lock); |
176 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) { | 180 | if ((*state & (HT_ADDBA_REQUESTED_MSK | HT_ADDBA_RECEIVED_MSK)) != |
181 | HT_ADDBA_REQUESTED_MSK) { | ||
177 | spin_unlock_bh(&sta->lock); | 182 | spin_unlock_bh(&sta->lock); |
178 | *state = HT_AGG_STATE_IDLE; | 183 | *state = HT_AGG_STATE_IDLE; |
179 | #ifdef CONFIG_MAC80211_HT_DEBUG | 184 | #ifdef CONFIG_MAC80211_HT_DEBUG |
180 | printk(KERN_DEBUG "timer expired on tid %d but we are not " | 185 | printk(KERN_DEBUG "timer expired on tid %d but we are not " |
181 | "expecting addBA response there", tid); | 186 | "(or no longer) expecting addBA response there", |
187 | tid); | ||
182 | #endif | 188 | #endif |
183 | return; | 189 | return; |
184 | } | 190 | } |
@@ -523,11 +529,6 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
523 | goto unlock; | 529 | goto unlock; |
524 | } | 530 | } |
525 | 531 | ||
526 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
527 | printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n", | ||
528 | sta->sta.addr, tid); | ||
529 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
530 | |||
531 | ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator); | 532 | ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator); |
532 | 533 | ||
533 | unlock: | 534 | unlock: |
@@ -543,7 +544,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_hw *hw, | |||
543 | struct sta_info *sta; | 544 | struct sta_info *sta; |
544 | int ret = 0; | 545 | int ret = 0; |
545 | 546 | ||
546 | if (WARN_ON(!local->ops->ampdu_action)) | 547 | if (!local->ops->ampdu_action) |
547 | return -EINVAL; | 548 | return -EINVAL; |
548 | 549 | ||
549 | if (tid >= STA_TID_NUM) | 550 | if (tid >= STA_TID_NUM) |
@@ -666,21 +667,21 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
666 | 667 | ||
667 | state = &sta->ampdu_mlme.tid_state_tx[tid]; | 668 | state = &sta->ampdu_mlme.tid_state_tx[tid]; |
668 | 669 | ||
669 | del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | ||
670 | |||
671 | spin_lock_bh(&sta->lock); | 670 | spin_lock_bh(&sta->lock); |
672 | 671 | ||
673 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) | 672 | if (!(*state & HT_ADDBA_REQUESTED_MSK)) |
674 | goto timer_still_needed; | 673 | goto out; |
675 | 674 | ||
676 | if (mgmt->u.action.u.addba_resp.dialog_token != | 675 | if (mgmt->u.action.u.addba_resp.dialog_token != |
677 | sta->ampdu_mlme.tid_tx[tid]->dialog_token) { | 676 | sta->ampdu_mlme.tid_tx[tid]->dialog_token) { |
678 | #ifdef CONFIG_MAC80211_HT_DEBUG | 677 | #ifdef CONFIG_MAC80211_HT_DEBUG |
679 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); | 678 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); |
680 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 679 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
681 | goto timer_still_needed; | 680 | goto out; |
682 | } | 681 | } |
683 | 682 | ||
683 | del_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | ||
684 | |||
684 | #ifdef CONFIG_MAC80211_HT_DEBUG | 685 | #ifdef CONFIG_MAC80211_HT_DEBUG |
685 | printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); | 686 | printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid); |
686 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | 687 | #endif /* CONFIG_MAC80211_HT_DEBUG */ |
@@ -699,10 +700,6 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
699 | ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); | 700 | ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR); |
700 | } | 701 | } |
701 | 702 | ||
702 | goto out; | ||
703 | |||
704 | timer_still_needed: | ||
705 | add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer); | ||
706 | out: | 703 | out: |
707 | spin_unlock_bh(&sta->lock); | 704 | spin_unlock_bh(&sta->lock); |
708 | } | 705 | } |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 48ef1a282b91..cdc58e61d921 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -141,7 +141,6 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | |||
141 | struct sta_info *sta, | 141 | struct sta_info *sta, |
142 | struct ieee80211_mgmt *mgmt, size_t len) | 142 | struct ieee80211_mgmt *mgmt, size_t len) |
143 | { | 143 | { |
144 | struct ieee80211_local *local = sdata->local; | ||
145 | u16 tid, params; | 144 | u16 tid, params; |
146 | u16 initiator; | 145 | u16 initiator; |
147 | 146 | ||
@@ -161,10 +160,9 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | |||
161 | WLAN_BACK_INITIATOR, 0); | 160 | WLAN_BACK_INITIATOR, 0); |
162 | else { /* WLAN_BACK_RECIPIENT */ | 161 | else { /* WLAN_BACK_RECIPIENT */ |
163 | spin_lock_bh(&sta->lock); | 162 | spin_lock_bh(&sta->lock); |
164 | sta->ampdu_mlme.tid_state_tx[tid] = | 163 | if (sta->ampdu_mlme.tid_state_tx[tid] & HT_ADDBA_REQUESTED_MSK) |
165 | HT_AGG_STATE_OPERATIONAL; | 164 | ___ieee80211_stop_tx_ba_session(sta, tid, |
165 | WLAN_BACK_RECIPIENT); | ||
166 | spin_unlock_bh(&sta->lock); | 166 | spin_unlock_bh(&sta->lock); |
167 | ieee80211_stop_tx_ba_session(&local->hw, sta->sta.addr, tid, | ||
168 | WLAN_BACK_RECIPIENT); | ||
169 | } | 167 | } |
170 | } | 168 | } |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 588005c84a6d..10d316e455de 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -662,6 +662,14 @@ struct ieee80211_local { | |||
662 | bool suspended; | 662 | bool suspended; |
663 | 663 | ||
664 | /* | 664 | /* |
665 | * Resuming is true while suspended, but when we're reprogramming the | ||
666 | * hardware -- at that time it's allowed to use ieee80211_queue_work() | ||
667 | * again even though some other parts of the stack are still suspended | ||
668 | * and we still drop received frames to avoid waking the stack. | ||
669 | */ | ||
670 | bool resuming; | ||
671 | |||
672 | /* | ||
665 | * quiescing is true during the suspend process _only_ to | 673 | * quiescing is true during the suspend process _only_ to |
666 | * ease timer cancelling etc. | 674 | * ease timer cancelling etc. |
667 | */ | 675 | */ |
@@ -1083,6 +1091,8 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
1083 | 1091 | ||
1084 | int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | 1092 | int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, |
1085 | enum ieee80211_back_parties initiator); | 1093 | enum ieee80211_back_parties initiator); |
1094 | int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | ||
1095 | enum ieee80211_back_parties initiator); | ||
1086 | 1096 | ||
1087 | /* Spectrum management */ | 1097 | /* Spectrum management */ |
1088 | void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, | 1098 | void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index aeb65b3d2295..e6c08da8da26 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -520,9 +520,9 @@ EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); | |||
520 | */ | 520 | */ |
521 | static bool ieee80211_can_queue_work(struct ieee80211_local *local) | 521 | static bool ieee80211_can_queue_work(struct ieee80211_local *local) |
522 | { | 522 | { |
523 | if (WARN(local->suspended, "queueing ieee80211 work while " | 523 | if (WARN(local->suspended && !local->resuming, |
524 | "going to suspend\n")) | 524 | "queueing ieee80211 work while going to suspend\n")) |
525 | return false; | 525 | return false; |
526 | 526 | ||
527 | return true; | 527 | return true; |
528 | } | 528 | } |
@@ -1025,13 +1025,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1025 | struct sta_info *sta; | 1025 | struct sta_info *sta; |
1026 | unsigned long flags; | 1026 | unsigned long flags; |
1027 | int res; | 1027 | int res; |
1028 | bool from_suspend = local->suspended; | ||
1029 | 1028 | ||
1030 | /* | 1029 | if (local->suspended) |
1031 | * We're going to start the hardware, at that point | 1030 | local->resuming = true; |
1032 | * we are no longer suspended and can RX frames. | ||
1033 | */ | ||
1034 | local->suspended = false; | ||
1035 | 1031 | ||
1036 | /* restart hardware */ | 1032 | /* restart hardware */ |
1037 | if (local->open_count) { | 1033 | if (local->open_count) { |
@@ -1129,11 +1125,14 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1129 | * If this is for hw restart things are still running. | 1125 | * If this is for hw restart things are still running. |
1130 | * We may want to change that later, however. | 1126 | * We may want to change that later, however. |
1131 | */ | 1127 | */ |
1132 | if (!from_suspend) | 1128 | if (!local->suspended) |
1133 | return 0; | 1129 | return 0; |
1134 | 1130 | ||
1135 | #ifdef CONFIG_PM | 1131 | #ifdef CONFIG_PM |
1132 | /* first set suspended false, then resuming */ | ||
1136 | local->suspended = false; | 1133 | local->suspended = false; |
1134 | mb(); | ||
1135 | local->resuming = false; | ||
1137 | 1136 | ||
1138 | list_for_each_entry(sdata, &local->interfaces, list) { | 1137 | list_for_each_entry(sdata, &local->interfaces, list) { |
1139 | switch(sdata->vif.type) { | 1138 | switch(sdata->vif.type) { |
diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c index c93494fef8ef..d65d3481919c 100644 --- a/net/netfilter/nf_log.c +++ b/net/netfilter/nf_log.c | |||
@@ -128,9 +128,8 @@ EXPORT_SYMBOL(nf_log_packet); | |||
128 | 128 | ||
129 | #ifdef CONFIG_PROC_FS | 129 | #ifdef CONFIG_PROC_FS |
130 | static void *seq_start(struct seq_file *seq, loff_t *pos) | 130 | static void *seq_start(struct seq_file *seq, loff_t *pos) |
131 | __acquires(RCU) | ||
132 | { | 131 | { |
133 | rcu_read_lock(); | 132 | mutex_lock(&nf_log_mutex); |
134 | 133 | ||
135 | if (*pos >= ARRAY_SIZE(nf_loggers)) | 134 | if (*pos >= ARRAY_SIZE(nf_loggers)) |
136 | return NULL; | 135 | return NULL; |
@@ -149,9 +148,8 @@ static void *seq_next(struct seq_file *s, void *v, loff_t *pos) | |||
149 | } | 148 | } |
150 | 149 | ||
151 | static void seq_stop(struct seq_file *s, void *v) | 150 | static void seq_stop(struct seq_file *s, void *v) |
152 | __releases(RCU) | ||
153 | { | 151 | { |
154 | rcu_read_unlock(); | 152 | mutex_unlock(&nf_log_mutex); |
155 | } | 153 | } |
156 | 154 | ||
157 | static int seq_show(struct seq_file *s, void *v) | 155 | static int seq_show(struct seq_file *s, void *v) |
@@ -161,7 +159,7 @@ static int seq_show(struct seq_file *s, void *v) | |||
161 | struct nf_logger *t; | 159 | struct nf_logger *t; |
162 | int ret; | 160 | int ret; |
163 | 161 | ||
164 | logger = rcu_dereference(nf_loggers[*pos]); | 162 | logger = nf_loggers[*pos]; |
165 | 163 | ||
166 | if (!logger) | 164 | if (!logger) |
167 | ret = seq_printf(s, "%2lld NONE (", *pos); | 165 | ret = seq_printf(s, "%2lld NONE (", *pos); |
@@ -171,22 +169,16 @@ static int seq_show(struct seq_file *s, void *v) | |||
171 | if (ret < 0) | 169 | if (ret < 0) |
172 | return ret; | 170 | return ret; |
173 | 171 | ||
174 | mutex_lock(&nf_log_mutex); | ||
175 | list_for_each_entry(t, &nf_loggers_l[*pos], list[*pos]) { | 172 | list_for_each_entry(t, &nf_loggers_l[*pos], list[*pos]) { |
176 | ret = seq_printf(s, "%s", t->name); | 173 | ret = seq_printf(s, "%s", t->name); |
177 | if (ret < 0) { | 174 | if (ret < 0) |
178 | mutex_unlock(&nf_log_mutex); | ||
179 | return ret; | 175 | return ret; |
180 | } | ||
181 | if (&t->list[*pos] != nf_loggers_l[*pos].prev) { | 176 | if (&t->list[*pos] != nf_loggers_l[*pos].prev) { |
182 | ret = seq_printf(s, ","); | 177 | ret = seq_printf(s, ","); |
183 | if (ret < 0) { | 178 | if (ret < 0) |
184 | mutex_unlock(&nf_log_mutex); | ||
185 | return ret; | 179 | return ret; |
186 | } | ||
187 | } | 180 | } |
188 | } | 181 | } |
189 | mutex_unlock(&nf_log_mutex); | ||
190 | 182 | ||
191 | return seq_printf(s, ")\n"); | 183 | return seq_printf(s, ")\n"); |
192 | } | 184 | } |
diff --git a/net/netfilter/xt_limit.c b/net/netfilter/xt_limit.c index 2e8089ecd0af..2773be6a71dd 100644 --- a/net/netfilter/xt_limit.c +++ b/net/netfilter/xt_limit.c | |||
@@ -112,7 +112,7 @@ static bool limit_mt_check(const struct xt_mtchk_param *par) | |||
112 | 112 | ||
113 | priv = kmalloc(sizeof(*priv), GFP_KERNEL); | 113 | priv = kmalloc(sizeof(*priv), GFP_KERNEL); |
114 | if (priv == NULL) | 114 | if (priv == NULL) |
115 | return -ENOMEM; | 115 | return false; |
116 | 116 | ||
117 | /* For SMP, we only want to use one set of state. */ | 117 | /* For SMP, we only want to use one set of state. */ |
118 | r->master = priv; | 118 | r->master = priv; |
diff --git a/net/netfilter/xt_osf.c b/net/netfilter/xt_osf.c index 63e190504656..4d1a41bbd5d7 100644 --- a/net/netfilter/xt_osf.c +++ b/net/netfilter/xt_osf.c | |||
@@ -118,7 +118,7 @@ static int xt_osf_remove_callback(struct sock *ctnl, struct sk_buff *skb, | |||
118 | { | 118 | { |
119 | struct xt_osf_user_finger *f; | 119 | struct xt_osf_user_finger *f; |
120 | struct xt_osf_finger *sf; | 120 | struct xt_osf_finger *sf; |
121 | int err = ENOENT; | 121 | int err = -ENOENT; |
122 | 122 | ||
123 | if (!osf_attrs[OSF_ATTR_FINGER]) | 123 | if (!osf_attrs[OSF_ATTR_FINGER]) |
124 | return -EINVAL; | 124 | return -EINVAL; |
diff --git a/net/rfkill/core.c b/net/rfkill/core.c index ba2efb960c60..a001f7c1f711 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c | |||
@@ -1189,6 +1189,7 @@ static long rfkill_fop_ioctl(struct file *file, unsigned int cmd, | |||
1189 | #endif | 1189 | #endif |
1190 | 1190 | ||
1191 | static const struct file_operations rfkill_fops = { | 1191 | static const struct file_operations rfkill_fops = { |
1192 | .owner = THIS_MODULE, | ||
1192 | .open = rfkill_fop_open, | 1193 | .open = rfkill_fop_open, |
1193 | .read = rfkill_fop_read, | 1194 | .read = rfkill_fop_read, |
1194 | .write = rfkill_fop_write, | 1195 | .write = rfkill_fop_write, |
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index c9f20e28521b..23e5e97aa617 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -423,16 +423,6 @@ void sctp_retransmit_mark(struct sctp_outq *q, | |||
423 | if ((reason == SCTP_RTXR_FAST_RTX && | 423 | if ((reason == SCTP_RTXR_FAST_RTX && |
424 | (chunk->fast_retransmit == SCTP_NEED_FRTX)) || | 424 | (chunk->fast_retransmit == SCTP_NEED_FRTX)) || |
425 | (reason != SCTP_RTXR_FAST_RTX && !chunk->tsn_gap_acked)) { | 425 | (reason != SCTP_RTXR_FAST_RTX && !chunk->tsn_gap_acked)) { |
426 | /* If this chunk was sent less then 1 rto ago, do not | ||
427 | * retransmit this chunk, but give the peer time | ||
428 | * to acknowlege it. Do this only when | ||
429 | * retransmitting due to T3 timeout. | ||
430 | */ | ||
431 | if (reason == SCTP_RTXR_T3_RTX && | ||
432 | time_before(jiffies, chunk->sent_at + | ||
433 | transport->last_rto)) | ||
434 | continue; | ||
435 | |||
436 | /* RFC 2960 6.2.1 Processing a Received SACK | 426 | /* RFC 2960 6.2.1 Processing a Received SACK |
437 | * | 427 | * |
438 | * C) Any time a DATA chunk is marked for | 428 | * C) Any time a DATA chunk is marked for |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 8674d4919556..efa516b47e81 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -480,7 +480,6 @@ static void sctp_do_8_2_transport_strike(struct sctp_association *asoc, | |||
480 | * that indicates that we have an outstanding HB. | 480 | * that indicates that we have an outstanding HB. |
481 | */ | 481 | */ |
482 | if (!is_hb || transport->hb_sent) { | 482 | if (!is_hb || transport->hb_sent) { |
483 | transport->last_rto = transport->rto; | ||
484 | transport->rto = min((transport->rto * 2), transport->asoc->rto_max); | 483 | transport->rto = min((transport->rto * 2), transport->asoc->rto_max); |
485 | } | 484 | } |
486 | } | 485 | } |
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 3b141bb32faf..37a1184d789f 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -74,7 +74,7 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer, | |||
74 | * given destination transport address, set RTO to the protocol | 74 | * given destination transport address, set RTO to the protocol |
75 | * parameter 'RTO.Initial'. | 75 | * parameter 'RTO.Initial'. |
76 | */ | 76 | */ |
77 | peer->last_rto = peer->rto = msecs_to_jiffies(sctp_rto_initial); | 77 | peer->rto = msecs_to_jiffies(sctp_rto_initial); |
78 | peer->rtt = 0; | 78 | peer->rtt = 0; |
79 | peer->rttvar = 0; | 79 | peer->rttvar = 0; |
80 | peer->srtt = 0; | 80 | peer->srtt = 0; |
@@ -386,7 +386,6 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt) | |||
386 | tp->rto = tp->asoc->rto_max; | 386 | tp->rto = tp->asoc->rto_max; |
387 | 387 | ||
388 | tp->rtt = rtt; | 388 | tp->rtt = rtt; |
389 | tp->last_rto = tp->rto; | ||
390 | 389 | ||
391 | /* Reset rto_pending so that a new RTT measurement is started when a | 390 | /* Reset rto_pending so that a new RTT measurement is started when a |
392 | * new data chunk is sent. | 391 | * new data chunk is sent. |
@@ -602,7 +601,7 @@ void sctp_transport_reset(struct sctp_transport *t) | |||
602 | */ | 601 | */ |
603 | t->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380)); | 602 | t->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380)); |
604 | t->ssthresh = asoc->peer.i.a_rwnd; | 603 | t->ssthresh = asoc->peer.i.a_rwnd; |
605 | t->last_rto = t->rto = asoc->rto_initial; | 604 | t->rto = asoc->rto_initial; |
606 | t->rtt = 0; | 605 | t->rtt = 0; |
607 | t->srtt = 0; | 606 | t->srtt = 0; |
608 | t->rttvar = 0; | 607 | t->rttvar = 0; |
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 6d69c7ccdcc7..80599e3a7994 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile | |||
@@ -30,7 +30,7 @@ silentoldconfig: $(obj)/conf | |||
30 | $< -s $(Kconfig) | 30 | $< -s $(Kconfig) |
31 | 31 | ||
32 | localmodconfig: $(obj)/streamline_config.pl $(obj)/conf | 32 | localmodconfig: $(obj)/streamline_config.pl $(obj)/conf |
33 | $(Q)perl $< $(Kconfig) > .tmp.config | 33 | $(Q)perl $< $(srctree) $(Kconfig) > .tmp.config |
34 | $(Q)if [ -f .config ]; then \ | 34 | $(Q)if [ -f .config ]; then \ |
35 | cmp -s .tmp.config .config || \ | 35 | cmp -s .tmp.config .config || \ |
36 | (mv -f .config .config.old.1; \ | 36 | (mv -f .config .config.old.1; \ |
@@ -44,7 +44,7 @@ localmodconfig: $(obj)/streamline_config.pl $(obj)/conf | |||
44 | $(Q)rm -f .tmp.config | 44 | $(Q)rm -f .tmp.config |
45 | 45 | ||
46 | localyesconfig: $(obj)/streamline_config.pl $(obj)/conf | 46 | localyesconfig: $(obj)/streamline_config.pl $(obj)/conf |
47 | $(Q)perl $< $(Kconfig) > .tmp.config | 47 | $(Q)perl $< $(srctree) $(Kconfig) > .tmp.config |
48 | $(Q)sed -i s/=m/=y/ .tmp.config | 48 | $(Q)sed -i s/=m/=y/ .tmp.config |
49 | $(Q)if [ -f .config ]; then \ | 49 | $(Q)if [ -f .config ]; then \ |
50 | cmp -s .tmp.config .config || \ | 50 | cmp -s .tmp.config .config || \ |
diff --git a/scripts/kconfig/streamline_config.pl b/scripts/kconfig/streamline_config.pl index 95984db8e1e0..0d800820c3cd 100644 --- a/scripts/kconfig/streamline_config.pl +++ b/scripts/kconfig/streamline_config.pl | |||
@@ -43,7 +43,6 @@ | |||
43 | # make oldconfig | 43 | # make oldconfig |
44 | # | 44 | # |
45 | my $config = ".config"; | 45 | my $config = ".config"; |
46 | my $linuxpath = "."; | ||
47 | 46 | ||
48 | my $uname = `uname -r`; | 47 | my $uname = `uname -r`; |
49 | chomp $uname; | 48 | chomp $uname; |
@@ -111,7 +110,11 @@ sub find_config { | |||
111 | 110 | ||
112 | find_config; | 111 | find_config; |
113 | 112 | ||
114 | my @makefiles = `find $linuxpath -name Makefile`; | 113 | # Get the build source and top level Kconfig file (passed in) |
114 | my $ksource = $ARGV[0]; | ||
115 | my $kconfig = $ARGV[1]; | ||
116 | |||
117 | my @makefiles = `find $ksource -name Makefile`; | ||
115 | my %depends; | 118 | my %depends; |
116 | my %selects; | 119 | my %selects; |
117 | my %prompts; | 120 | my %prompts; |
@@ -119,9 +122,6 @@ my %objects; | |||
119 | my $var; | 122 | my $var; |
120 | my $cont = 0; | 123 | my $cont = 0; |
121 | 124 | ||
122 | # Get the top level Kconfig file (passed in) | ||
123 | my $kconfig = $ARGV[0]; | ||
124 | |||
125 | # prevent recursion | 125 | # prevent recursion |
126 | my %read_kconfigs; | 126 | my %read_kconfigs; |
127 | 127 | ||
@@ -132,7 +132,7 @@ sub read_kconfig { | |||
132 | my $config; | 132 | my $config; |
133 | my @kconfigs; | 133 | my @kconfigs; |
134 | 134 | ||
135 | open(KIN, $kconfig) || die "Can't open $kconfig"; | 135 | open(KIN, "$ksource/$kconfig") || die "Can't open $kconfig"; |
136 | while (<KIN>) { | 136 | while (<KIN>) { |
137 | chomp; | 137 | chomp; |
138 | 138 | ||
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 1f0f8213e2d5..6c160a038b23 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c | |||
@@ -504,6 +504,10 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream, | |||
504 | int err; | 504 | int err; |
505 | 505 | ||
506 | aaci_pcm_hw_free(substream); | 506 | aaci_pcm_hw_free(substream); |
507 | if (aacirun->pcm_open) { | ||
508 | snd_ac97_pcm_close(aacirun->pcm); | ||
509 | aacirun->pcm_open = 0; | ||
510 | } | ||
507 | 511 | ||
508 | err = devdma_hw_alloc(NULL, substream, | 512 | err = devdma_hw_alloc(NULL, substream, |
509 | params_buffer_bytes(params)); | 513 | params_buffer_bytes(params)); |
@@ -517,7 +521,7 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream, | |||
517 | else | 521 | else |
518 | err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params), | 522 | err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params), |
519 | params_channels(params), | 523 | params_channels(params), |
520 | aacirun->pcm->r[1].slots); | 524 | aacirun->pcm->r[0].slots); |
521 | 525 | ||
522 | if (err) | 526 | if (err) |
523 | goto out; | 527 | goto out; |
diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index 6b24d8bb02bb..90a0264f7538 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c | |||
@@ -625,11 +625,10 @@ static int tlv320aic23_resume(struct platform_device *pdev) | |||
625 | { | 625 | { |
626 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 626 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
627 | struct snd_soc_codec *codec = socdev->card->codec; | 627 | struct snd_soc_codec *codec = socdev->card->codec; |
628 | int i; | ||
629 | u16 reg; | 628 | u16 reg; |
630 | 629 | ||
631 | /* Sync reg_cache with the hardware */ | 630 | /* Sync reg_cache with the hardware */ |
632 | for (reg = 0; reg < ARRAY_SIZE(tlv320aic23_reg); i++) { | 631 | for (reg = 0; reg < TLV320AIC23_RESET; reg++) { |
633 | u16 val = tlv320aic23_read_reg_cache(codec, reg); | 632 | u16 val = tlv320aic23_read_reg_cache(codec, reg); |
634 | tlv320aic23_write(codec, reg, val); | 633 | tlv320aic23_write(codec, reg, val); |
635 | } | 634 | } |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index d89f6dc00908..66d4c165f99b 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -973,9 +973,19 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) | |||
973 | if (!w->power_check) | 973 | if (!w->power_check) |
974 | continue; | 974 | continue; |
975 | 975 | ||
976 | power = w->power_check(w); | 976 | /* If we're suspending then pull down all the |
977 | if (power) | 977 | * power. */ |
978 | sys_power = 1; | 978 | switch (event) { |
979 | case SND_SOC_DAPM_STREAM_SUSPEND: | ||
980 | power = 0; | ||
981 | break; | ||
982 | |||
983 | default: | ||
984 | power = w->power_check(w); | ||
985 | if (power) | ||
986 | sys_power = 1; | ||
987 | break; | ||
988 | } | ||
979 | 989 | ||
980 | if (w->power == power) | 990 | if (w->power == power) |
981 | continue; | 991 | continue; |
@@ -999,8 +1009,12 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) | |||
999 | case SND_SOC_DAPM_STREAM_RESUME: | 1009 | case SND_SOC_DAPM_STREAM_RESUME: |
1000 | sys_power = 1; | 1010 | sys_power = 1; |
1001 | break; | 1011 | break; |
1012 | case SND_SOC_DAPM_STREAM_SUSPEND: | ||
1013 | sys_power = 0; | ||
1014 | break; | ||
1002 | case SND_SOC_DAPM_STREAM_NOP: | 1015 | case SND_SOC_DAPM_STREAM_NOP: |
1003 | sys_power = codec->bias_level != SND_SOC_BIAS_STANDBY; | 1016 | sys_power = codec->bias_level != SND_SOC_BIAS_STANDBY; |
1017 | break; | ||
1004 | default: | 1018 | default: |
1005 | break; | 1019 | break; |
1006 | } | 1020 | } |