diff options
276 files changed, 9918 insertions, 1581 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 c824b4d62754..6150c80bccf6 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) |
| @@ -749,6 +771,14 @@ ARM/NEC MOBILEPRO 900/c MACHINE SUPPORT | |||
| 749 | M: Michael Petchkovsky <mkpetch@internode.on.net> | 771 | M: Michael Petchkovsky <mkpetch@internode.on.net> |
| 750 | S: Maintained | 772 | S: Maintained |
| 751 | 773 | ||
| 774 | ARM/NOMADIK ARCHITECTURE | ||
| 775 | M: Alessandro Rubini <rubini@unipv.it> | ||
| 776 | M: STEricsson <STEricsson_nomadik_linux@list.st.com> | ||
| 777 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||
| 778 | S: Maintained | ||
| 779 | F: arch/arm/mach-nomadik/ | ||
| 780 | F: arch/arm/plat-nomadik/ | ||
| 781 | |||
| 752 | ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT | 782 | ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT |
| 753 | M: Nelson Castillo <arhuaco@freaks-unidos.net> | 783 | M: Nelson Castillo <arhuaco@freaks-unidos.net> |
| 754 | L: openmoko-kernel@lists.openmoko.org (subscribers-only) | 784 | L: openmoko-kernel@lists.openmoko.org (subscribers-only) |
| @@ -893,6 +923,12 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | |||
| 893 | W: http://www.mcuos.com | 923 | W: http://www.mcuos.com |
| 894 | S: Maintained | 924 | S: Maintained |
| 895 | 925 | ||
| 926 | ARM/U8500 ARM ARCHITECTURE | ||
| 927 | M: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> | ||
| 928 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | ||
| 929 | S: Maintained | ||
| 930 | F: arch/arm/mach-ux500/ | ||
| 931 | |||
| 896 | ARM/VFP SUPPORT | 932 | ARM/VFP SUPPORT |
| 897 | M: Russell King <linux@arm.linux.org.uk> | 933 | M: Russell King <linux@arm.linux.org.uk> |
| 898 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 934 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| @@ -1027,7 +1063,7 @@ F: drivers/serial/atmel_serial.c | |||
| 1027 | 1063 | ||
| 1028 | ATMEL LCDFB DRIVER | 1064 | ATMEL LCDFB DRIVER |
| 1029 | M: Nicolas Ferre <nicolas.ferre@atmel.com> | 1065 | M: Nicolas Ferre <nicolas.ferre@atmel.com> |
| 1030 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 1066 | L: linux-fbdev@vger.kernel.org |
| 1031 | S: Maintained | 1067 | S: Maintained |
| 1032 | F: drivers/video/atmel_lcdfb.c | 1068 | F: drivers/video/atmel_lcdfb.c |
| 1033 | F: include/video/atmel_lcdc.h | 1069 | F: include/video/atmel_lcdc.h |
| @@ -2113,7 +2149,7 @@ F: drivers/net/wan/dlci.c | |||
| 2113 | F: drivers/net/wan/sdla.c | 2149 | F: drivers/net/wan/sdla.c |
| 2114 | 2150 | ||
| 2115 | FRAMEBUFFER LAYER | 2151 | FRAMEBUFFER LAYER |
| 2116 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 2152 | L: linux-fbdev@vger.kernel.org |
| 2117 | W: http://linux-fbdev.sourceforge.net/ | 2153 | W: http://linux-fbdev.sourceforge.net/ |
| 2118 | S: Orphan | 2154 | S: Orphan |
| 2119 | F: Documentation/fb/ | 2155 | F: Documentation/fb/ |
| @@ -2136,7 +2172,7 @@ F: drivers/i2c/busses/i2c-cpm.c | |||
| 2136 | 2172 | ||
| 2137 | FREESCALE IMX / MXC FRAMEBUFFER DRIVER | 2173 | FREESCALE IMX / MXC FRAMEBUFFER DRIVER |
| 2138 | M: Sascha Hauer <kernel@pengutronix.de> | 2174 | M: Sascha Hauer <kernel@pengutronix.de> |
| 2139 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 2175 | L: linux-fbdev@vger.kernel.org |
| 2140 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 2176 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 2141 | S: Maintained | 2177 | S: Maintained |
| 2142 | F: arch/arm/plat-mxc/include/mach/imxfb.h | 2178 | F: arch/arm/plat-mxc/include/mach/imxfb.h |
| @@ -2312,6 +2348,13 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | |||
| 2312 | S: Maintained | 2348 | S: Maintained |
| 2313 | F: drivers/media/video/gspca/finepix.c | 2349 | F: drivers/media/video/gspca/finepix.c |
| 2314 | 2350 | ||
| 2351 | GSPCA GL860 SUBDRIVER | ||
| 2352 | M: Olivier Lorin <o.lorin@laposte.net> | ||
| 2353 | L: linux-media@vger.kernel.org | ||
| 2354 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6.git | ||
| 2355 | S: Maintained | ||
| 2356 | F: drivers/media/video/gspca/gl860/ | ||
| 2357 | |||
| 2315 | GSPCA M5602 SUBDRIVER | 2358 | GSPCA M5602 SUBDRIVER |
| 2316 | M: Erik Andren <erik.andren@gmail.com> | 2359 | M: Erik Andren <erik.andren@gmail.com> |
| 2317 | L: linux-media@vger.kernel.org | 2360 | L: linux-media@vger.kernel.org |
| @@ -2533,8 +2576,7 @@ S: Maintained | |||
| 2533 | F: Documentation/i2c/ | 2576 | F: Documentation/i2c/ |
| 2534 | F: drivers/i2c/ | 2577 | F: drivers/i2c/ |
| 2535 | F: include/linux/i2c.h | 2578 | F: include/linux/i2c.h |
| 2536 | F: include/linux/i2c-dev.h | 2579 | F: include/linux/i2c-*.h |
| 2537 | F: include/linux/i2c-id.h | ||
| 2538 | 2580 | ||
| 2539 | I2C-TINY-USB DRIVER | 2581 | I2C-TINY-USB DRIVER |
| 2540 | M: Till Harbaum <till@harbaum.org> | 2582 | M: Till Harbaum <till@harbaum.org> |
| @@ -2635,7 +2677,7 @@ S: Supported | |||
| 2635 | F: security/integrity/ima/ | 2677 | F: security/integrity/ima/ |
| 2636 | 2678 | ||
| 2637 | IMS TWINTURBO FRAMEBUFFER DRIVER | 2679 | IMS TWINTURBO FRAMEBUFFER DRIVER |
| 2638 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 2680 | L: linux-fbdev@vger.kernel.org |
| 2639 | S: Orphan | 2681 | S: Orphan |
| 2640 | F: drivers/video/imsttfb.c | 2682 | F: drivers/video/imsttfb.c |
| 2641 | 2683 | ||
| @@ -2670,14 +2712,14 @@ F: drivers/input/ | |||
| 2670 | 2712 | ||
| 2671 | INTEL FRAMEBUFFER DRIVER (excluding 810 and 815) | 2713 | INTEL FRAMEBUFFER DRIVER (excluding 810 and 815) |
| 2672 | M: Sylvain Meyer <sylvain.meyer@worldonline.fr> | 2714 | M: Sylvain Meyer <sylvain.meyer@worldonline.fr> |
| 2673 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 2715 | L: linux-fbdev@vger.kernel.org |
| 2674 | S: Maintained | 2716 | S: Maintained |
| 2675 | F: Documentation/fb/intelfb.txt | 2717 | F: Documentation/fb/intelfb.txt |
| 2676 | F: drivers/video/intelfb/ | 2718 | F: drivers/video/intelfb/ |
| 2677 | 2719 | ||
| 2678 | INTEL 810/815 FRAMEBUFFER DRIVER | 2720 | INTEL 810/815 FRAMEBUFFER DRIVER |
| 2679 | M: Antonino Daplas <adaplas@gmail.com> | 2721 | M: Antonino Daplas <adaplas@gmail.com> |
| 2680 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 2722 | L: linux-fbdev@vger.kernel.org |
| 2681 | S: Maintained | 2723 | S: Maintained |
| 2682 | F: drivers/video/i810/ | 2724 | F: drivers/video/i810/ |
| 2683 | 2725 | ||
| @@ -3391,7 +3433,7 @@ S: Supported | |||
| 3391 | 3433 | ||
| 3392 | MATROX FRAMEBUFFER DRIVER | 3434 | MATROX FRAMEBUFFER DRIVER |
| 3393 | M: Petr Vandrovec <vandrove@vc.cvut.cz> | 3435 | M: Petr Vandrovec <vandrove@vc.cvut.cz> |
| 3394 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 3436 | L: linux-fbdev@vger.kernel.org |
| 3395 | S: Maintained | 3437 | S: Maintained |
| 3396 | F: drivers/video/matrox/matroxfb_* | 3438 | F: drivers/video/matrox/matroxfb_* |
| 3397 | F: include/linux/matroxfb.h | 3439 | F: include/linux/matroxfb.h |
| @@ -3778,7 +3820,7 @@ F: fs/ntfs/ | |||
| 3778 | 3820 | ||
| 3779 | NVIDIA (rivafb and nvidiafb) FRAMEBUFFER DRIVER | 3821 | NVIDIA (rivafb and nvidiafb) FRAMEBUFFER DRIVER |
| 3780 | M: Antonino Daplas <adaplas@gmail.com> | 3822 | M: Antonino Daplas <adaplas@gmail.com> |
| 3781 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 3823 | L: linux-fbdev@vger.kernel.org |
| 3782 | S: Maintained | 3824 | S: Maintained |
| 3783 | F: drivers/video/riva/ | 3825 | F: drivers/video/riva/ |
| 3784 | F: drivers/video/nvidia/ | 3826 | F: drivers/video/nvidia/ |
| @@ -3813,7 +3855,7 @@ F: sound/soc/omap/ | |||
| 3813 | 3855 | ||
| 3814 | OMAP FRAMEBUFFER SUPPORT | 3856 | OMAP FRAMEBUFFER SUPPORT |
| 3815 | M: Imre Deak <imre.deak@nokia.com> | 3857 | M: Imre Deak <imre.deak@nokia.com> |
| 3816 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 3858 | L: linux-fbdev@vger.kernel.org |
| 3817 | L: linux-omap@vger.kernel.org | 3859 | L: linux-omap@vger.kernel.org |
| 3818 | S: Maintained | 3860 | S: Maintained |
| 3819 | F: drivers/video/omap/ | 3861 | F: drivers/video/omap/ |
| @@ -4319,14 +4361,14 @@ F: include/linux/qnxtypes.h | |||
| 4319 | 4361 | ||
| 4320 | RADEON FRAMEBUFFER DISPLAY DRIVER | 4362 | RADEON FRAMEBUFFER DISPLAY DRIVER |
| 4321 | M: Benjamin Herrenschmidt <benh@kernel.crashing.org> | 4363 | M: Benjamin Herrenschmidt <benh@kernel.crashing.org> |
| 4322 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 4364 | L: linux-fbdev@vger.kernel.org |
| 4323 | S: Maintained | 4365 | S: Maintained |
| 4324 | F: drivers/video/aty/radeon* | 4366 | F: drivers/video/aty/radeon* |
| 4325 | F: include/linux/radeonfb.h | 4367 | F: include/linux/radeonfb.h |
| 4326 | 4368 | ||
| 4327 | RAGE128 FRAMEBUFFER DISPLAY DRIVER | 4369 | RAGE128 FRAMEBUFFER DISPLAY DRIVER |
| 4328 | M: Paul Mackerras <paulus@samba.org> | 4370 | M: Paul Mackerras <paulus@samba.org> |
| 4329 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 4371 | L: linux-fbdev@vger.kernel.org |
| 4330 | S: Maintained | 4372 | S: Maintained |
| 4331 | F: drivers/video/aty/aty128fb.c | 4373 | F: drivers/video/aty/aty128fb.c |
| 4332 | 4374 | ||
| @@ -4465,7 +4507,7 @@ F: drivers/net/wireless/rtl818x/rtl8187* | |||
| 4465 | 4507 | ||
| 4466 | S3 SAVAGE FRAMEBUFFER DRIVER | 4508 | S3 SAVAGE FRAMEBUFFER DRIVER |
| 4467 | M: Antonino Daplas <adaplas@gmail.com> | 4509 | M: Antonino Daplas <adaplas@gmail.com> |
| 4468 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 4510 | L: linux-fbdev@vger.kernel.org |
| 4469 | S: Maintained | 4511 | S: Maintained |
| 4470 | F: drivers/video/savage/ | 4512 | F: drivers/video/savage/ |
| 4471 | 4513 | ||
| @@ -5628,7 +5670,7 @@ S: Maintained | |||
| 5628 | 5670 | ||
| 5629 | UVESAFB DRIVER | 5671 | UVESAFB DRIVER |
| 5630 | M: Michal Januszewski <spock@gentoo.org> | 5672 | M: Michal Januszewski <spock@gentoo.org> |
| 5631 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 5673 | L: linux-fbdev@vger.kernel.org |
| 5632 | W: http://dev.gentoo.org/~spock/projects/uvesafb/ | 5674 | W: http://dev.gentoo.org/~spock/projects/uvesafb/ |
| 5633 | S: Maintained | 5675 | S: Maintained |
| 5634 | F: Documentation/fb/uvesafb.txt | 5676 | F: Documentation/fb/uvesafb.txt |
| @@ -5661,7 +5703,7 @@ F: drivers/mmc/host/via-sdmmc.c | |||
| 5661 | VIA UNICHROME(PRO)/CHROME9 FRAMEBUFFER DRIVER | 5703 | VIA UNICHROME(PRO)/CHROME9 FRAMEBUFFER DRIVER |
| 5662 | M: Joseph Chan <JosephChan@via.com.tw> | 5704 | M: Joseph Chan <JosephChan@via.com.tw> |
| 5663 | M: Scott Fang <ScottFang@viatech.com.cn> | 5705 | M: Scott Fang <ScottFang@viatech.com.cn> |
| 5664 | L: linux-fbdev-devel@lists.sourceforge.net (moderated for non-subscribers) | 5706 | L: linux-fbdev@vger.kernel.org |
| 5665 | S: Maintained | 5707 | S: Maintained |
| 5666 | F: drivers/video/via/ | 5708 | F: drivers/video/via/ |
| 5667 | 5709 | ||
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 1c4119c60040..1ae18d879e12 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
| @@ -702,6 +702,16 @@ config ARCH_BCMRING | |||
| 702 | help | 702 | help |
| 703 | Support for Broadcom's BCMRing platform. | 703 | Support for Broadcom's BCMRing platform. |
| 704 | 704 | ||
| 705 | config ARCH_U8500 | ||
| 706 | bool "ST-Ericsson U8500 Series" | ||
| 707 | select CPU_V7 | ||
| 708 | select ARM_AMBA | ||
| 709 | select GENERIC_TIME | ||
| 710 | select GENERIC_CLOCKEVENTS | ||
| 711 | select COMMON_CLKDEV | ||
| 712 | help | ||
| 713 | Support for ST-Ericsson's Ux500 architecture | ||
| 714 | |||
| 705 | endchoice | 715 | endchoice |
| 706 | 716 | ||
| 707 | source "arch/arm/mach-clps711x/Kconfig" | 717 | source "arch/arm/mach-clps711x/Kconfig" |
| @@ -787,6 +797,7 @@ source "arch/arm/mach-at91/Kconfig" | |||
| 787 | source "arch/arm/plat-mxc/Kconfig" | 797 | source "arch/arm/plat-mxc/Kconfig" |
| 788 | 798 | ||
| 789 | source "arch/arm/mach-nomadik/Kconfig" | 799 | source "arch/arm/mach-nomadik/Kconfig" |
| 800 | source "arch/arm/plat-nomadik/Kconfig" | ||
| 790 | 801 | ||
| 791 | source "arch/arm/mach-netx/Kconfig" | 802 | source "arch/arm/mach-netx/Kconfig" |
| 792 | 803 | ||
| @@ -804,6 +815,8 @@ source "arch/arm/mach-w90x900/Kconfig" | |||
| 804 | 815 | ||
| 805 | source "arch/arm/mach-bcmring/Kconfig" | 816 | source "arch/arm/mach-bcmring/Kconfig" |
| 806 | 817 | ||
| 818 | source "arch/arm/mach-ux500/Kconfig" | ||
| 819 | |||
| 807 | # Definitions to make life easier | 820 | # Definitions to make life easier |
| 808 | config ARCH_ACORN | 821 | config ARCH_ACORN |
| 809 | bool | 822 | bool |
| @@ -955,10 +968,10 @@ source "kernel/time/Kconfig" | |||
| 955 | config SMP | 968 | config SMP |
| 956 | bool "Symmetric Multi-Processing (EXPERIMENTAL)" | 969 | bool "Symmetric Multi-Processing (EXPERIMENTAL)" |
| 957 | depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\ | 970 | depends on EXPERIMENTAL && (REALVIEW_EB_ARM11MP || REALVIEW_EB_A9MP ||\ |
| 958 | MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4) | 971 | MACH_REALVIEW_PB11MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || ARCH_U8500) |
| 959 | depends on GENERIC_CLOCKEVENTS | 972 | depends on GENERIC_CLOCKEVENTS |
| 960 | select USE_GENERIC_SMP_HELPERS | 973 | select USE_GENERIC_SMP_HELPERS |
| 961 | select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4) | 974 | select HAVE_ARM_SCU if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500) |
| 962 | help | 975 | help |
| 963 | This enables support for systems with more than one CPU. If you have | 976 | This enables support for systems with more than one CPU. If you have |
| 964 | a system with only one CPU, like most personal computers, say N. If | 977 | a system with only one CPU, like most personal computers, say N. If |
| @@ -1027,9 +1040,9 @@ config HOTPLUG_CPU | |||
| 1027 | config LOCAL_TIMERS | 1040 | config LOCAL_TIMERS |
| 1028 | bool "Use local timer interrupts" | 1041 | bool "Use local timer interrupts" |
| 1029 | depends on SMP && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || \ | 1042 | depends on SMP && (REALVIEW_EB_ARM11MP || MACH_REALVIEW_PB11MP || \ |
| 1030 | REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4) | 1043 | REALVIEW_EB_A9MP || MACH_REALVIEW_PBX || ARCH_OMAP4 || ARCH_U8500) |
| 1031 | default y | 1044 | default y |
| 1032 | select HAVE_ARM_TWD if (ARCH_REALVIEW || ARCH_OMAP4) | 1045 | select HAVE_ARM_TWD if (ARCH_REALVIEW || ARCH_OMAP4 || ARCH_U8500) |
| 1033 | help | 1046 | help |
| 1034 | Enable support for local timers on SMP platforms, rather then the | 1047 | Enable support for local timers on SMP platforms, rather then the |
| 1035 | legacy IPI broadcast method. Local timers allows the system | 1048 | 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 a73caaf66763..7603eba7c0cd 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile | |||
| @@ -166,6 +166,7 @@ machine-$(CONFIG_ARCH_SHARK) := shark | |||
| 166 | machine-$(CONFIG_ARCH_STMP378X) := stmp378x | 166 | machine-$(CONFIG_ARCH_STMP378X) := stmp378x |
| 167 | machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx | 167 | machine-$(CONFIG_ARCH_STMP37XX) := stmp37xx |
| 168 | machine-$(CONFIG_ARCH_U300) := u300 | 168 | machine-$(CONFIG_ARCH_U300) := u300 |
| 169 | machine-$(CONFIG_ARCH_U8500) := ux500 | ||
| 169 | machine-$(CONFIG_ARCH_VERSATILE) := versatile | 170 | machine-$(CONFIG_ARCH_VERSATILE) := versatile |
| 170 | machine-$(CONFIG_ARCH_W90X900) := w90x900 | 171 | machine-$(CONFIG_ARCH_W90X900) := w90x900 |
| 171 | machine-$(CONFIG_FOOTBRIDGE) := footbridge | 172 | machine-$(CONFIG_FOOTBRIDGE) := footbridge |
| @@ -176,6 +177,7 @@ machine-$(CONFIG_ARCH_MXC91231) := mxc91231 | |||
| 176 | plat-$(CONFIG_ARCH_MXC) := mxc | 177 | plat-$(CONFIG_ARCH_MXC) := mxc |
| 177 | plat-$(CONFIG_ARCH_OMAP) := omap | 178 | plat-$(CONFIG_ARCH_OMAP) := omap |
| 178 | plat-$(CONFIG_PLAT_IOP) := iop | 179 | plat-$(CONFIG_PLAT_IOP) := iop |
| 180 | plat-$(CONFIG_PLAT_NOMADIK) := nomadik | ||
| 179 | plat-$(CONFIG_PLAT_ORION) := orion | 181 | plat-$(CONFIG_PLAT_ORION) := orion |
| 180 | plat-$(CONFIG_PLAT_PXA) := pxa | 182 | plat-$(CONFIG_PLAT_PXA) := pxa |
| 181 | plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx s3c | 183 | plat-$(CONFIG_PLAT_S3C24XX) := s3c24xx s3c |
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/kmap_types.h b/arch/arm/include/asm/kmap_types.h index d16ec97ec9a9..c019949a5189 100644 --- a/arch/arm/include/asm/kmap_types.h +++ b/arch/arm/include/asm/kmap_types.h | |||
| @@ -22,4 +22,10 @@ enum km_type { | |||
| 22 | KM_TYPE_NR | 22 | KM_TYPE_NR |
| 23 | }; | 23 | }; |
| 24 | 24 | ||
| 25 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
| 26 | #define KM_NMI (-1) | ||
| 27 | #define KM_NMI_PTE (-1) | ||
| 28 | #define KM_IRQ_PTE (-1) | ||
| 29 | #endif | ||
| 30 | |||
| 25 | #endif | 31 | #endif |
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 2fd88437348b..c71e39ed092f 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig | |||
| @@ -163,6 +163,11 @@ config MACH_CPUAT91 | |||
| 163 | Select this if you are using the Eukrea Electromatique's | 163 | Select this if you are using the Eukrea Electromatique's |
| 164 | CPUAT91 board <http://www.eukrea.com/>. | 164 | CPUAT91 board <http://www.eukrea.com/>. |
| 165 | 165 | ||
| 166 | config MACH_ECO920 | ||
| 167 | bool "eco920" | ||
| 168 | help | ||
| 169 | Select this if you are using the eco920 board | ||
| 170 | |||
| 166 | endif | 171 | endif |
| 167 | 172 | ||
| 168 | # ---------------------------------------------------------- | 173 | # ---------------------------------------------------------- |
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-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 3da45d051743..d98023f55503 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c | |||
| @@ -802,10 +802,12 @@ static void __init spitz_init(void) | |||
| 802 | { | 802 | { |
| 803 | spitz_ficp_platform_data.gpio_pwdown = SPITZ_GPIO_IR_ON; | 803 | spitz_ficp_platform_data.gpio_pwdown = SPITZ_GPIO_IR_ON; |
| 804 | 804 | ||
| 805 | #ifdef CONFIG_MACH_BORZOI | ||
| 805 | if (machine_is_borzoi()) { | 806 | if (machine_is_borzoi()) { |
| 806 | sharpsl_nand_platform_data.badblock_pattern = &sharpsl_akita_bbt; | 807 | sharpsl_nand_platform_data.badblock_pattern = &sharpsl_akita_bbt; |
| 807 | sharpsl_nand_platform_data.ecc_layout = &akita_oobinfo; | 808 | sharpsl_nand_platform_data.ecc_layout = &akita_oobinfo; |
| 808 | } | 809 | } |
| 810 | #endif | ||
| 809 | 811 | ||
| 810 | platform_scoop_config = &spitz_pcmcia_config; | 812 | platform_scoop_config = &spitz_pcmcia_config; |
| 811 | 813 | ||
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 9264d814cd7a..7b7d4c36c11c 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
| @@ -774,5 +774,5 @@ config CACHE_XSC3L2 | |||
| 774 | 774 | ||
| 775 | config ARM_L1_CACHE_SHIFT | 775 | config ARM_L1_CACHE_SHIFT |
| 776 | int | 776 | int |
| 777 | default 6 if ARCH_OMAP3 | 777 | default 6 if ARCH_OMAP3 || ARCH_S5PC1XX |
| 778 | default 5 | 778 | default 5 |
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 055cb2aa8134..42352e75742b 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 ea67be0223ac..2427cdcd9098 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/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c index f24d04132eda..4d227b152001 100644 --- a/drivers/watchdog/pnx4008_wdt.c +++ b/drivers/watchdog/pnx4008_wdt.c | |||
| @@ -317,7 +317,7 @@ static int __devexit pnx4008_wdt_remove(struct platform_device *pdev) | |||
| 317 | 317 | ||
| 318 | static struct platform_driver platform_wdt_driver = { | 318 | static struct platform_driver platform_wdt_driver = { |
| 319 | .driver = { | 319 | .driver = { |
| 320 | .name = "watchdog", | 320 | .name = "pnx4008-watchdog", |
| 321 | .owner = THIS_MODULE, | 321 | .owner = THIS_MODULE, |
| 322 | }, | 322 | }, |
| 323 | .probe = pnx4008_wdt_probe, | 323 | .probe = pnx4008_wdt_probe, |
| @@ -352,4 +352,4 @@ MODULE_PARM_DESC(nowayout, | |||
| 352 | 352 | ||
| 353 | MODULE_LICENSE("GPL"); | 353 | MODULE_LICENSE("GPL"); |
| 354 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); | 354 | MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); |
| 355 | MODULE_ALIAS("platform:watchdog"); | 355 | MODULE_ALIAS("platform:pnx4008-watchdog"); |
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 | } |
