diff options
756 files changed, 8884 insertions, 5997 deletions
diff --git a/Documentation/ABI/testing/sysfs-platform-asus-laptop b/Documentation/ABI/testing/sysfs-platform-asus-laptop index 1d775390e856..41ff8ae4dee0 100644 --- a/Documentation/ABI/testing/sysfs-platform-asus-laptop +++ b/Documentation/ABI/testing/sysfs-platform-asus-laptop | |||
@@ -47,6 +47,20 @@ Date: January 2007 | |||
47 | KernelVersion: 2.6.20 | 47 | KernelVersion: 2.6.20 |
48 | Contact: "Corentin Chary" <corentincj@iksaif.net> | 48 | Contact: "Corentin Chary" <corentincj@iksaif.net> |
49 | Description: | 49 | Description: |
50 | Control the bluetooth device. 1 means on, 0 means off. | 50 | Control the wlan device. 1 means on, 0 means off. |
51 | This may control the led, the device or both. | 51 | This may control the led, the device or both. |
52 | Users: Lapsus | 52 | Users: Lapsus |
53 | |||
54 | What: /sys/devices/platform/asus_laptop/wimax | ||
55 | Date: October 2010 | ||
56 | KernelVersion: 2.6.37 | ||
57 | Contact: "Corentin Chary" <corentincj@iksaif.net> | ||
58 | Description: | ||
59 | Control the wimax device. 1 means on, 0 means off. | ||
60 | |||
61 | What: /sys/devices/platform/asus_laptop/wwan | ||
62 | Date: October 2010 | ||
63 | KernelVersion: 2.6.37 | ||
64 | Contact: "Corentin Chary" <corentincj@iksaif.net> | ||
65 | Description: | ||
66 | Control the wwan (3G) device. 1 means on, 0 means off. | ||
diff --git a/Documentation/ABI/testing/sysfs-platform-eeepc-wmi b/Documentation/ABI/testing/sysfs-platform-eeepc-wmi new file mode 100644 index 000000000000..e4b5fef5fadd --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-eeepc-wmi | |||
@@ -0,0 +1,10 @@ | |||
1 | What: /sys/devices/platform/eeepc-wmi/cpufv | ||
2 | Date: Oct 2010 | ||
3 | KernelVersion: 2.6.37 | ||
4 | Contact: "Corentin Chary" <corentincj@iksaif.net> | ||
5 | Description: | ||
6 | Change CPU clock configuration (write-only). | ||
7 | There are three available clock configuration: | ||
8 | * 0 -> Super Performance Mode | ||
9 | * 1 -> High Performance Mode | ||
10 | * 2 -> Power Saving Mode | ||
diff --git a/Documentation/accounting/getdelays.c b/Documentation/accounting/getdelays.c index a2976a6de033..e9c77788a39d 100644 --- a/Documentation/accounting/getdelays.c +++ b/Documentation/accounting/getdelays.c | |||
@@ -516,6 +516,7 @@ int main(int argc, char *argv[]) | |||
516 | default: | 516 | default: |
517 | fprintf(stderr, "Unknown nla_type %d\n", | 517 | fprintf(stderr, "Unknown nla_type %d\n", |
518 | na->nla_type); | 518 | na->nla_type); |
519 | case TASKSTATS_TYPE_NULL: | ||
519 | break; | 520 | break; |
520 | } | 521 | } |
521 | na = (struct nlattr *) (GENLMSG_DATA(&msg) + len); | 522 | na = (struct nlattr *) (GENLMSG_DATA(&msg) + len); |
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index a91f30890011..33fa3e5d38fd 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking | |||
@@ -18,7 +18,6 @@ prototypes: | |||
18 | char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen); | 18 | char *(*d_dname)((struct dentry *dentry, char *buffer, int buflen); |
19 | 19 | ||
20 | locking rules: | 20 | locking rules: |
21 | none have BKL | ||
22 | dcache_lock rename_lock ->d_lock may block | 21 | dcache_lock rename_lock ->d_lock may block |
23 | d_revalidate: no no no yes | 22 | d_revalidate: no no no yes |
24 | d_hash no no no yes | 23 | d_hash no no no yes |
@@ -42,18 +41,23 @@ ata *); | |||
42 | int (*rename) (struct inode *, struct dentry *, | 41 | int (*rename) (struct inode *, struct dentry *, |
43 | struct inode *, struct dentry *); | 42 | struct inode *, struct dentry *); |
44 | int (*readlink) (struct dentry *, char __user *,int); | 43 | int (*readlink) (struct dentry *, char __user *,int); |
45 | int (*follow_link) (struct dentry *, struct nameidata *); | 44 | void * (*follow_link) (struct dentry *, struct nameidata *); |
45 | void (*put_link) (struct dentry *, struct nameidata *, void *); | ||
46 | void (*truncate) (struct inode *); | 46 | void (*truncate) (struct inode *); |
47 | int (*permission) (struct inode *, int, struct nameidata *); | 47 | int (*permission) (struct inode *, int, struct nameidata *); |
48 | int (*check_acl)(struct inode *, int); | ||
48 | int (*setattr) (struct dentry *, struct iattr *); | 49 | int (*setattr) (struct dentry *, struct iattr *); |
49 | int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *); | 50 | int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *); |
50 | int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); | 51 | int (*setxattr) (struct dentry *, const char *,const void *,size_t,int); |
51 | ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); | 52 | ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); |
52 | ssize_t (*listxattr) (struct dentry *, char *, size_t); | 53 | ssize_t (*listxattr) (struct dentry *, char *, size_t); |
53 | int (*removexattr) (struct dentry *, const char *); | 54 | int (*removexattr) (struct dentry *, const char *); |
55 | void (*truncate_range)(struct inode *, loff_t, loff_t); | ||
56 | long (*fallocate)(struct inode *inode, int mode, loff_t offset, loff_t len); | ||
57 | int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len); | ||
54 | 58 | ||
55 | locking rules: | 59 | locking rules: |
56 | all may block, none have BKL | 60 | all may block |
57 | i_mutex(inode) | 61 | i_mutex(inode) |
58 | lookup: yes | 62 | lookup: yes |
59 | create: yes | 63 | create: yes |
@@ -66,19 +70,24 @@ rmdir: yes (both) (see below) | |||
66 | rename: yes (all) (see below) | 70 | rename: yes (all) (see below) |
67 | readlink: no | 71 | readlink: no |
68 | follow_link: no | 72 | follow_link: no |
73 | put_link: no | ||
69 | truncate: yes (see below) | 74 | truncate: yes (see below) |
70 | setattr: yes | 75 | setattr: yes |
71 | permission: no | 76 | permission: no |
77 | check_acl: no | ||
72 | getattr: no | 78 | getattr: no |
73 | setxattr: yes | 79 | setxattr: yes |
74 | getxattr: no | 80 | getxattr: no |
75 | listxattr: no | 81 | listxattr: no |
76 | removexattr: yes | 82 | removexattr: yes |
83 | truncate_range: yes | ||
84 | fallocate: no | ||
85 | fiemap: no | ||
77 | Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on | 86 | Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on |
78 | victim. | 87 | victim. |
79 | cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem. | 88 | cross-directory ->rename() has (per-superblock) ->s_vfs_rename_sem. |
80 | ->truncate() is never called directly - it's a callback, not a | 89 | ->truncate() is never called directly - it's a callback, not a |
81 | method. It's called by vmtruncate() - library function normally used by | 90 | method. It's called by vmtruncate() - deprecated library function used by |
82 | ->setattr(). Locking information above applies to that call (i.e. is | 91 | ->setattr(). Locking information above applies to that call (i.e. is |
83 | inherited from ->setattr() - vmtruncate() is used when ATTR_SIZE had been | 92 | inherited from ->setattr() - vmtruncate() is used when ATTR_SIZE had been |
84 | passed). | 93 | passed). |
@@ -91,7 +100,7 @@ prototypes: | |||
91 | struct inode *(*alloc_inode)(struct super_block *sb); | 100 | struct inode *(*alloc_inode)(struct super_block *sb); |
92 | void (*destroy_inode)(struct inode *); | 101 | void (*destroy_inode)(struct inode *); |
93 | void (*dirty_inode) (struct inode *); | 102 | void (*dirty_inode) (struct inode *); |
94 | int (*write_inode) (struct inode *, int); | 103 | int (*write_inode) (struct inode *, struct writeback_control *wbc); |
95 | int (*drop_inode) (struct inode *); | 104 | int (*drop_inode) (struct inode *); |
96 | void (*evict_inode) (struct inode *); | 105 | void (*evict_inode) (struct inode *); |
97 | void (*put_super) (struct super_block *); | 106 | void (*put_super) (struct super_block *); |
@@ -105,10 +114,10 @@ prototypes: | |||
105 | int (*show_options)(struct seq_file *, struct vfsmount *); | 114 | int (*show_options)(struct seq_file *, struct vfsmount *); |
106 | ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t); | 115 | ssize_t (*quota_read)(struct super_block *, int, char *, size_t, loff_t); |
107 | ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t); | 116 | ssize_t (*quota_write)(struct super_block *, int, const char *, size_t, loff_t); |
117 | int (*bdev_try_to_free_page)(struct super_block*, struct page*, gfp_t); | ||
108 | 118 | ||
109 | locking rules: | 119 | locking rules: |
110 | All may block [not true, see below] | 120 | All may block [not true, see below] |
111 | None have BKL | ||
112 | s_umount | 121 | s_umount |
113 | alloc_inode: | 122 | alloc_inode: |
114 | destroy_inode: | 123 | destroy_inode: |
@@ -127,6 +136,7 @@ umount_begin: no | |||
127 | show_options: no (namespace_sem) | 136 | show_options: no (namespace_sem) |
128 | quota_read: no (see below) | 137 | quota_read: no (see below) |
129 | quota_write: no (see below) | 138 | quota_write: no (see below) |
139 | bdev_try_to_free_page: no (see below) | ||
130 | 140 | ||
131 | ->statfs() has s_umount (shared) when called by ustat(2) (native or | 141 | ->statfs() has s_umount (shared) when called by ustat(2) (native or |
132 | compat), but that's an accident of bad API; s_umount is used to pin | 142 | compat), but that's an accident of bad API; s_umount is used to pin |
@@ -139,19 +149,25 @@ be the only ones operating on the quota file by the quota code (via | |||
139 | dqio_sem) (unless an admin really wants to screw up something and | 149 | dqio_sem) (unless an admin really wants to screw up something and |
140 | writes to quota files with quotas on). For other details about locking | 150 | writes to quota files with quotas on). For other details about locking |
141 | see also dquot_operations section. | 151 | see also dquot_operations section. |
152 | ->bdev_try_to_free_page is called from the ->releasepage handler of | ||
153 | the block device inode. See there for more details. | ||
142 | 154 | ||
143 | --------------------------- file_system_type --------------------------- | 155 | --------------------------- file_system_type --------------------------- |
144 | prototypes: | 156 | prototypes: |
145 | int (*get_sb) (struct file_system_type *, int, | 157 | int (*get_sb) (struct file_system_type *, int, |
146 | const char *, void *, struct vfsmount *); | 158 | const char *, void *, struct vfsmount *); |
159 | struct dentry *(*mount) (struct file_system_type *, int, | ||
160 | const char *, void *); | ||
147 | void (*kill_sb) (struct super_block *); | 161 | void (*kill_sb) (struct super_block *); |
148 | locking rules: | 162 | locking rules: |
149 | may block BKL | 163 | may block |
150 | get_sb yes no | 164 | get_sb yes |
151 | kill_sb yes no | 165 | mount yes |
166 | kill_sb yes | ||
152 | 167 | ||
153 | ->get_sb() returns error or 0 with locked superblock attached to the vfsmount | 168 | ->get_sb() returns error or 0 with locked superblock attached to the vfsmount |
154 | (exclusive on ->s_umount). | 169 | (exclusive on ->s_umount). |
170 | ->mount() returns ERR_PTR or the root dentry. | ||
155 | ->kill_sb() takes a write-locked superblock, does all shutdown work on it, | 171 | ->kill_sb() takes a write-locked superblock, does all shutdown work on it, |
156 | unlocks and drops the reference. | 172 | unlocks and drops the reference. |
157 | 173 | ||
@@ -173,28 +189,38 @@ prototypes: | |||
173 | sector_t (*bmap)(struct address_space *, sector_t); | 189 | sector_t (*bmap)(struct address_space *, sector_t); |
174 | int (*invalidatepage) (struct page *, unsigned long); | 190 | int (*invalidatepage) (struct page *, unsigned long); |
175 | int (*releasepage) (struct page *, int); | 191 | int (*releasepage) (struct page *, int); |
192 | void (*freepage)(struct page *); | ||
176 | int (*direct_IO)(int, struct kiocb *, const struct iovec *iov, | 193 | int (*direct_IO)(int, struct kiocb *, const struct iovec *iov, |
177 | loff_t offset, unsigned long nr_segs); | 194 | loff_t offset, unsigned long nr_segs); |
178 | int (*launder_page) (struct page *); | 195 | int (*get_xip_mem)(struct address_space *, pgoff_t, int, void **, |
196 | unsigned long *); | ||
197 | int (*migratepage)(struct address_space *, struct page *, struct page *); | ||
198 | int (*launder_page)(struct page *); | ||
199 | int (*is_partially_uptodate)(struct page *, read_descriptor_t *, unsigned long); | ||
200 | int (*error_remove_page)(struct address_space *, struct page *); | ||
179 | 201 | ||
180 | locking rules: | 202 | locking rules: |
181 | All except set_page_dirty may block | 203 | All except set_page_dirty and freepage may block |
182 | 204 | ||
183 | BKL PageLocked(page) i_mutex | 205 | PageLocked(page) i_mutex |
184 | writepage: no yes, unlocks (see below) | 206 | writepage: yes, unlocks (see below) |
185 | readpage: no yes, unlocks | 207 | readpage: yes, unlocks |
186 | sync_page: no maybe | 208 | sync_page: maybe |
187 | writepages: no | 209 | writepages: |
188 | set_page_dirty no no | 210 | set_page_dirty no |
189 | readpages: no | 211 | readpages: |
190 | write_begin: no locks the page yes | 212 | write_begin: locks the page yes |
191 | write_end: no yes, unlocks yes | 213 | write_end: yes, unlocks yes |
192 | perform_write: no n/a yes | 214 | bmap: |
193 | bmap: no | 215 | invalidatepage: yes |
194 | invalidatepage: no yes | 216 | releasepage: yes |
195 | releasepage: no yes | 217 | freepage: yes |
196 | direct_IO: no | 218 | direct_IO: |
197 | launder_page: no yes | 219 | get_xip_mem: maybe |
220 | migratepage: yes (both) | ||
221 | launder_page: yes | ||
222 | is_partially_uptodate: yes | ||
223 | error_remove_page: yes | ||
198 | 224 | ||
199 | ->write_begin(), ->write_end(), ->sync_page() and ->readpage() | 225 | ->write_begin(), ->write_end(), ->sync_page() and ->readpage() |
200 | may be called from the request handler (/dev/loop). | 226 | may be called from the request handler (/dev/loop). |
@@ -274,9 +300,8 @@ under spinlock (it cannot block) and is sometimes called with the page | |||
274 | not locked. | 300 | not locked. |
275 | 301 | ||
276 | ->bmap() is currently used by legacy ioctl() (FIBMAP) provided by some | 302 | ->bmap() is currently used by legacy ioctl() (FIBMAP) provided by some |
277 | filesystems and by the swapper. The latter will eventually go away. All | 303 | filesystems and by the swapper. The latter will eventually go away. Please, |
278 | instances do not actually need the BKL. Please, keep it that way and don't | 304 | keep it that way and don't breed new callers. |
279 | breed new callers. | ||
280 | 305 | ||
281 | ->invalidatepage() is called when the filesystem must attempt to drop | 306 | ->invalidatepage() is called when the filesystem must attempt to drop |
282 | some or all of the buffers from the page when it is being truncated. It | 307 | some or all of the buffers from the page when it is being truncated. It |
@@ -288,53 +313,46 @@ buffers from the page in preparation for freeing it. It returns zero to | |||
288 | indicate that the buffers are (or may be) freeable. If ->releasepage is zero, | 313 | indicate that the buffers are (or may be) freeable. If ->releasepage is zero, |
289 | the kernel assumes that the fs has no private interest in the buffers. | 314 | the kernel assumes that the fs has no private interest in the buffers. |
290 | 315 | ||
316 | ->freepage() is called when the kernel is done dropping the page | ||
317 | from the page cache. | ||
318 | |||
291 | ->launder_page() may be called prior to releasing a page if | 319 | ->launder_page() may be called prior to releasing a page if |
292 | it is still found to be dirty. It returns zero if the page was successfully | 320 | it is still found to be dirty. It returns zero if the page was successfully |
293 | cleaned, or an error value if not. Note that in order to prevent the page | 321 | cleaned, or an error value if not. Note that in order to prevent the page |
294 | getting mapped back in and redirtied, it needs to be kept locked | 322 | getting mapped back in and redirtied, it needs to be kept locked |
295 | across the entire operation. | 323 | across the entire operation. |
296 | 324 | ||
297 | Note: currently almost all instances of address_space methods are | ||
298 | using BKL for internal serialization and that's one of the worst sources | ||
299 | of contention. Normally they are calling library functions (in fs/buffer.c) | ||
300 | and pass foo_get_block() as a callback (on local block-based filesystems, | ||
301 | indeed). BKL is not needed for library stuff and is usually taken by | ||
302 | foo_get_block(). It's an overkill, since block bitmaps can be protected by | ||
303 | internal fs locking and real critical areas are much smaller than the areas | ||
304 | filesystems protect now. | ||
305 | |||
306 | ----------------------- file_lock_operations ------------------------------ | 325 | ----------------------- file_lock_operations ------------------------------ |
307 | prototypes: | 326 | prototypes: |
308 | void (*fl_insert)(struct file_lock *); /* lock insertion callback */ | ||
309 | void (*fl_remove)(struct file_lock *); /* lock removal callback */ | ||
310 | void (*fl_copy_lock)(struct file_lock *, struct file_lock *); | 327 | void (*fl_copy_lock)(struct file_lock *, struct file_lock *); |
311 | void (*fl_release_private)(struct file_lock *); | 328 | void (*fl_release_private)(struct file_lock *); |
312 | 329 | ||
313 | 330 | ||
314 | locking rules: | 331 | locking rules: |
315 | BKL may block | 332 | file_lock_lock may block |
316 | fl_insert: yes no | 333 | fl_copy_lock: yes no |
317 | fl_remove: yes no | 334 | fl_release_private: maybe no |
318 | fl_copy_lock: yes no | ||
319 | fl_release_private: yes yes | ||
320 | 335 | ||
321 | ----------------------- lock_manager_operations --------------------------- | 336 | ----------------------- lock_manager_operations --------------------------- |
322 | prototypes: | 337 | prototypes: |
323 | int (*fl_compare_owner)(struct file_lock *, struct file_lock *); | 338 | int (*fl_compare_owner)(struct file_lock *, struct file_lock *); |
324 | void (*fl_notify)(struct file_lock *); /* unblock callback */ | 339 | void (*fl_notify)(struct file_lock *); /* unblock callback */ |
340 | int (*fl_grant)(struct file_lock *, struct file_lock *, int); | ||
325 | void (*fl_release_private)(struct file_lock *); | 341 | void (*fl_release_private)(struct file_lock *); |
326 | void (*fl_break)(struct file_lock *); /* break_lease callback */ | 342 | void (*fl_break)(struct file_lock *); /* break_lease callback */ |
343 | int (*fl_mylease)(struct file_lock *, struct file_lock *); | ||
344 | int (*fl_change)(struct file_lock **, int); | ||
327 | 345 | ||
328 | locking rules: | 346 | locking rules: |
329 | BKL may block | 347 | file_lock_lock may block |
330 | fl_compare_owner: yes no | 348 | fl_compare_owner: yes no |
331 | fl_notify: yes no | 349 | fl_notify: yes no |
332 | fl_release_private: yes yes | 350 | fl_grant: no no |
333 | fl_break: yes no | 351 | fl_release_private: maybe no |
334 | 352 | fl_break: yes no | |
335 | Currently only NFSD and NLM provide instances of this class. None of the | 353 | fl_mylease: yes no |
336 | them block. If you have out-of-tree instances - please, show up. Locking | 354 | fl_change yes no |
337 | in that area will change. | 355 | |
338 | --------------------------- buffer_head ----------------------------------- | 356 | --------------------------- buffer_head ----------------------------------- |
339 | prototypes: | 357 | prototypes: |
340 | void (*b_end_io)(struct buffer_head *bh, int uptodate); | 358 | void (*b_end_io)(struct buffer_head *bh, int uptodate); |
@@ -359,17 +377,17 @@ prototypes: | |||
359 | void (*swap_slot_free_notify) (struct block_device *, unsigned long); | 377 | void (*swap_slot_free_notify) (struct block_device *, unsigned long); |
360 | 378 | ||
361 | locking rules: | 379 | locking rules: |
362 | BKL bd_mutex | 380 | bd_mutex |
363 | open: no yes | 381 | open: yes |
364 | release: no yes | 382 | release: yes |
365 | ioctl: no no | 383 | ioctl: no |
366 | compat_ioctl: no no | 384 | compat_ioctl: no |
367 | direct_access: no no | 385 | direct_access: no |
368 | media_changed: no no | 386 | media_changed: no |
369 | unlock_native_capacity: no no | 387 | unlock_native_capacity: no |
370 | revalidate_disk: no no | 388 | revalidate_disk: no |
371 | getgeo: no no | 389 | getgeo: no |
372 | swap_slot_free_notify: no no (see below) | 390 | swap_slot_free_notify: no (see below) |
373 | 391 | ||
374 | media_changed, unlock_native_capacity and revalidate_disk are called only from | 392 | media_changed, unlock_native_capacity and revalidate_disk are called only from |
375 | check_disk_change(). | 393 | check_disk_change(). |
@@ -408,34 +426,21 @@ prototypes: | |||
408 | unsigned long (*get_unmapped_area)(struct file *, unsigned long, | 426 | unsigned long (*get_unmapped_area)(struct file *, unsigned long, |
409 | unsigned long, unsigned long, unsigned long); | 427 | unsigned long, unsigned long, unsigned long); |
410 | int (*check_flags)(int); | 428 | int (*check_flags)(int); |
429 | int (*flock) (struct file *, int, struct file_lock *); | ||
430 | ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, | ||
431 | size_t, unsigned int); | ||
432 | ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, | ||
433 | size_t, unsigned int); | ||
434 | int (*setlease)(struct file *, long, struct file_lock **); | ||
411 | }; | 435 | }; |
412 | 436 | ||
413 | locking rules: | 437 | locking rules: |
414 | All may block. | 438 | All may block except for ->setlease. |
415 | BKL | 439 | No VFS locks held on entry except for ->fsync and ->setlease. |
416 | llseek: no (see below) | 440 | |
417 | read: no | 441 | ->fsync() has i_mutex on inode. |
418 | aio_read: no | 442 | |
419 | write: no | 443 | ->setlease has the file_list_lock held and must not sleep. |
420 | aio_write: no | ||
421 | readdir: no | ||
422 | poll: no | ||
423 | unlocked_ioctl: no | ||
424 | compat_ioctl: no | ||
425 | mmap: no | ||
426 | open: no | ||
427 | flush: no | ||
428 | release: no | ||
429 | fsync: no (see below) | ||
430 | aio_fsync: no | ||
431 | fasync: no | ||
432 | lock: yes | ||
433 | readv: no | ||
434 | writev: no | ||
435 | sendfile: no | ||
436 | sendpage: no | ||
437 | get_unmapped_area: no | ||
438 | check_flags: no | ||
439 | 444 | ||
440 | ->llseek() locking has moved from llseek to the individual llseek | 445 | ->llseek() locking has moved from llseek to the individual llseek |
441 | implementations. If your fs is not using generic_file_llseek, you | 446 | implementations. If your fs is not using generic_file_llseek, you |
@@ -445,17 +450,10 @@ mutex or just to use i_size_read() instead. | |||
445 | Note: this does not protect the file->f_pos against concurrent modifications | 450 | Note: this does not protect the file->f_pos against concurrent modifications |
446 | since this is something the userspace has to take care about. | 451 | since this is something the userspace has to take care about. |
447 | 452 | ||
448 | Note: ext2_release() was *the* source of contention on fs-intensive | 453 | ->fasync() is responsible for maintaining the FASYNC bit in filp->f_flags. |
449 | loads and dropping BKL on ->release() helps to get rid of that (we still | 454 | Most instances call fasync_helper(), which does that maintenance, so it's |
450 | grab BKL for cases when we close a file that had been opened r/w, but that | 455 | not normally something one needs to worry about. Return values > 0 will be |
451 | can and should be done using the internal locking with smaller critical areas). | 456 | mapped to zero in the VFS layer. |
452 | Current worst offender is ext2_get_block()... | ||
453 | |||
454 | ->fasync() is called without BKL protection, and is responsible for | ||
455 | maintaining the FASYNC bit in filp->f_flags. Most instances call | ||
456 | fasync_helper(), which does that maintenance, so it's not normally | ||
457 | something one needs to worry about. Return values > 0 will be mapped to | ||
458 | zero in the VFS layer. | ||
459 | 457 | ||
460 | ->readdir() and ->ioctl() on directories must be changed. Ideally we would | 458 | ->readdir() and ->ioctl() on directories must be changed. Ideally we would |
461 | move ->readdir() to inode_operations and use a separate method for directory | 459 | move ->readdir() to inode_operations and use a separate method for directory |
@@ -466,8 +464,6 @@ components. And there are other reasons why the current interface is a mess... | |||
466 | ->read on directories probably must go away - we should just enforce -EISDIR | 464 | ->read on directories probably must go away - we should just enforce -EISDIR |
467 | in sys_read() and friends. | 465 | in sys_read() and friends. |
468 | 466 | ||
469 | ->fsync() has i_mutex on inode. | ||
470 | |||
471 | --------------------------- dquot_operations ------------------------------- | 467 | --------------------------- dquot_operations ------------------------------- |
472 | prototypes: | 468 | prototypes: |
473 | int (*write_dquot) (struct dquot *); | 469 | int (*write_dquot) (struct dquot *); |
@@ -502,12 +498,12 @@ prototypes: | |||
502 | int (*access)(struct vm_area_struct *, unsigned long, void*, int, int); | 498 | int (*access)(struct vm_area_struct *, unsigned long, void*, int, int); |
503 | 499 | ||
504 | locking rules: | 500 | locking rules: |
505 | BKL mmap_sem PageLocked(page) | 501 | mmap_sem PageLocked(page) |
506 | open: no yes | 502 | open: yes |
507 | close: no yes | 503 | close: yes |
508 | fault: no yes can return with page locked | 504 | fault: yes can return with page locked |
509 | page_mkwrite: no yes can return with page locked | 505 | page_mkwrite: yes can return with page locked |
510 | access: no yes | 506 | access: yes |
511 | 507 | ||
512 | ->fault() is called when a previously not present pte is about | 508 | ->fault() is called when a previously not present pte is about |
513 | to be faulted in. The filesystem must find and return the page associated | 509 | to be faulted in. The filesystem must find and return the page associated |
@@ -534,6 +530,3 @@ VM_IO | VM_PFNMAP VMAs. | |||
534 | 530 | ||
535 | (if you break something or notice that it is broken and do not fix it yourself | 531 | (if you break something or notice that it is broken and do not fix it yourself |
536 | - at least put it here) | 532 | - at least put it here) |
537 | |||
538 | ipc/shm.c::shm_delete() - may need BKL. | ||
539 | ->read() and ->write() in many drivers are (probably) missing BKL. | ||
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 55c28b79d8dc..20899e095e7e 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt | |||
@@ -534,6 +534,7 @@ struct address_space_operations { | |||
534 | sector_t (*bmap)(struct address_space *, sector_t); | 534 | sector_t (*bmap)(struct address_space *, sector_t); |
535 | int (*invalidatepage) (struct page *, unsigned long); | 535 | int (*invalidatepage) (struct page *, unsigned long); |
536 | int (*releasepage) (struct page *, int); | 536 | int (*releasepage) (struct page *, int); |
537 | void (*freepage)(struct page *); | ||
537 | ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov, | 538 | ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov, |
538 | loff_t offset, unsigned long nr_segs); | 539 | loff_t offset, unsigned long nr_segs); |
539 | struct page* (*get_xip_page)(struct address_space *, sector_t, | 540 | struct page* (*get_xip_page)(struct address_space *, sector_t, |
@@ -678,6 +679,12 @@ struct address_space_operations { | |||
678 | need to ensure this. Possibly it can clear the PageUptodate | 679 | need to ensure this. Possibly it can clear the PageUptodate |
679 | bit if it cannot free private data yet. | 680 | bit if it cannot free private data yet. |
680 | 681 | ||
682 | freepage: freepage is called once the page is no longer visible in | ||
683 | the page cache in order to allow the cleanup of any private | ||
684 | data. Since it may be called by the memory reclaimer, it | ||
685 | should not assume that the original address_space mapping still | ||
686 | exists, and it should not block. | ||
687 | |||
681 | direct_IO: called by the generic read/write routines to perform | 688 | direct_IO: called by the generic read/write routines to perform |
682 | direct_IO - that is IO requests which bypass the page cache | 689 | direct_IO - that is IO requests which bypass the page cache |
683 | and transfer data directly between the storage and the | 690 | and transfer data directly between the storage and the |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index cdd2a6e8a3b7..01ece1b9213e 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1759,7 +1759,7 @@ and is between 256 and 4096 characters. It is defined in the file | |||
1759 | 1759 | ||
1760 | nousb [USB] Disable the USB subsystem | 1760 | nousb [USB] Disable the USB subsystem |
1761 | 1761 | ||
1762 | nowatchdog [KNL] Disable the lockup detector. | 1762 | nowatchdog [KNL] Disable the lockup detector (NMI watchdog). |
1763 | 1763 | ||
1764 | nowb [ARM] | 1764 | nowb [ARM] |
1765 | 1765 | ||
@@ -2175,11 +2175,6 @@ and is between 256 and 4096 characters. It is defined in the file | |||
2175 | reset_devices [KNL] Force drivers to reset the underlying device | 2175 | reset_devices [KNL] Force drivers to reset the underlying device |
2176 | during initialization. | 2176 | during initialization. |
2177 | 2177 | ||
2178 | resource_alloc_from_bottom | ||
2179 | Allocate new resources from the beginning of available | ||
2180 | space, not the end. If you need to use this, please | ||
2181 | report a bug. | ||
2182 | |||
2183 | resume= [SWSUSP] | 2178 | resume= [SWSUSP] |
2184 | Specify the partition device for software suspend | 2179 | Specify the partition device for software suspend |
2185 | 2180 | ||
diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt index 489e9bacd165..41cc7b30d7dd 100644 --- a/Documentation/power/runtime_pm.txt +++ b/Documentation/power/runtime_pm.txt | |||
@@ -379,8 +379,8 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: | |||
379 | zero) | 379 | zero) |
380 | 380 | ||
381 | bool pm_runtime_suspended(struct device *dev); | 381 | bool pm_runtime_suspended(struct device *dev); |
382 | - return true if the device's runtime PM status is 'suspended', or false | 382 | - return true if the device's runtime PM status is 'suspended' and its |
383 | otherwise | 383 | 'power.disable_depth' field is equal to zero, or false otherwise |
384 | 384 | ||
385 | void pm_runtime_allow(struct device *dev); | 385 | void pm_runtime_allow(struct device *dev); |
386 | - set the power.runtime_auto flag for the device and decrease its usage | 386 | - set the power.runtime_auto flag for the device and decrease its usage |
diff --git a/Documentation/scsi/scsi_mid_low_api.txt b/Documentation/scsi/scsi_mid_low_api.txt index 570ef2b3d79b..df322c103466 100644 --- a/Documentation/scsi/scsi_mid_low_api.txt +++ b/Documentation/scsi/scsi_mid_low_api.txt | |||
@@ -1044,9 +1044,9 @@ Details: | |||
1044 | 1044 | ||
1045 | 1045 | ||
1046 | /** | 1046 | /** |
1047 | * queuecommand - queue scsi command, invoke 'done' on completion | 1047 | * queuecommand - queue scsi command, invoke scp->scsi_done on completion |
1048 | * @shost: pointer to the scsi host object | ||
1048 | * @scp: pointer to scsi command object | 1049 | * @scp: pointer to scsi command object |
1049 | * @done: function pointer to be invoked on completion | ||
1050 | * | 1050 | * |
1051 | * Returns 0 on success. | 1051 | * Returns 0 on success. |
1052 | * | 1052 | * |
@@ -1074,42 +1074,45 @@ Details: | |||
1074 | * | 1074 | * |
1075 | * Other types of errors that are detected immediately may be | 1075 | * Other types of errors that are detected immediately may be |
1076 | * flagged by setting scp->result to an appropriate value, | 1076 | * flagged by setting scp->result to an appropriate value, |
1077 | * invoking the 'done' callback, and then returning 0 from this | 1077 | * invoking the scp->scsi_done callback, and then returning 0 |
1078 | * function. If the command is not performed immediately (and the | 1078 | * from this function. If the command is not performed |
1079 | * LLD is starting (or will start) the given command) then this | 1079 | * immediately (and the LLD is starting (or will start) the given |
1080 | * function should place 0 in scp->result and return 0. | 1080 | * command) then this function should place 0 in scp->result and |
1081 | * return 0. | ||
1081 | * | 1082 | * |
1082 | * Command ownership. If the driver returns zero, it owns the | 1083 | * Command ownership. If the driver returns zero, it owns the |
1083 | * command and must take responsibility for ensuring the 'done' | 1084 | * command and must take responsibility for ensuring the |
1084 | * callback is executed. Note: the driver may call done before | 1085 | * scp->scsi_done callback is executed. Note: the driver may |
1085 | * returning zero, but after it has called done, it may not | 1086 | * call scp->scsi_done before returning zero, but after it has |
1086 | * return any value other than zero. If the driver makes a | 1087 | * called scp->scsi_done, it may not return any value other than |
1087 | * non-zero return, it must not execute the command's done | 1088 | * zero. If the driver makes a non-zero return, it must not |
1088 | * callback at any time. | 1089 | * execute the command's scsi_done callback at any time. |
1089 | * | 1090 | * |
1090 | * Locks: struct Scsi_Host::host_lock held on entry (with "irqsave") | 1091 | * Locks: up to and including 2.6.36, struct Scsi_Host::host_lock |
1091 | * and is expected to be held on return. | 1092 | * held on entry (with "irqsave") and is expected to be |
1093 | * held on return. From 2.6.37 onwards, queuecommand is | ||
1094 | * called without any locks held. | ||
1092 | * | 1095 | * |
1093 | * Calling context: in interrupt (soft irq) or process context | 1096 | * Calling context: in interrupt (soft irq) or process context |
1094 | * | 1097 | * |
1095 | * Notes: This function should be relatively fast. Normally it will | 1098 | * Notes: This function should be relatively fast. Normally it |
1096 | * not wait for IO to complete. Hence the 'done' callback is invoked | 1099 | * will not wait for IO to complete. Hence the scp->scsi_done |
1097 | * (often directly from an interrupt service routine) some time after | 1100 | * callback is invoked (often directly from an interrupt service |
1098 | * this function has returned. In some cases (e.g. pseudo adapter | 1101 | * routine) some time after this function has returned. In some |
1099 | * drivers that manufacture the response to a SCSI INQUIRY) | 1102 | * cases (e.g. pseudo adapter drivers that manufacture the |
1100 | * the 'done' callback may be invoked before this function returns. | 1103 | * response to a SCSI INQUIRY) the scp->scsi_done callback may be |
1101 | * If the 'done' callback is not invoked within a certain period | 1104 | * invoked before this function returns. If the scp->scsi_done |
1102 | * the SCSI mid level will commence error processing. | 1105 | * callback is not invoked within a certain period the SCSI mid |
1103 | * If a status of CHECK CONDITION is placed in "result" when the | 1106 | * level will commence error processing. If a status of CHECK |
1104 | * 'done' callback is invoked, then the LLD driver should | 1107 | * CONDITION is placed in "result" when the scp->scsi_done |
1105 | * perform autosense and fill in the struct scsi_cmnd::sense_buffer | 1108 | * callback is invoked, then the LLD driver should perform |
1109 | * autosense and fill in the struct scsi_cmnd::sense_buffer | ||
1106 | * array. The scsi_cmnd::sense_buffer array is zeroed prior to | 1110 | * array. The scsi_cmnd::sense_buffer array is zeroed prior to |
1107 | * the mid level queuing a command to an LLD. | 1111 | * the mid level queuing a command to an LLD. |
1108 | * | 1112 | * |
1109 | * Defined in: LLD | 1113 | * Defined in: LLD |
1110 | **/ | 1114 | **/ |
1111 | int queuecommand(struct scsi_cmnd * scp, | 1115 | int queuecommand(struct Scsi_Host *shost, struct scsi_cmnd * scp) |
1112 | void (*done)(struct scsi_cmnd *)) | ||
1113 | 1116 | ||
1114 | 1117 | ||
1115 | /** | 1118 | /** |
diff --git a/Documentation/trace/postprocess/trace-vmscan-postprocess.pl b/Documentation/trace/postprocess/trace-vmscan-postprocess.pl index b3e73ddb1567..12cecc83cd91 100644 --- a/Documentation/trace/postprocess/trace-vmscan-postprocess.pl +++ b/Documentation/trace/postprocess/trace-vmscan-postprocess.pl | |||
@@ -373,9 +373,18 @@ EVENT_PROCESS: | |||
373 | print " $regex_lru_isolate/o\n"; | 373 | print " $regex_lru_isolate/o\n"; |
374 | next; | 374 | next; |
375 | } | 375 | } |
376 | my $isolate_mode = $1; | ||
376 | my $nr_scanned = $4; | 377 | my $nr_scanned = $4; |
377 | my $nr_contig_dirty = $7; | 378 | my $nr_contig_dirty = $7; |
378 | $perprocesspid{$process_pid}->{HIGH_NR_SCANNED} += $nr_scanned; | 379 | |
380 | # To closer match vmstat scanning statistics, only count isolate_both | ||
381 | # and isolate_inactive as scanning. isolate_active is rotation | ||
382 | # isolate_inactive == 0 | ||
383 | # isolate_active == 1 | ||
384 | # isolate_both == 2 | ||
385 | if ($isolate_mode != 1) { | ||
386 | $perprocesspid{$process_pid}->{HIGH_NR_SCANNED} += $nr_scanned; | ||
387 | } | ||
379 | $perprocesspid{$process_pid}->{HIGH_NR_CONTIG_DIRTY} += $nr_contig_dirty; | 388 | $perprocesspid{$process_pid}->{HIGH_NR_CONTIG_DIRTY} += $nr_contig_dirty; |
380 | } elsif ($tracepoint eq "mm_vmscan_lru_shrink_inactive") { | 389 | } elsif ($tracepoint eq "mm_vmscan_lru_shrink_inactive") { |
381 | $details = $5; | 390 | $details = $5; |
diff --git a/MAINTAINERS b/MAINTAINERS index 1a1c27b9c557..7585e9dd835b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -405,7 +405,7 @@ S: Supported | |||
405 | F: drivers/usb/gadget/amd5536udc.* | 405 | F: drivers/usb/gadget/amd5536udc.* |
406 | 406 | ||
407 | AMD GEODE PROCESSOR/CHIPSET SUPPORT | 407 | AMD GEODE PROCESSOR/CHIPSET SUPPORT |
408 | P: Jordan Crouse | 408 | P: Andres Salomon <dilinger@queued.net> |
409 | L: linux-geode@lists.infradead.org (moderated for non-subscribers) | 409 | L: linux-geode@lists.infradead.org (moderated for non-subscribers) |
410 | W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html | 410 | W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html |
411 | S: Supported | 411 | S: Supported |
@@ -559,14 +559,14 @@ W: http://maxim.org.za/at91_26.html | |||
559 | S: Maintained | 559 | S: Maintained |
560 | 560 | ||
561 | ARM/BCMRING ARM ARCHITECTURE | 561 | ARM/BCMRING ARM ARCHITECTURE |
562 | M: Leo Chen <leochen@broadcom.com> | 562 | M: Jiandong Zheng <jdzheng@broadcom.com> |
563 | M: Scott Branden <sbranden@broadcom.com> | 563 | M: Scott Branden <sbranden@broadcom.com> |
564 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 564 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
565 | S: Maintained | 565 | S: Maintained |
566 | F: arch/arm/mach-bcmring | 566 | F: arch/arm/mach-bcmring |
567 | 567 | ||
568 | ARM/BCMRING MTD NAND DRIVER | 568 | ARM/BCMRING MTD NAND DRIVER |
569 | M: Leo Chen <leochen@broadcom.com> | 569 | M: Jiandong Zheng <jdzheng@broadcom.com> |
570 | M: Scott Branden <sbranden@broadcom.com> | 570 | M: Scott Branden <sbranden@broadcom.com> |
571 | L: linux-mtd@lists.infradead.org | 571 | L: linux-mtd@lists.infradead.org |
572 | S: Maintained | 572 | S: Maintained |
@@ -792,11 +792,14 @@ S: Maintained | |||
792 | 792 | ||
793 | ARM/NOMADIK ARCHITECTURE | 793 | ARM/NOMADIK ARCHITECTURE |
794 | M: Alessandro Rubini <rubini@unipv.it> | 794 | M: Alessandro Rubini <rubini@unipv.it> |
795 | M: Linus Walleij <linus.walleij@stericsson.com> | ||
795 | M: STEricsson <STEricsson_nomadik_linux@list.st.com> | 796 | M: STEricsson <STEricsson_nomadik_linux@list.st.com> |
796 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 797 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
797 | S: Maintained | 798 | S: Maintained |
798 | F: arch/arm/mach-nomadik/ | 799 | F: arch/arm/mach-nomadik/ |
799 | F: arch/arm/plat-nomadik/ | 800 | F: arch/arm/plat-nomadik/ |
801 | F: drivers/i2c/busses/i2c-nomadik.c | ||
802 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git | ||
800 | 803 | ||
801 | ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT | 804 | ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT |
802 | M: Nelson Castillo <arhuaco@freaks-unidos.net> | 805 | M: Nelson Castillo <arhuaco@freaks-unidos.net> |
@@ -815,7 +818,7 @@ F: drivers/mmc/host/msm_sdcc.c | |||
815 | F: drivers/mmc/host/msm_sdcc.h | 818 | F: drivers/mmc/host/msm_sdcc.h |
816 | F: drivers/serial/msm_serial.h | 819 | F: drivers/serial/msm_serial.h |
817 | F: drivers/serial/msm_serial.c | 820 | F: drivers/serial/msm_serial.c |
818 | T: git git://codeaurora.org/quic/kernel/dwalker/linux-msm.git | 821 | T: git git://codeaurora.org/quic/kernel/davidb/linux-msm.git |
819 | S: Maintained | 822 | S: Maintained |
820 | 823 | ||
821 | ARM/TOSA MACHINE SUPPORT | 824 | ARM/TOSA MACHINE SUPPORT |
@@ -998,12 +1001,24 @@ F: drivers/i2c/busses/i2c-stu300.c | |||
998 | F: drivers/rtc/rtc-coh901331.c | 1001 | F: drivers/rtc/rtc-coh901331.c |
999 | F: drivers/watchdog/coh901327_wdt.c | 1002 | F: drivers/watchdog/coh901327_wdt.c |
1000 | F: drivers/dma/coh901318* | 1003 | F: drivers/dma/coh901318* |
1004 | F: drivers/mfd/ab3100* | ||
1005 | F: drivers/rtc/rtc-ab3100.c | ||
1006 | F: drivers/rtc/rtc-coh901331.c | ||
1007 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git | ||
1001 | 1008 | ||
1002 | ARM/U8500 ARM ARCHITECTURE | 1009 | ARM/Ux500 ARM ARCHITECTURE |
1003 | M: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> | 1010 | M: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> |
1011 | M: Linus Walleij <linus.walleij@stericsson.com> | ||
1004 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 1012 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
1005 | S: Maintained | 1013 | S: Maintained |
1006 | F: arch/arm/mach-ux500/ | 1014 | F: arch/arm/mach-ux500/ |
1015 | F: drivers/dma/ste_dma40* | ||
1016 | F: drivers/mfd/ab3550* | ||
1017 | F: drivers/mfd/abx500* | ||
1018 | F: drivers/mfd/ab8500* | ||
1019 | F: drivers/mfd/stmpe* | ||
1020 | F: drivers/rtc/rtc-ab8500.c | ||
1021 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git | ||
1007 | 1022 | ||
1008 | ARM/VFP SUPPORT | 1023 | ARM/VFP SUPPORT |
1009 | M: Russell King <linux@arm.linux.org.uk> | 1024 | M: Russell King <linux@arm.linux.org.uk> |
@@ -4590,7 +4605,7 @@ F: drivers/pcmcia/ | |||
4590 | F: include/pcmcia/ | 4605 | F: include/pcmcia/ |
4591 | 4606 | ||
4592 | PCNET32 NETWORK DRIVER | 4607 | PCNET32 NETWORK DRIVER |
4593 | M: Don Fry <pcnet32@verizon.net> | 4608 | M: Don Fry <pcnet32@frontier.com> |
4594 | L: netdev@vger.kernel.org | 4609 | L: netdev@vger.kernel.org |
4595 | S: Maintained | 4610 | S: Maintained |
4596 | F: drivers/net/pcnet32.c | 4611 | F: drivers/net/pcnet32.c |
@@ -5932,7 +5947,6 @@ F: include/linux/tty.h | |||
5932 | 5947 | ||
5933 | TULIP NETWORK DRIVERS | 5948 | TULIP NETWORK DRIVERS |
5934 | M: Grant Grundler <grundler@parisc-linux.org> | 5949 | M: Grant Grundler <grundler@parisc-linux.org> |
5935 | M: Kyle McMartin <kyle@mcmartin.ca> | ||
5936 | L: netdev@vger.kernel.org | 5950 | L: netdev@vger.kernel.org |
5937 | S: Maintained | 5951 | S: Maintained |
5938 | F: drivers/net/tulip/ | 5952 | F: drivers/net/tulip/ |
@@ -6584,6 +6598,15 @@ F: include/linux/mfd/wm8400* | |||
6584 | F: include/sound/wm????.h | 6598 | F: include/sound/wm????.h |
6585 | F: sound/soc/codecs/wm* | 6599 | F: sound/soc/codecs/wm* |
6586 | 6600 | ||
6601 | WORKQUEUE | ||
6602 | M: Tejun Heo <tj@kernel.org> | ||
6603 | L: linux-kernel@vger.kernel.org | ||
6604 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq.git | ||
6605 | S: Maintained | ||
6606 | F: include/linux/workqueue.h | ||
6607 | F: kernel/workqueue.c | ||
6608 | F: Documentation/workqueue.txt | ||
6609 | |||
6587 | X.25 NETWORK LAYER | 6610 | X.25 NETWORK LAYER |
6588 | M: Andrew Hendry <andrew.hendry@gmail.com> | 6611 | M: Andrew Hendry <andrew.hendry@gmail.com> |
6589 | L: linux-x25@vger.kernel.org | 6612 | L: linux-x25@vger.kernel.org |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 2 | 1 | VERSION = 2 |
2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
3 | SUBLEVEL = 37 | 3 | SUBLEVEL = 37 |
4 | EXTRAVERSION = -rc5 | 4 | EXTRAVERSION = |
5 | NAME = Flesh-Eating Bats with Fangs | 5 | NAME = Flesh-Eating Bats with Fangs |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index f1d9297b1050..d56d21c0573b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -1311,7 +1311,7 @@ config HZ | |||
1311 | 1311 | ||
1312 | config THUMB2_KERNEL | 1312 | config THUMB2_KERNEL |
1313 | bool "Compile the kernel in Thumb-2 mode" | 1313 | bool "Compile the kernel in Thumb-2 mode" |
1314 | depends on CPU_V7 && EXPERIMENTAL | 1314 | depends on CPU_V7 && !CPU_V6 && EXPERIMENTAL |
1315 | select AEABI | 1315 | select AEABI |
1316 | select ARM_ASM_UNIFIED | 1316 | select ARM_ASM_UNIFIED |
1317 | help | 1317 | help |
@@ -1759,7 +1759,7 @@ comment "At least one emulation must be selected" | |||
1759 | 1759 | ||
1760 | config FPE_NWFPE | 1760 | config FPE_NWFPE |
1761 | bool "NWFPE math emulation" | 1761 | bool "NWFPE math emulation" |
1762 | depends on !AEABI || OABI_COMPAT | 1762 | depends on (!AEABI || OABI_COMPAT) && !THUMB2_KERNEL |
1763 | ---help--- | 1763 | ---help--- |
1764 | Say Y to include the NWFPE floating point emulator in the kernel. | 1764 | Say Y to include the NWFPE floating point emulator in the kernel. |
1765 | This is necessary to run most binaries. Linux does not currently | 1765 | This is necessary to run most binaries. Linux does not currently |
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c index 1bec96e85196..42ff90b46dfb 100644 --- a/arch/arm/common/it8152.c +++ b/arch/arm/common/it8152.c | |||
@@ -352,3 +352,4 @@ struct pci_bus * __init it8152_pci_scan_bus(int nr, struct pci_sys_data *sys) | |||
352 | return pci_scan_bus(nr, &it8152_ops, sys); | 352 | return pci_scan_bus(nr, &it8152_ops, sys); |
353 | } | 353 | } |
354 | 354 | ||
355 | EXPORT_SYMBOL(dma_set_coherent_mask); | ||
diff --git a/arch/arm/include/asm/hardware/it8152.h b/arch/arm/include/asm/hardware/it8152.h index 21fa272301f8..b2f95c72287c 100644 --- a/arch/arm/include/asm/hardware/it8152.h +++ b/arch/arm/include/asm/hardware/it8152.h | |||
@@ -76,6 +76,7 @@ extern unsigned long it8152_base_address; | |||
76 | IT8152_PD_IRQ(0) Audio controller (ACR) | 76 | IT8152_PD_IRQ(0) Audio controller (ACR) |
77 | */ | 77 | */ |
78 | #define IT8152_IRQ(x) (IRQ_BOARD_START + (x)) | 78 | #define IT8152_IRQ(x) (IRQ_BOARD_START + (x)) |
79 | #define IT8152_LAST_IRQ (IRQ_BOARD_START + 40) | ||
79 | 80 | ||
80 | /* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */ | 81 | /* IRQ-sources in 3 groups - local devices, LPC (serial), and external PCI */ |
81 | #define IT8152_LD_IRQ_COUNT 9 | 82 | #define IT8152_LD_IRQ_COUNT 9 |
diff --git a/arch/arm/include/asm/highmem.h b/arch/arm/include/asm/highmem.h index 1fc684e70ab6..7080e2c8fa62 100644 --- a/arch/arm/include/asm/highmem.h +++ b/arch/arm/include/asm/highmem.h | |||
@@ -25,9 +25,6 @@ extern void *kmap_high(struct page *page); | |||
25 | extern void *kmap_high_get(struct page *page); | 25 | extern void *kmap_high_get(struct page *page); |
26 | extern void kunmap_high(struct page *page); | 26 | extern void kunmap_high(struct page *page); |
27 | 27 | ||
28 | extern void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte); | ||
29 | extern void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte); | ||
30 | |||
31 | /* | 28 | /* |
32 | * The following functions are already defined by <linux/highmem.h> | 29 | * The following functions are already defined by <linux/highmem.h> |
33 | * when CONFIG_HIGHMEM is not set. | 30 | * when CONFIG_HIGHMEM is not set. |
diff --git a/arch/arm/include/asm/sizes.h b/arch/arm/include/asm/sizes.h index 4fc1565e4f93..316bb2b2be3d 100644 --- a/arch/arm/include/asm/sizes.h +++ b/arch/arm/include/asm/sizes.h | |||
@@ -13,9 +13,6 @@ | |||
13 | * along with this program; if not, write to the Free Software | 13 | * along with this program; if not, write to the Free Software |
14 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 14 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
15 | */ | 15 | */ |
16 | /* DO NOT EDIT!! - this file automatically generated | ||
17 | * from .s file by awk -f s2h.awk | ||
18 | */ | ||
19 | /* Size definitions | 16 | /* Size definitions |
20 | * Copyright (C) ARM Limited 1998. All rights reserved. | 17 | * Copyright (C) ARM Limited 1998. All rights reserved. |
21 | */ | 18 | */ |
@@ -25,6 +22,9 @@ | |||
25 | 22 | ||
26 | /* handy sizes */ | 23 | /* handy sizes */ |
27 | #define SZ_16 0x00000010 | 24 | #define SZ_16 0x00000010 |
25 | #define SZ_32 0x00000020 | ||
26 | #define SZ_64 0x00000040 | ||
27 | #define SZ_128 0x00000080 | ||
28 | #define SZ_256 0x00000100 | 28 | #define SZ_256 0x00000100 |
29 | #define SZ_512 0x00000200 | 29 | #define SZ_512 0x00000200 |
30 | 30 | ||
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 1120f18a6b17..80025948b8ad 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h | |||
@@ -150,6 +150,7 @@ extern unsigned int user_debug; | |||
150 | #define rmb() dmb() | 150 | #define rmb() dmb() |
151 | #define wmb() mb() | 151 | #define wmb() mb() |
152 | #else | 152 | #else |
153 | #include <asm/memory.h> | ||
153 | #define mb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) | 154 | #define mb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) |
154 | #define rmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) | 155 | #define rmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) |
155 | #define wmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) | 156 | #define wmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0) |
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S index 8bfa98757cd2..80bf8cd88d7c 100644 --- a/arch/arm/kernel/entry-common.S +++ b/arch/arm/kernel/entry-common.S | |||
@@ -29,6 +29,9 @@ ret_fast_syscall: | |||
29 | ldr r1, [tsk, #TI_FLAGS] | 29 | ldr r1, [tsk, #TI_FLAGS] |
30 | tst r1, #_TIF_WORK_MASK | 30 | tst r1, #_TIF_WORK_MASK |
31 | bne fast_work_pending | 31 | bne fast_work_pending |
32 | #if defined(CONFIG_IRQSOFF_TRACER) | ||
33 | asm_trace_hardirqs_on | ||
34 | #endif | ||
32 | 35 | ||
33 | /* perform architecture specific actions before user return */ | 36 | /* perform architecture specific actions before user return */ |
34 | arch_ret_to_user r1, lr | 37 | arch_ret_to_user r1, lr |
@@ -65,6 +68,9 @@ ret_slow_syscall: | |||
65 | tst r1, #_TIF_WORK_MASK | 68 | tst r1, #_TIF_WORK_MASK |
66 | bne work_pending | 69 | bne work_pending |
67 | no_work_pending: | 70 | no_work_pending: |
71 | #if defined(CONFIG_IRQSOFF_TRACER) | ||
72 | asm_trace_hardirqs_on | ||
73 | #endif | ||
68 | /* perform architecture specific actions before user return */ | 74 | /* perform architecture specific actions before user return */ |
69 | arch_ret_to_user r1, lr | 75 | arch_ret_to_user r1, lr |
70 | 76 | ||
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 8c1959590252..9066473c0ebc 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
@@ -310,7 +310,6 @@ asmlinkage void __cpuinit secondary_start_kernel(void) | |||
310 | * All kernel threads share the same mm context; grab a | 310 | * All kernel threads share the same mm context; grab a |
311 | * reference and switch to it. | 311 | * reference and switch to it. |
312 | */ | 312 | */ |
313 | atomic_inc(&mm->mm_users); | ||
314 | atomic_inc(&mm->mm_count); | 313 | atomic_inc(&mm->mm_count); |
315 | current->active_mm = mm; | 314 | current->active_mm = mm; |
316 | cpumask_set_cpu(cpu, mm_cpumask(mm)); | 315 | cpumask_set_cpu(cpu, mm_cpumask(mm)); |
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index 62d686f0b426..d13add71f72a 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile | |||
@@ -65,7 +65,7 @@ obj-$(CONFIG_MACH_AT91SAM9G20EK) += board-sam9g20ek.o | |||
65 | obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o | 65 | obj-$(CONFIG_MACH_CPU9G20) += board-cpu9krea.o |
66 | obj-$(CONFIG_MACH_STAMP9G20) += board-stamp9g20.o | 66 | obj-$(CONFIG_MACH_STAMP9G20) += board-stamp9g20.o |
67 | obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o | 67 | obj-$(CONFIG_MACH_PORTUXG20) += board-stamp9g20.o |
68 | obj-$(CONFIG_MACH_PCONTROL_G20) += board-pcontrol-g20.o | 68 | obj-$(CONFIG_MACH_PCONTROL_G20) += board-pcontrol-g20.o board-stamp9g20.o |
69 | 69 | ||
70 | # AT91SAM9260/AT91SAM9G20 board-specific support | 70 | # AT91SAM9260/AT91SAM9G20 board-specific support |
71 | obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o | 71 | obj-$(CONFIG_MACH_SNAPPER_9260) += board-snapper9260.o |
diff --git a/arch/arm/mach-at91/board-pcontrol-g20.c b/arch/arm/mach-at91/board-pcontrol-g20.c index bba5a560e02b..feb65787c30b 100644 --- a/arch/arm/mach-at91/board-pcontrol-g20.c +++ b/arch/arm/mach-at91/board-pcontrol-g20.c | |||
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | #include <mach/board.h> | 32 | #include <mach/board.h> |
33 | #include <mach/at91sam9_smc.h> | 33 | #include <mach/at91sam9_smc.h> |
34 | #include <mach/stamp9g20.h> | ||
34 | 35 | ||
35 | #include "sam9_smc.h" | 36 | #include "sam9_smc.h" |
36 | #include "generic.h" | 37 | #include "generic.h" |
@@ -38,11 +39,7 @@ | |||
38 | 39 | ||
39 | static void __init pcontrol_g20_map_io(void) | 40 | static void __init pcontrol_g20_map_io(void) |
40 | { | 41 | { |
41 | /* Initialize processor: 18.432 MHz crystal */ | 42 | stamp9g20_map_io(); |
42 | at91sam9260_initialize(18432000); | ||
43 | |||
44 | /* DGBU on ttyS0. (Rx, Tx) only TTL -> JTAG connector X7 17,19 ) */ | ||
45 | at91_register_uart(0, 0, 0); | ||
46 | 43 | ||
47 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) piggyback A2 */ | 44 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS) piggyback A2 */ |
48 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | 45 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS |
@@ -54,9 +51,6 @@ static void __init pcontrol_g20_map_io(void) | |||
54 | 51 | ||
55 | /* USART2 on ttyS3. (Rx, Tx) 9bit-Bus Multidrop-mode X4 */ | 52 | /* USART2 on ttyS3. (Rx, Tx) 9bit-Bus Multidrop-mode X4 */ |
56 | at91_register_uart(AT91SAM9260_ID_US4, 3, 0); | 53 | at91_register_uart(AT91SAM9260_ID_US4, 3, 0); |
57 | |||
58 | /* set serial console to ttyS0 (ie, DBGU) */ | ||
59 | at91_set_serial_console(0); | ||
60 | } | 54 | } |
61 | 55 | ||
62 | 56 | ||
@@ -66,38 +60,6 @@ static void __init init_irq(void) | |||
66 | } | 60 | } |
67 | 61 | ||
68 | 62 | ||
69 | /* | ||
70 | * NAND flash 512MiB 1,8V 8-bit, sector size 128 KiB | ||
71 | */ | ||
72 | static struct atmel_nand_data __initdata nand_data = { | ||
73 | .ale = 21, | ||
74 | .cle = 22, | ||
75 | .rdy_pin = AT91_PIN_PC13, | ||
76 | .enable_pin = AT91_PIN_PC14, | ||
77 | }; | ||
78 | |||
79 | /* | ||
80 | * Bus timings; unit = 7.57ns | ||
81 | */ | ||
82 | static struct sam9_smc_config __initdata nand_smc_config = { | ||
83 | .ncs_read_setup = 0, | ||
84 | .nrd_setup = 2, | ||
85 | .ncs_write_setup = 0, | ||
86 | .nwe_setup = 2, | ||
87 | |||
88 | .ncs_read_pulse = 4, | ||
89 | .nrd_pulse = 4, | ||
90 | .ncs_write_pulse = 4, | ||
91 | .nwe_pulse = 4, | ||
92 | |||
93 | .read_cycle = 7, | ||
94 | .write_cycle = 7, | ||
95 | |||
96 | .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | ||
97 | | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8, | ||
98 | .tdf_cycles = 3, | ||
99 | }; | ||
100 | |||
101 | static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { { | 63 | static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { { |
102 | .ncs_read_setup = 16, | 64 | .ncs_read_setup = 16, |
103 | .nrd_setup = 18, | 65 | .nrd_setup = 18, |
@@ -138,14 +100,6 @@ static struct sam9_smc_config __initdata pcontrol_smc_config[2] = { { | |||
138 | .tdf_cycles = 1, | 100 | .tdf_cycles = 1, |
139 | } }; | 101 | } }; |
140 | 102 | ||
141 | static void __init add_device_nand(void) | ||
142 | { | ||
143 | /* configure chip-select 3 (NAND) */ | ||
144 | sam9_smc_configure(3, &nand_smc_config); | ||
145 | at91_add_device_nand(&nand_data); | ||
146 | } | ||
147 | |||
148 | |||
149 | static void __init add_device_pcontrol(void) | 103 | static void __init add_device_pcontrol(void) |
150 | { | 104 | { |
151 | /* configure chip-select 4 (IO compatible to 8051 X4 ) */ | 105 | /* configure chip-select 4 (IO compatible to 8051 X4 ) */ |
@@ -156,23 +110,6 @@ static void __init add_device_pcontrol(void) | |||
156 | 110 | ||
157 | 111 | ||
158 | /* | 112 | /* |
159 | * MCI (SD/MMC) | ||
160 | * det_pin, wp_pin and vcc_pin are not connected | ||
161 | */ | ||
162 | #if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) | ||
163 | static struct mci_platform_data __initdata mmc_data = { | ||
164 | .slot[0] = { | ||
165 | .bus_width = 4, | ||
166 | }, | ||
167 | }; | ||
168 | #else | ||
169 | static struct at91_mmc_data __initdata mmc_data = { | ||
170 | .wire4 = 1, | ||
171 | }; | ||
172 | #endif | ||
173 | |||
174 | |||
175 | /* | ||
176 | * USB Host port | 113 | * USB Host port |
177 | */ | 114 | */ |
178 | static struct at91_usbh_data __initdata usbh_data = { | 115 | static struct at91_usbh_data __initdata usbh_data = { |
@@ -265,42 +202,13 @@ static struct spi_board_info pcontrol_g20_spi_devices[] = { | |||
265 | }; | 202 | }; |
266 | 203 | ||
267 | 204 | ||
268 | /* | ||
269 | * Dallas 1-Wire DS2431 | ||
270 | */ | ||
271 | static struct w1_gpio_platform_data w1_gpio_pdata = { | ||
272 | .pin = AT91_PIN_PA29, | ||
273 | .is_open_drain = 1, | ||
274 | }; | ||
275 | |||
276 | static struct platform_device w1_device = { | ||
277 | .name = "w1-gpio", | ||
278 | .id = -1, | ||
279 | .dev.platform_data = &w1_gpio_pdata, | ||
280 | }; | ||
281 | |||
282 | static void add_wire1(void) | ||
283 | { | ||
284 | at91_set_GPIO_periph(w1_gpio_pdata.pin, 1); | ||
285 | at91_set_multi_drive(w1_gpio_pdata.pin, 1); | ||
286 | platform_device_register(&w1_device); | ||
287 | } | ||
288 | |||
289 | |||
290 | static void __init pcontrol_g20_board_init(void) | 205 | static void __init pcontrol_g20_board_init(void) |
291 | { | 206 | { |
292 | at91_add_device_serial(); | 207 | stamp9g20_board_init(); |
293 | add_device_nand(); | ||
294 | #if defined(CONFIG_MMC_ATMELMCI) || defined(CONFIG_MMC_ATMELMCI_MODULE) | ||
295 | at91_add_device_mci(0, &mmc_data); | ||
296 | #else | ||
297 | at91_add_device_mmc(0, &mmc_data); | ||
298 | #endif | ||
299 | at91_add_device_usbh(&usbh_data); | 208 | at91_add_device_usbh(&usbh_data); |
300 | at91_add_device_eth(&macb_data); | 209 | at91_add_device_eth(&macb_data); |
301 | at91_add_device_i2c(pcontrol_g20_i2c_devices, | 210 | at91_add_device_i2c(pcontrol_g20_i2c_devices, |
302 | ARRAY_SIZE(pcontrol_g20_i2c_devices)); | 211 | ARRAY_SIZE(pcontrol_g20_i2c_devices)); |
303 | add_wire1(); | ||
304 | add_device_pcontrol(); | 212 | add_device_pcontrol(); |
305 | at91_add_device_spi(pcontrol_g20_spi_devices, | 213 | at91_add_device_spi(pcontrol_g20_spi_devices, |
306 | ARRAY_SIZE(pcontrol_g20_spi_devices)); | 214 | ARRAY_SIZE(pcontrol_g20_spi_devices)); |
diff --git a/arch/arm/mach-at91/board-stamp9g20.c b/arch/arm/mach-at91/board-stamp9g20.c index 5206eef4a67e..f8902b118960 100644 --- a/arch/arm/mach-at91/board-stamp9g20.c +++ b/arch/arm/mach-at91/board-stamp9g20.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include "generic.h" | 32 | #include "generic.h" |
33 | 33 | ||
34 | 34 | ||
35 | static void __init portuxg20_map_io(void) | 35 | void __init stamp9g20_map_io(void) |
36 | { | 36 | { |
37 | /* Initialize processor: 18.432 MHz crystal */ | 37 | /* Initialize processor: 18.432 MHz crystal */ |
38 | at91sam9260_initialize(18432000); | 38 | at91sam9260_initialize(18432000); |
@@ -40,6 +40,24 @@ static void __init portuxg20_map_io(void) | |||
40 | /* DGBU on ttyS0. (Rx & Tx only) */ | 40 | /* DGBU on ttyS0. (Rx & Tx only) */ |
41 | at91_register_uart(0, 0, 0); | 41 | at91_register_uart(0, 0, 0); |
42 | 42 | ||
43 | /* set serial console to ttyS0 (ie, DBGU) */ | ||
44 | at91_set_serial_console(0); | ||
45 | } | ||
46 | |||
47 | static void __init stamp9g20evb_map_io(void) | ||
48 | { | ||
49 | stamp9g20_map_io(); | ||
50 | |||
51 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ | ||
52 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS | ||
53 | | ATMEL_UART_DTR | ATMEL_UART_DSR | ||
54 | | ATMEL_UART_DCD | ATMEL_UART_RI); | ||
55 | } | ||
56 | |||
57 | static void __init portuxg20_map_io(void) | ||
58 | { | ||
59 | stamp9g20_map_io(); | ||
60 | |||
43 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ | 61 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ |
44 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS | 62 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS |
45 | | ATMEL_UART_DTR | ATMEL_UART_DSR | 63 | | ATMEL_UART_DTR | ATMEL_UART_DSR |
@@ -56,26 +74,6 @@ static void __init portuxg20_map_io(void) | |||
56 | 74 | ||
57 | /* USART5 on ttyS6. (Rx, Tx only) */ | 75 | /* USART5 on ttyS6. (Rx, Tx only) */ |
58 | at91_register_uart(AT91SAM9260_ID_US5, 6, 0); | 76 | at91_register_uart(AT91SAM9260_ID_US5, 6, 0); |
59 | |||
60 | /* set serial console to ttyS0 (ie, DBGU) */ | ||
61 | at91_set_serial_console(0); | ||
62 | } | ||
63 | |||
64 | static void __init stamp9g20_map_io(void) | ||
65 | { | ||
66 | /* Initialize processor: 18.432 MHz crystal */ | ||
67 | at91sam9260_initialize(18432000); | ||
68 | |||
69 | /* DGBU on ttyS0. (Rx & Tx only) */ | ||
70 | at91_register_uart(0, 0, 0); | ||
71 | |||
72 | /* USART0 on ttyS1. (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI) */ | ||
73 | at91_register_uart(AT91SAM9260_ID_US0, 1, ATMEL_UART_CTS | ATMEL_UART_RTS | ||
74 | | ATMEL_UART_DTR | ATMEL_UART_DSR | ||
75 | | ATMEL_UART_DCD | ATMEL_UART_RI); | ||
76 | |||
77 | /* set serial console to ttyS0 (ie, DBGU) */ | ||
78 | at91_set_serial_console(0); | ||
79 | } | 77 | } |
80 | 78 | ||
81 | static void __init init_irq(void) | 79 | static void __init init_irq(void) |
@@ -156,7 +154,7 @@ static struct at91_udc_data __initdata portuxg20_udc_data = { | |||
156 | .pullup_pin = 0, /* pull-up driven by UDC */ | 154 | .pullup_pin = 0, /* pull-up driven by UDC */ |
157 | }; | 155 | }; |
158 | 156 | ||
159 | static struct at91_udc_data __initdata stamp9g20_udc_data = { | 157 | static struct at91_udc_data __initdata stamp9g20evb_udc_data = { |
160 | .vbus_pin = AT91_PIN_PA22, | 158 | .vbus_pin = AT91_PIN_PA22, |
161 | .pullup_pin = 0, /* pull-up driven by UDC */ | 159 | .pullup_pin = 0, /* pull-up driven by UDC */ |
162 | }; | 160 | }; |
@@ -190,7 +188,7 @@ static struct gpio_led portuxg20_leds[] = { | |||
190 | } | 188 | } |
191 | }; | 189 | }; |
192 | 190 | ||
193 | static struct gpio_led stamp9g20_leds[] = { | 191 | static struct gpio_led stamp9g20evb_leds[] = { |
194 | { | 192 | { |
195 | .name = "D8", | 193 | .name = "D8", |
196 | .gpio = AT91_PIN_PB18, | 194 | .gpio = AT91_PIN_PB18, |
@@ -250,7 +248,7 @@ void add_w1(void) | |||
250 | } | 248 | } |
251 | 249 | ||
252 | 250 | ||
253 | static void __init generic_board_init(void) | 251 | void __init stamp9g20_board_init(void) |
254 | { | 252 | { |
255 | /* Serial */ | 253 | /* Serial */ |
256 | at91_add_device_serial(); | 254 | at91_add_device_serial(); |
@@ -262,34 +260,40 @@ static void __init generic_board_init(void) | |||
262 | #else | 260 | #else |
263 | at91_add_device_mmc(0, &mmc_data); | 261 | at91_add_device_mmc(0, &mmc_data); |
264 | #endif | 262 | #endif |
265 | /* USB Host */ | ||
266 | at91_add_device_usbh(&usbh_data); | ||
267 | /* Ethernet */ | ||
268 | at91_add_device_eth(&macb_data); | ||
269 | /* I2C */ | ||
270 | at91_add_device_i2c(NULL, 0); | ||
271 | /* W1 */ | 263 | /* W1 */ |
272 | add_w1(); | 264 | add_w1(); |
273 | } | 265 | } |
274 | 266 | ||
275 | static void __init portuxg20_board_init(void) | 267 | static void __init portuxg20_board_init(void) |
276 | { | 268 | { |
277 | generic_board_init(); | 269 | stamp9g20_board_init(); |
278 | /* SPI */ | 270 | /* USB Host */ |
279 | at91_add_device_spi(portuxg20_spi_devices, ARRAY_SIZE(portuxg20_spi_devices)); | 271 | at91_add_device_usbh(&usbh_data); |
280 | /* USB Device */ | 272 | /* USB Device */ |
281 | at91_add_device_udc(&portuxg20_udc_data); | 273 | at91_add_device_udc(&portuxg20_udc_data); |
274 | /* Ethernet */ | ||
275 | at91_add_device_eth(&macb_data); | ||
276 | /* I2C */ | ||
277 | at91_add_device_i2c(NULL, 0); | ||
278 | /* SPI */ | ||
279 | at91_add_device_spi(portuxg20_spi_devices, ARRAY_SIZE(portuxg20_spi_devices)); | ||
282 | /* LEDs */ | 280 | /* LEDs */ |
283 | at91_gpio_leds(portuxg20_leds, ARRAY_SIZE(portuxg20_leds)); | 281 | at91_gpio_leds(portuxg20_leds, ARRAY_SIZE(portuxg20_leds)); |
284 | } | 282 | } |
285 | 283 | ||
286 | static void __init stamp9g20_board_init(void) | 284 | static void __init stamp9g20evb_board_init(void) |
287 | { | 285 | { |
288 | generic_board_init(); | 286 | stamp9g20_board_init(); |
287 | /* USB Host */ | ||
288 | at91_add_device_usbh(&usbh_data); | ||
289 | /* USB Device */ | 289 | /* USB Device */ |
290 | at91_add_device_udc(&stamp9g20_udc_data); | 290 | at91_add_device_udc(&stamp9g20evb_udc_data); |
291 | /* Ethernet */ | ||
292 | at91_add_device_eth(&macb_data); | ||
293 | /* I2C */ | ||
294 | at91_add_device_i2c(NULL, 0); | ||
291 | /* LEDs */ | 295 | /* LEDs */ |
292 | at91_gpio_leds(stamp9g20_leds, ARRAY_SIZE(stamp9g20_leds)); | 296 | at91_gpio_leds(stamp9g20evb_leds, ARRAY_SIZE(stamp9g20evb_leds)); |
293 | } | 297 | } |
294 | 298 | ||
295 | MACHINE_START(PORTUXG20, "taskit PortuxG20") | 299 | MACHINE_START(PORTUXG20, "taskit PortuxG20") |
@@ -305,7 +309,7 @@ MACHINE_START(STAMP9G20, "taskit Stamp9G20") | |||
305 | /* Maintainer: taskit GmbH */ | 309 | /* Maintainer: taskit GmbH */ |
306 | .boot_params = AT91_SDRAM_BASE + 0x100, | 310 | .boot_params = AT91_SDRAM_BASE + 0x100, |
307 | .timer = &at91sam926x_timer, | 311 | .timer = &at91sam926x_timer, |
308 | .map_io = stamp9g20_map_io, | 312 | .map_io = stamp9g20evb_map_io, |
309 | .init_irq = init_irq, | 313 | .init_irq = init_irq, |
310 | .init_machine = stamp9g20_board_init, | 314 | .init_machine = stamp9g20evb_board_init, |
311 | MACHINE_END | 315 | MACHINE_END |
diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index 7525cee3983f..9113da6845f1 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c | |||
@@ -658,7 +658,7 @@ static void __init at91_upll_usbfs_clock_init(unsigned long main_clock) | |||
658 | /* Now set uhpck values */ | 658 | /* Now set uhpck values */ |
659 | uhpck.parent = &utmi_clk; | 659 | uhpck.parent = &utmi_clk; |
660 | uhpck.pmc_mask = AT91SAM926x_PMC_UHP; | 660 | uhpck.pmc_mask = AT91SAM926x_PMC_UHP; |
661 | uhpck.rate_hz = utmi_clk.parent->rate_hz; | 661 | uhpck.rate_hz = utmi_clk.rate_hz; |
662 | uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8); | 662 | uhpck.rate_hz /= 1 + ((at91_sys_read(AT91_PMC_USB) & AT91_PMC_OHCIUSBDIV) >> 8); |
663 | } | 663 | } |
664 | 664 | ||
diff --git a/arch/arm/mach-at91/include/mach/at91_mci.h b/arch/arm/mach-at91/include/mach/at91_mci.h index 57f8ee154943..27ac6f550fe3 100644 --- a/arch/arm/mach-at91/include/mach/at91_mci.h +++ b/arch/arm/mach-at91/include/mach/at91_mci.h | |||
@@ -74,6 +74,8 @@ | |||
74 | #define AT91_MCI_TRTYP_BLOCK (0 << 19) | 74 | #define AT91_MCI_TRTYP_BLOCK (0 << 19) |
75 | #define AT91_MCI_TRTYP_MULTIPLE (1 << 19) | 75 | #define AT91_MCI_TRTYP_MULTIPLE (1 << 19) |
76 | #define AT91_MCI_TRTYP_STREAM (2 << 19) | 76 | #define AT91_MCI_TRTYP_STREAM (2 << 19) |
77 | #define AT91_MCI_TRTYP_SDIO_BYTE (4 << 19) | ||
78 | #define AT91_MCI_TRTYP_SDIO_BLOCK (5 << 19) | ||
77 | 79 | ||
78 | #define AT91_MCI_BLKR 0x18 /* Block Register */ | 80 | #define AT91_MCI_BLKR 0x18 /* Block Register */ |
79 | #define AT91_MCI_BLKR_BCNT(n) ((0xffff & (n)) << 0) /* Block count */ | 81 | #define AT91_MCI_BLKR_BCNT(n) ((0xffff & (n)) << 0) /* Block count */ |
diff --git a/arch/arm/mach-at91/include/mach/stamp9g20.h b/arch/arm/mach-at91/include/mach/stamp9g20.h new file mode 100644 index 000000000000..6120f9c46d59 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/stamp9g20.h | |||
@@ -0,0 +1,7 @@ | |||
1 | #ifndef __MACH_STAMP9G20_H | ||
2 | #define __MACH_STAMP9G20_H | ||
3 | |||
4 | void stamp9g20_map_io(void); | ||
5 | void stamp9g20_board_init(void); | ||
6 | |||
7 | #endif | ||
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index 24498a932ba6..a54b3db80366 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c | |||
@@ -513,4 +513,4 @@ int dma_set_coherent_mask(struct device *dev, u64 mask) | |||
513 | 513 | ||
514 | EXPORT_SYMBOL(ixp4xx_pci_read); | 514 | EXPORT_SYMBOL(ixp4xx_pci_read); |
515 | EXPORT_SYMBOL(ixp4xx_pci_write); | 515 | EXPORT_SYMBOL(ixp4xx_pci_write); |
516 | 516 | EXPORT_SYMBOL(dma_set_coherent_mask); | |
diff --git a/arch/arm/mach-mmp/mmp2.c b/arch/arm/mach-mmp/mmp2.c index daf3993349f8..2e3dd08ccc3f 100644 --- a/arch/arm/mach-mmp/mmp2.c +++ b/arch/arm/mach-mmp/mmp2.c | |||
@@ -126,7 +126,6 @@ static APBC_CLK(twsi3, MMP2_TWSI3, 0, 26000000); | |||
126 | static APBC_CLK(twsi4, MMP2_TWSI4, 0, 26000000); | 126 | static APBC_CLK(twsi4, MMP2_TWSI4, 0, 26000000); |
127 | static APBC_CLK(twsi5, MMP2_TWSI5, 0, 26000000); | 127 | static APBC_CLK(twsi5, MMP2_TWSI5, 0, 26000000); |
128 | static APBC_CLK(twsi6, MMP2_TWSI6, 0, 26000000); | 128 | static APBC_CLK(twsi6, MMP2_TWSI6, 0, 26000000); |
129 | static APBC_CLK(rtc, MMP2_RTC, 0, 32768); | ||
130 | 129 | ||
131 | static APMU_CLK(nand, NAND, 0xbf, 100000000); | 130 | static APMU_CLK(nand, NAND, 0xbf, 100000000); |
132 | 131 | ||
diff --git a/arch/arm/mach-omap2/board-zoom-peripherals.c b/arch/arm/mach-omap2/board-zoom-peripherals.c index 86c9b2102952..9db9203667df 100644 --- a/arch/arm/mach-omap2/board-zoom-peripherals.c +++ b/arch/arm/mach-omap2/board-zoom-peripherals.c | |||
@@ -216,7 +216,7 @@ static struct omap2_hsmmc_info mmc[] __initdata = { | |||
216 | { | 216 | { |
217 | .name = "wl1271", | 217 | .name = "wl1271", |
218 | .mmc = 3, | 218 | .mmc = 3, |
219 | .caps = MMC_CAP_4_BIT_DATA, | 219 | .caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD, |
220 | .gpio_wp = -EINVAL, | 220 | .gpio_wp = -EINVAL, |
221 | .gpio_cd = -EINVAL, | 221 | .gpio_cd = -EINVAL, |
222 | .nonremovable = true, | 222 | .nonremovable = true, |
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 40562ddd3ee4..a1939b1e6f82 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c | |||
@@ -297,7 +297,7 @@ static int __init _omap2_init_reprogram_sdrc(void) | |||
297 | return 0; | 297 | return 0; |
298 | 298 | ||
299 | dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck"); | 299 | dpll3_m2_ck = clk_get(NULL, "dpll3_m2_ck"); |
300 | if (!dpll3_m2_ck) | 300 | if (IS_ERR(dpll3_m2_ck)) |
301 | return -EINVAL; | 301 | return -EINVAL; |
302 | 302 | ||
303 | rate = clk_get_rate(dpll3_m2_ck); | 303 | rate = clk_get_rate(dpll3_m2_ck); |
diff --git a/arch/arm/mach-omap2/pm-debug.c b/arch/arm/mach-omap2/pm-debug.c index 5e81517a7af2..a8afb610c7d8 100644 --- a/arch/arm/mach-omap2/pm-debug.c +++ b/arch/arm/mach-omap2/pm-debug.c | |||
@@ -161,6 +161,23 @@ void omap2_pm_dump(int mode, int resume, unsigned int us) | |||
161 | printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val); | 161 | printk(KERN_INFO "%-20s: 0x%08x\n", regs[i].name, regs[i].val); |
162 | } | 162 | } |
163 | 163 | ||
164 | void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds) | ||
165 | { | ||
166 | u32 tick_rate, cycles; | ||
167 | |||
168 | if (!seconds && !milliseconds) | ||
169 | return; | ||
170 | |||
171 | tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup)); | ||
172 | cycles = tick_rate * seconds + tick_rate * milliseconds / 1000; | ||
173 | omap_dm_timer_stop(gptimer_wakeup); | ||
174 | omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles); | ||
175 | |||
176 | pr_info("PM: Resume timer in %u.%03u secs" | ||
177 | " (%d ticks at %d ticks/sec.)\n", | ||
178 | seconds, milliseconds, cycles, tick_rate); | ||
179 | } | ||
180 | |||
164 | #ifdef CONFIG_DEBUG_FS | 181 | #ifdef CONFIG_DEBUG_FS |
165 | #include <linux/debugfs.h> | 182 | #include <linux/debugfs.h> |
166 | #include <linux/seq_file.h> | 183 | #include <linux/seq_file.h> |
@@ -354,23 +371,6 @@ void pm_dbg_update_time(struct powerdomain *pwrdm, int prev) | |||
354 | pwrdm->timer = t; | 371 | pwrdm->timer = t; |
355 | } | 372 | } |
356 | 373 | ||
357 | void omap2_pm_wakeup_on_timer(u32 seconds, u32 milliseconds) | ||
358 | { | ||
359 | u32 tick_rate, cycles; | ||
360 | |||
361 | if (!seconds && !milliseconds) | ||
362 | return; | ||
363 | |||
364 | tick_rate = clk_get_rate(omap_dm_timer_get_fclk(gptimer_wakeup)); | ||
365 | cycles = tick_rate * seconds + tick_rate * milliseconds / 1000; | ||
366 | omap_dm_timer_stop(gptimer_wakeup); | ||
367 | omap_dm_timer_set_load_start(gptimer_wakeup, 0, 0xffffffff - cycles); | ||
368 | |||
369 | pr_info("PM: Resume timer in %u.%03u secs" | ||
370 | " (%d ticks at %d ticks/sec.)\n", | ||
371 | seconds, milliseconds, cycles, tick_rate); | ||
372 | } | ||
373 | |||
374 | static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user) | 374 | static int clkdm_dbg_show_counter(struct clockdomain *clkdm, void *user) |
375 | { | 375 | { |
376 | struct seq_file *s = (struct seq_file *)user; | 376 | struct seq_file *s = (struct seq_file *)user; |
diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index c85923e56b85..aaeea49b9bdd 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c | |||
@@ -53,6 +53,19 @@ | |||
53 | #include <plat/powerdomain.h> | 53 | #include <plat/powerdomain.h> |
54 | #include <plat/clockdomain.h> | 54 | #include <plat/clockdomain.h> |
55 | 55 | ||
56 | #ifdef CONFIG_SUSPEND | ||
57 | static suspend_state_t suspend_state = PM_SUSPEND_ON; | ||
58 | static inline bool is_suspending(void) | ||
59 | { | ||
60 | return (suspend_state != PM_SUSPEND_ON); | ||
61 | } | ||
62 | #else | ||
63 | static inline bool is_suspending(void) | ||
64 | { | ||
65 | return false; | ||
66 | } | ||
67 | #endif | ||
68 | |||
56 | static void (*omap2_sram_idle)(void); | 69 | static void (*omap2_sram_idle)(void); |
57 | static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl, | 70 | static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl, |
58 | void __iomem *sdrc_power); | 71 | void __iomem *sdrc_power); |
@@ -120,8 +133,9 @@ static void omap2_enter_full_retention(void) | |||
120 | goto no_sleep; | 133 | goto no_sleep; |
121 | 134 | ||
122 | /* Block console output in case it is on one of the OMAP UARTs */ | 135 | /* Block console output in case it is on one of the OMAP UARTs */ |
123 | if (try_acquire_console_sem()) | 136 | if (!is_suspending()) |
124 | goto no_sleep; | 137 | if (try_acquire_console_sem()) |
138 | goto no_sleep; | ||
125 | 139 | ||
126 | omap_uart_prepare_idle(0); | 140 | omap_uart_prepare_idle(0); |
127 | omap_uart_prepare_idle(1); | 141 | omap_uart_prepare_idle(1); |
@@ -136,7 +150,8 @@ static void omap2_enter_full_retention(void) | |||
136 | omap_uart_resume_idle(1); | 150 | omap_uart_resume_idle(1); |
137 | omap_uart_resume_idle(0); | 151 | omap_uart_resume_idle(0); |
138 | 152 | ||
139 | release_console_sem(); | 153 | if (!is_suspending()) |
154 | release_console_sem(); | ||
140 | 155 | ||
141 | no_sleep: | 156 | no_sleep: |
142 | if (omap2_pm_debug) { | 157 | if (omap2_pm_debug) { |
@@ -284,6 +299,12 @@ out: | |||
284 | local_irq_enable(); | 299 | local_irq_enable(); |
285 | } | 300 | } |
286 | 301 | ||
302 | static int omap2_pm_begin(suspend_state_t state) | ||
303 | { | ||
304 | suspend_state = state; | ||
305 | return 0; | ||
306 | } | ||
307 | |||
287 | static int omap2_pm_prepare(void) | 308 | static int omap2_pm_prepare(void) |
288 | { | 309 | { |
289 | /* We cannot sleep in idle until we have resumed */ | 310 | /* We cannot sleep in idle until we have resumed */ |
@@ -333,10 +354,17 @@ static void omap2_pm_finish(void) | |||
333 | enable_hlt(); | 354 | enable_hlt(); |
334 | } | 355 | } |
335 | 356 | ||
357 | static void omap2_pm_end(void) | ||
358 | { | ||
359 | suspend_state = PM_SUSPEND_ON; | ||
360 | } | ||
361 | |||
336 | static struct platform_suspend_ops omap_pm_ops = { | 362 | static struct platform_suspend_ops omap_pm_ops = { |
363 | .begin = omap2_pm_begin, | ||
337 | .prepare = omap2_pm_prepare, | 364 | .prepare = omap2_pm_prepare, |
338 | .enter = omap2_pm_enter, | 365 | .enter = omap2_pm_enter, |
339 | .finish = omap2_pm_finish, | 366 | .finish = omap2_pm_finish, |
367 | .end = omap2_pm_end, | ||
340 | .valid = suspend_valid_only_mem, | 368 | .valid = suspend_valid_only_mem, |
341 | }; | 369 | }; |
342 | 370 | ||
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 0ec8a04b7473..648b8c50d024 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
@@ -50,6 +50,19 @@ | |||
50 | #include "sdrc.h" | 50 | #include "sdrc.h" |
51 | #include "control.h" | 51 | #include "control.h" |
52 | 52 | ||
53 | #ifdef CONFIG_SUSPEND | ||
54 | static suspend_state_t suspend_state = PM_SUSPEND_ON; | ||
55 | static inline bool is_suspending(void) | ||
56 | { | ||
57 | return (suspend_state != PM_SUSPEND_ON); | ||
58 | } | ||
59 | #else | ||
60 | static inline bool is_suspending(void) | ||
61 | { | ||
62 | return false; | ||
63 | } | ||
64 | #endif | ||
65 | |||
53 | /* Scratchpad offsets */ | 66 | /* Scratchpad offsets */ |
54 | #define OMAP343X_TABLE_ADDRESS_OFFSET 0xc4 | 67 | #define OMAP343X_TABLE_ADDRESS_OFFSET 0xc4 |
55 | #define OMAP343X_TABLE_VALUE_OFFSET 0xc0 | 68 | #define OMAP343X_TABLE_VALUE_OFFSET 0xc0 |
@@ -387,10 +400,11 @@ void omap_sram_idle(void) | |||
387 | } | 400 | } |
388 | 401 | ||
389 | /* Block console output in case it is on one of the OMAP UARTs */ | 402 | /* Block console output in case it is on one of the OMAP UARTs */ |
390 | if (per_next_state < PWRDM_POWER_ON || | 403 | if (!is_suspending()) |
391 | core_next_state < PWRDM_POWER_ON) | 404 | if (per_next_state < PWRDM_POWER_ON || |
392 | if (try_acquire_console_sem()) | 405 | core_next_state < PWRDM_POWER_ON) |
393 | goto console_still_active; | 406 | if (try_acquire_console_sem()) |
407 | goto console_still_active; | ||
394 | 408 | ||
395 | /* PER */ | 409 | /* PER */ |
396 | if (per_next_state < PWRDM_POWER_ON) { | 410 | if (per_next_state < PWRDM_POWER_ON) { |
@@ -470,7 +484,8 @@ void omap_sram_idle(void) | |||
470 | omap_uart_resume_idle(3); | 484 | omap_uart_resume_idle(3); |
471 | } | 485 | } |
472 | 486 | ||
473 | release_console_sem(); | 487 | if (!is_suspending()) |
488 | release_console_sem(); | ||
474 | 489 | ||
475 | console_still_active: | 490 | console_still_active: |
476 | /* Disable IO-PAD and IO-CHAIN wakeup */ | 491 | /* Disable IO-PAD and IO-CHAIN wakeup */ |
@@ -514,8 +529,6 @@ out: | |||
514 | } | 529 | } |
515 | 530 | ||
516 | #ifdef CONFIG_SUSPEND | 531 | #ifdef CONFIG_SUSPEND |
517 | static suspend_state_t suspend_state; | ||
518 | |||
519 | static int omap3_pm_prepare(void) | 532 | static int omap3_pm_prepare(void) |
520 | { | 533 | { |
521 | disable_hlt(); | 534 | disable_hlt(); |
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index 298a22a754e2..f81acee4738d 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h | |||
@@ -243,13 +243,14 @@ | |||
243 | #define OMAP24XX_EN_GPT1_MASK (1 << 0) | 243 | #define OMAP24XX_EN_GPT1_MASK (1 << 0) |
244 | 244 | ||
245 | /* PM_WKST_WKUP, CM_IDLEST_WKUP shared bits */ | 245 | /* PM_WKST_WKUP, CM_IDLEST_WKUP shared bits */ |
246 | #define OMAP24XX_ST_GPIOS_SHIFT (1 << 2) | 246 | #define OMAP24XX_ST_GPIOS_SHIFT 2 |
247 | #define OMAP24XX_ST_GPIOS_MASK 2 | 247 | #define OMAP24XX_ST_GPIOS_MASK (1 << 2) |
248 | #define OMAP24XX_ST_GPT1_SHIFT (1 << 0) | 248 | #define OMAP24XX_ST_GPT1_SHIFT 0 |
249 | #define OMAP24XX_ST_GPT1_MASK 0 | 249 | #define OMAP24XX_ST_GPT1_MASK (1 << 0) |
250 | 250 | ||
251 | /* CM_IDLEST_MDM and PM_WKST_MDM shared bits */ | 251 | /* CM_IDLEST_MDM and PM_WKST_MDM shared bits */ |
252 | #define OMAP2430_ST_MDM_SHIFT (1 << 0) | 252 | #define OMAP2430_ST_MDM_SHIFT 0 |
253 | #define OMAP2430_ST_MDM_MASK (1 << 0) | ||
253 | 254 | ||
254 | 255 | ||
255 | /* 3430 register bits shared between CM & PRM registers */ | 256 | /* 3430 register bits shared between CM & PRM registers */ |
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index dd235ecc9d6c..c93e73d54dd1 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig | |||
@@ -540,6 +540,7 @@ config MACH_ICONTROL | |||
540 | config ARCH_PXA_ESERIES | 540 | config ARCH_PXA_ESERIES |
541 | bool "PXA based Toshiba e-series PDAs" | 541 | bool "PXA based Toshiba e-series PDAs" |
542 | select PXA25x | 542 | select PXA25x |
543 | select FB_W100 | ||
543 | 544 | ||
544 | config MACH_E330 | 545 | config MACH_E330 |
545 | bool "Toshiba e330" | 546 | bool "Toshiba e330" |
diff --git a/arch/arm/mach-pxa/palmtx.c b/arch/arm/mach-pxa/palmtx.c index d2060a1d1d68..e5c9932b7588 100644 --- a/arch/arm/mach-pxa/palmtx.c +++ b/arch/arm/mach-pxa/palmtx.c | |||
@@ -241,7 +241,8 @@ static inline void palmtx_keys_init(void) {} | |||
241 | /****************************************************************************** | 241 | /****************************************************************************** |
242 | * NAND Flash | 242 | * NAND Flash |
243 | ******************************************************************************/ | 243 | ******************************************************************************/ |
244 | #if defined(CONFIG_MTD_NAND_GPIO) || defined(CONFIG_MTD_NAND_GPIO_MODULE) | 244 | #if defined(CONFIG_MTD_NAND_PLATFORM) || \ |
245 | defined(CONFIG_MTD_NAND_PLATFORM_MODULE) | ||
245 | static void palmtx_nand_cmd_ctl(struct mtd_info *mtd, int cmd, | 246 | static void palmtx_nand_cmd_ctl(struct mtd_info *mtd, int cmd, |
246 | unsigned int ctrl) | 247 | unsigned int ctrl) |
247 | { | 248 | { |
diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S index 52c30b01a671..ae008110db4e 100644 --- a/arch/arm/mach-pxa/sleep.S +++ b/arch/arm/mach-pxa/sleep.S | |||
@@ -353,8 +353,8 @@ resume_turn_on_mmu: | |||
353 | 353 | ||
354 | @ Let us ensure we jump to resume_after_mmu only when the mcr above | 354 | @ Let us ensure we jump to resume_after_mmu only when the mcr above |
355 | @ actually took effect. They call it the "cpwait" operation. | 355 | @ actually took effect. They call it the "cpwait" operation. |
356 | mrc p15, 0, r1, c2, c0, 0 @ queue a dependency on CP15 | 356 | mrc p15, 0, r0, c2, c0, 0 @ queue a dependency on CP15 |
357 | sub pc, r2, r1, lsr #32 @ jump to virtual addr | 357 | sub pc, r2, r0, lsr #32 @ jump to virtual addr |
358 | nop | 358 | nop |
359 | nop | 359 | nop |
360 | nop | 360 | nop |
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig index cef6a65637bd..6983cb4d4cae 100644 --- a/arch/arm/mach-s3c2412/Kconfig +++ b/arch/arm/mach-s3c2412/Kconfig | |||
@@ -16,7 +16,7 @@ config CPU_S3C2412 | |||
16 | config CPU_S3C2412_ONLY | 16 | config CPU_S3C2412_ONLY |
17 | bool | 17 | bool |
18 | depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \ | 18 | depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \ |
19 | !CPU_2416 && !CPU_S3C2440 && !CPU_S3C2442 && \ | 19 | !CPU_S3C2416 && !CPU_S3C2440 && !CPU_S3C2442 && \ |
20 | !CPU_S3C2443 && CPU_S3C2412 | 20 | !CPU_S3C2443 && CPU_S3C2412 |
21 | default y if CPU_S3C2412 | 21 | default y if CPU_S3C2412 |
22 | 22 | ||
@@ -28,9 +28,16 @@ config S3C2412_DMA | |||
28 | 28 | ||
29 | config S3C2412_PM | 29 | config S3C2412_PM |
30 | bool | 30 | bool |
31 | select S3C2412_PM_SLEEP | ||
31 | help | 32 | help |
32 | Internal config node to apply S3C2412 power management | 33 | Internal config node to apply S3C2412 power management |
33 | 34 | ||
35 | config S3C2412_PM_SLEEP | ||
36 | bool | ||
37 | help | ||
38 | Internal config node to apply sleep for S3C2412 power management. | ||
39 | Can be selected by another SoCs with similar sleep procedure. | ||
40 | |||
34 | # Note, the S3C2412 IOtiming support is in plat-s3c24xx | 41 | # Note, the S3C2412 IOtiming support is in plat-s3c24xx |
35 | 42 | ||
36 | config S3C2412_CPUFREQ | 43 | config S3C2412_CPUFREQ |
diff --git a/arch/arm/mach-s3c2412/Makefile b/arch/arm/mach-s3c2412/Makefile index 530ec46cbaea..6c48a91ea39e 100644 --- a/arch/arm/mach-s3c2412/Makefile +++ b/arch/arm/mach-s3c2412/Makefile | |||
@@ -14,7 +14,8 @@ obj-$(CONFIG_CPU_S3C2412) += irq.o | |||
14 | obj-$(CONFIG_CPU_S3C2412) += clock.o | 14 | obj-$(CONFIG_CPU_S3C2412) += clock.o |
15 | obj-$(CONFIG_CPU_S3C2412) += gpio.o | 15 | obj-$(CONFIG_CPU_S3C2412) += gpio.o |
16 | obj-$(CONFIG_S3C2412_DMA) += dma.o | 16 | obj-$(CONFIG_S3C2412_DMA) += dma.o |
17 | obj-$(CONFIG_S3C2412_PM) += pm.o sleep.o | 17 | obj-$(CONFIG_S3C2412_PM) += pm.o |
18 | obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep.o | ||
18 | obj-$(CONFIG_S3C2412_CPUFREQ) += cpu-freq.o | 19 | obj-$(CONFIG_S3C2412_CPUFREQ) += cpu-freq.o |
19 | 20 | ||
20 | # Machine support | 21 | # Machine support |
diff --git a/arch/arm/mach-s3c2416/Kconfig b/arch/arm/mach-s3c2416/Kconfig index 87b9c9f003bd..df8d14974c90 100644 --- a/arch/arm/mach-s3c2416/Kconfig +++ b/arch/arm/mach-s3c2416/Kconfig | |||
@@ -27,6 +27,7 @@ config S3C2416_DMA | |||
27 | 27 | ||
28 | config S3C2416_PM | 28 | config S3C2416_PM |
29 | bool | 29 | bool |
30 | select S3C2412_PM_SLEEP | ||
30 | help | 31 | help |
31 | Internal config node to apply S3C2416 power management | 32 | Internal config node to apply S3C2416 power management |
32 | 33 | ||
@@ -35,9 +36,12 @@ menu "S3C2416 Machines" | |||
35 | config MACH_SMDK2416 | 36 | config MACH_SMDK2416 |
36 | bool "SMDK2416" | 37 | bool "SMDK2416" |
37 | select CPU_S3C2416 | 38 | select CPU_S3C2416 |
39 | select MACH_SMDK | ||
38 | select S3C_DEV_FB | 40 | select S3C_DEV_FB |
39 | select S3C_DEV_HSMMC | 41 | select S3C_DEV_HSMMC |
40 | select S3C_DEV_HSMMC1 | 42 | select S3C_DEV_HSMMC1 |
43 | select S3C_DEV_NAND | ||
44 | select S3C_DEV_USB_HOST | ||
41 | select S3C2416_PM if PM | 45 | select S3C2416_PM if PM |
42 | help | 46 | help |
43 | Say Y here if you are using an SMDK2416 | 47 | Say Y here if you are using an SMDK2416 |
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig index ff024a6c0f85..a0cb2581894f 100644 --- a/arch/arm/mach-s3c2440/Kconfig +++ b/arch/arm/mach-s3c2440/Kconfig | |||
@@ -18,6 +18,7 @@ config CPU_S3C2440 | |||
18 | config CPU_S3C2442 | 18 | config CPU_S3C2442 |
19 | bool | 19 | bool |
20 | select CPU_ARM920T | 20 | select CPU_ARM920T |
21 | select S3C_GPIO_PULL_DOWN | ||
21 | select S3C2410_CLOCK | 22 | select S3C2410_CLOCK |
22 | select S3C2410_GPIO | 23 | select S3C2410_GPIO |
23 | select S3C2410_PM if PM | 24 | select S3C2410_PM if PM |
@@ -178,6 +179,9 @@ config MACH_MINI2440 | |||
178 | bool "MINI2440 development board" | 179 | bool "MINI2440 development board" |
179 | select CPU_S3C2440 | 180 | select CPU_S3C2440 |
180 | select EEPROM_AT24 | 181 | select EEPROM_AT24 |
182 | select NEW_LEDS | ||
183 | select LEDS_CLASS | ||
184 | select LEDS_TRIGGER | ||
181 | select LEDS_TRIGGER_BACKLIGHT | 185 | select LEDS_TRIGGER_BACKLIGHT |
182 | select S3C_DEV_NAND | 186 | select S3C_DEV_NAND |
183 | select S3C_DEV_USB_HOST | 187 | select S3C_DEV_USB_HOST |
diff --git a/arch/arm/mach-s3c2440/s3c2440.c b/arch/arm/mach-s3c2440/s3c2440.c index d50f3ae6173d..f7663f731ea0 100644 --- a/arch/arm/mach-s3c2440/s3c2440.c +++ b/arch/arm/mach-s3c2440/s3c2440.c | |||
@@ -46,9 +46,6 @@ int __init s3c2440_init(void) | |||
46 | { | 46 | { |
47 | printk("S3C2440: Initialising architecture\n"); | 47 | printk("S3C2440: Initialising architecture\n"); |
48 | 48 | ||
49 | s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up; | ||
50 | s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up; | ||
51 | |||
52 | /* change irq for watchdog */ | 49 | /* change irq for watchdog */ |
53 | 50 | ||
54 | s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT; | 51 | s3c_device_wdt.resource[1].start = IRQ_S3C2440_WDT; |
@@ -58,3 +55,11 @@ int __init s3c2440_init(void) | |||
58 | 55 | ||
59 | return sysdev_register(&s3c2440_sysdev); | 56 | return sysdev_register(&s3c2440_sysdev); |
60 | } | 57 | } |
58 | |||
59 | void __init s3c2440_map_io(void) | ||
60 | { | ||
61 | s3c244x_map_io(); | ||
62 | |||
63 | s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1up; | ||
64 | s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1up; | ||
65 | } | ||
diff --git a/arch/arm/mach-s3c2440/s3c2442.c b/arch/arm/mach-s3c2440/s3c2442.c index 188ad1e57dc0..ecf813546554 100644 --- a/arch/arm/mach-s3c2440/s3c2442.c +++ b/arch/arm/mach-s3c2440/s3c2442.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
33 | #include <linux/ioport.h> | 33 | #include <linux/ioport.h> |
34 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
35 | #include <linux/gpio.h> | ||
35 | #include <linux/clk.h> | 36 | #include <linux/clk.h> |
36 | #include <linux/io.h> | 37 | #include <linux/io.h> |
37 | 38 | ||
@@ -43,6 +44,11 @@ | |||
43 | 44 | ||
44 | #include <plat/clock.h> | 45 | #include <plat/clock.h> |
45 | #include <plat/cpu.h> | 46 | #include <plat/cpu.h> |
47 | #include <plat/s3c244x.h> | ||
48 | |||
49 | #include <plat/gpio-core.h> | ||
50 | #include <plat/gpio-cfg.h> | ||
51 | #include <plat/gpio-cfg-helpers.h> | ||
46 | 52 | ||
47 | /* S3C2442 extended clock support */ | 53 | /* S3C2442 extended clock support */ |
48 | 54 | ||
@@ -163,3 +169,11 @@ int __init s3c2442_init(void) | |||
163 | 169 | ||
164 | return sysdev_register(&s3c2442_sysdev); | 170 | return sysdev_register(&s3c2442_sysdev); |
165 | } | 171 | } |
172 | |||
173 | void __init s3c2442_map_io(void) | ||
174 | { | ||
175 | s3c244x_map_io(); | ||
176 | |||
177 | s3c24xx_gpiocfg_default.set_pull = s3c_gpio_setpull_1down; | ||
178 | s3c24xx_gpiocfg_default.get_pull = s3c_gpio_getpull_1down; | ||
179 | } | ||
diff --git a/arch/arm/mach-s3c2443/Kconfig b/arch/arm/mach-s3c2443/Kconfig index 4fef723126fa..31babec90cec 100644 --- a/arch/arm/mach-s3c2443/Kconfig +++ b/arch/arm/mach-s3c2443/Kconfig | |||
@@ -5,6 +5,7 @@ | |||
5 | config CPU_S3C2443 | 5 | config CPU_S3C2443 |
6 | bool | 6 | bool |
7 | depends on ARCH_S3C2410 | 7 | depends on ARCH_S3C2410 |
8 | select CPU_ARM920T | ||
8 | select S3C2443_DMA if S3C2410_DMA | 9 | select S3C2443_DMA if S3C2410_DMA |
9 | select CPU_LLSERIAL_S3C2440 | 10 | select CPU_LLSERIAL_S3C2440 |
10 | select SAMSUNG_CLKSRC | 11 | select SAMSUNG_CLKSRC |
diff --git a/arch/arm/mach-s5pv210/mach-aquila.c b/arch/arm/mach-s5pv210/mach-aquila.c index 28677caf3613..461aa035afc0 100644 --- a/arch/arm/mach-s5pv210/mach-aquila.c +++ b/arch/arm/mach-s5pv210/mach-aquila.c | |||
@@ -378,6 +378,12 @@ static struct max8998_regulator_data aquila_regulators[] = { | |||
378 | static struct max8998_platform_data aquila_max8998_pdata = { | 378 | static struct max8998_platform_data aquila_max8998_pdata = { |
379 | .num_regulators = ARRAY_SIZE(aquila_regulators), | 379 | .num_regulators = ARRAY_SIZE(aquila_regulators), |
380 | .regulators = aquila_regulators, | 380 | .regulators = aquila_regulators, |
381 | .buck1_set1 = S5PV210_GPH0(3), | ||
382 | .buck1_set2 = S5PV210_GPH0(4), | ||
383 | .buck2_set3 = S5PV210_GPH0(5), | ||
384 | .buck1_max_voltage1 = 1200000, | ||
385 | .buck1_max_voltage2 = 1200000, | ||
386 | .buck2_max_voltage = 1200000, | ||
381 | }; | 387 | }; |
382 | #endif | 388 | #endif |
383 | 389 | ||
diff --git a/arch/arm/mach-s5pv210/mach-goni.c b/arch/arm/mach-s5pv210/mach-goni.c index b1dcf964a768..e22d5112fd44 100644 --- a/arch/arm/mach-s5pv210/mach-goni.c +++ b/arch/arm/mach-s5pv210/mach-goni.c | |||
@@ -518,6 +518,12 @@ static struct max8998_regulator_data goni_regulators[] = { | |||
518 | static struct max8998_platform_data goni_max8998_pdata = { | 518 | static struct max8998_platform_data goni_max8998_pdata = { |
519 | .num_regulators = ARRAY_SIZE(goni_regulators), | 519 | .num_regulators = ARRAY_SIZE(goni_regulators), |
520 | .regulators = goni_regulators, | 520 | .regulators = goni_regulators, |
521 | .buck1_set1 = S5PV210_GPH0(3), | ||
522 | .buck1_set2 = S5PV210_GPH0(4), | ||
523 | .buck2_set3 = S5PV210_GPH0(5), | ||
524 | .buck1_max_voltage1 = 1200000, | ||
525 | .buck1_max_voltage2 = 1200000, | ||
526 | .buck2_max_voltage = 1200000, | ||
521 | }; | 527 | }; |
522 | #endif | 528 | #endif |
523 | 529 | ||
diff --git a/arch/arm/mach-shmobile/include/mach/entry-macro.S b/arch/arm/mach-shmobile/include/mach/entry-macro.S index a285d13c7416..f428c4db2b60 100644 --- a/arch/arm/mach-shmobile/include/mach/entry-macro.S +++ b/arch/arm/mach-shmobile/include/mach/entry-macro.S | |||
@@ -1,4 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2010 Magnus Damm | ||
2 | * Copyright (C) 2008 Renesas Solutions Corp. | 3 | * Copyright (C) 2008 Renesas Solutions Corp. |
3 | * | 4 | * |
4 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
@@ -14,24 +15,45 @@ | |||
14 | * along with this program; if not, write to the Free Software | 15 | * along with this program; if not, write to the Free Software |
15 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 16 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
16 | */ | 17 | */ |
17 | #include <mach/hardware.h> | ||
18 | #include <mach/irqs.h> | 18 | #include <mach/irqs.h> |
19 | 19 | ||
20 | #define INTCA_BASE 0xe6980000 | ||
21 | #define INTFLGA_OFFS 0x00000018 /* accept pending interrupt */ | ||
22 | #define INTEVTA_OFFS 0x00000020 /* vector number of accepted interrupt */ | ||
23 | #define INTLVLA_OFFS 0x00000030 /* priority level of accepted interrupt */ | ||
24 | #define INTLVLB_OFFS 0x00000034 /* previous priority level */ | ||
25 | |||
20 | .macro disable_fiq | 26 | .macro disable_fiq |
21 | .endm | 27 | .endm |
22 | 28 | ||
23 | .macro get_irqnr_preamble, base, tmp | 29 | .macro get_irqnr_preamble, base, tmp |
24 | ldr \base, =INTFLGA | 30 | ldr \base, =INTCA_BASE |
25 | .endm | 31 | .endm |
26 | 32 | ||
27 | .macro arch_ret_to_user, tmp1, tmp2 | 33 | .macro arch_ret_to_user, tmp1, tmp2 |
28 | .endm | 34 | .endm |
29 | 35 | ||
30 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | 36 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp |
31 | ldr \irqnr, [\base] | 37 | /* The single INTFLGA read access below results in the following: |
38 | * | ||
39 | * 1. INTLVLB is updated with old priority value from INTLVLA | ||
40 | * 2. Highest priority interrupt is accepted | ||
41 | * 3. INTLVLA is updated to contain priority of accepted interrupt | ||
42 | * 4. Accepted interrupt vector is stored in INTFLGA and INTEVTA | ||
43 | */ | ||
44 | ldr \irqnr, [\base, #INTFLGA_OFFS] | ||
45 | |||
46 | /* Restore INTLVLA with the value saved in INTLVLB. | ||
47 | * This is required to support interrupt priorities properly. | ||
48 | */ | ||
49 | ldrb \tmp, [\base, #INTLVLB_OFFS] | ||
50 | strb \tmp, [\base, #INTLVLA_OFFS] | ||
51 | |||
52 | /* Handle invalid vector number case */ | ||
32 | cmp \irqnr, #0 | 53 | cmp \irqnr, #0 |
33 | beq 1000f | 54 | beq 1000f |
34 | /* intevt to irq number */ | 55 | |
56 | /* Convert vector to irq number, same as the evt2irq() macro */ | ||
35 | lsr \irqnr, \irqnr, #0x5 | 57 | lsr \irqnr, \irqnr, #0x5 |
36 | subs \irqnr, \irqnr, #16 | 58 | subs \irqnr, \irqnr, #16 |
37 | 59 | ||
diff --git a/arch/arm/mach-shmobile/include/mach/vmalloc.h b/arch/arm/mach-shmobile/include/mach/vmalloc.h index 4aecf6e3a859..2b8fd8b942fe 100644 --- a/arch/arm/mach-shmobile/include/mach/vmalloc.h +++ b/arch/arm/mach-shmobile/include/mach/vmalloc.h | |||
@@ -2,6 +2,6 @@ | |||
2 | #define __ASM_MACH_VMALLOC_H | 2 | #define __ASM_MACH_VMALLOC_H |
3 | 3 | ||
4 | /* Vmalloc at ... - 0xe5ffffff */ | 4 | /* Vmalloc at ... - 0xe5ffffff */ |
5 | #define VMALLOC_END 0xe6000000 | 5 | #define VMALLOC_END 0xe6000000UL |
6 | 6 | ||
7 | #endif /* __ASM_MACH_VMALLOC_H */ | 7 | #endif /* __ASM_MACH_VMALLOC_H */ |
diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c index 6e77c042d8e9..e0b0e7a4ec68 100644 --- a/arch/arm/mm/cache-feroceon-l2.c +++ b/arch/arm/mm/cache-feroceon-l2.c | |||
@@ -13,13 +13,9 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/highmem.h> | ||
16 | #include <asm/cacheflush.h> | 17 | #include <asm/cacheflush.h> |
17 | #include <asm/kmap_types.h> | ||
18 | #include <asm/fixmap.h> | ||
19 | #include <asm/pgtable.h> | ||
20 | #include <asm/tlbflush.h> | ||
21 | #include <plat/cache-feroceon-l2.h> | 18 | #include <plat/cache-feroceon-l2.h> |
22 | #include "mm.h" | ||
23 | 19 | ||
24 | /* | 20 | /* |
25 | * Low-level cache maintenance operations. | 21 | * Low-level cache maintenance operations. |
@@ -39,27 +35,30 @@ | |||
39 | * between which we don't want to be preempted. | 35 | * between which we don't want to be preempted. |
40 | */ | 36 | */ |
41 | 37 | ||
42 | static inline unsigned long l2_start_va(unsigned long paddr) | 38 | static inline unsigned long l2_get_va(unsigned long paddr) |
43 | { | 39 | { |
44 | #ifdef CONFIG_HIGHMEM | 40 | #ifdef CONFIG_HIGHMEM |
45 | /* | 41 | /* |
46 | * Let's do our own fixmap stuff in a minimal way here. | ||
47 | * Because range ops can't be done on physical addresses, | 42 | * Because range ops can't be done on physical addresses, |
48 | * we simply install a virtual mapping for it only for the | 43 | * we simply install a virtual mapping for it only for the |
49 | * TLB lookup to occur, hence no need to flush the untouched | 44 | * TLB lookup to occur, hence no need to flush the untouched |
50 | * memory mapping. This is protected with the disabling of | 45 | * memory mapping afterwards (note: a cache flush may happen |
51 | * interrupts by the caller. | 46 | * in some circumstances depending on the path taken in kunmap_atomic). |
52 | */ | 47 | */ |
53 | unsigned long idx = KM_L2_CACHE + KM_TYPE_NR * smp_processor_id(); | 48 | void *vaddr = kmap_atomic_pfn(paddr >> PAGE_SHIFT); |
54 | unsigned long vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | 49 | return (unsigned long)vaddr + (paddr & ~PAGE_MASK); |
55 | set_pte_ext(TOP_PTE(vaddr), pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL), 0); | ||
56 | local_flush_tlb_kernel_page(vaddr); | ||
57 | return vaddr + (paddr & ~PAGE_MASK); | ||
58 | #else | 50 | #else |
59 | return __phys_to_virt(paddr); | 51 | return __phys_to_virt(paddr); |
60 | #endif | 52 | #endif |
61 | } | 53 | } |
62 | 54 | ||
55 | static inline void l2_put_va(unsigned long vaddr) | ||
56 | { | ||
57 | #ifdef CONFIG_HIGHMEM | ||
58 | kunmap_atomic((void *)vaddr); | ||
59 | #endif | ||
60 | } | ||
61 | |||
63 | static inline void l2_clean_pa(unsigned long addr) | 62 | static inline void l2_clean_pa(unsigned long addr) |
64 | { | 63 | { |
65 | __asm__("mcr p15, 1, %0, c15, c9, 3" : : "r" (addr)); | 64 | __asm__("mcr p15, 1, %0, c15, c9, 3" : : "r" (addr)); |
@@ -76,13 +75,14 @@ static inline void l2_clean_pa_range(unsigned long start, unsigned long end) | |||
76 | */ | 75 | */ |
77 | BUG_ON((start ^ end) >> PAGE_SHIFT); | 76 | BUG_ON((start ^ end) >> PAGE_SHIFT); |
78 | 77 | ||
79 | raw_local_irq_save(flags); | 78 | va_start = l2_get_va(start); |
80 | va_start = l2_start_va(start); | ||
81 | va_end = va_start + (end - start); | 79 | va_end = va_start + (end - start); |
80 | raw_local_irq_save(flags); | ||
82 | __asm__("mcr p15, 1, %0, c15, c9, 4\n\t" | 81 | __asm__("mcr p15, 1, %0, c15, c9, 4\n\t" |
83 | "mcr p15, 1, %1, c15, c9, 5" | 82 | "mcr p15, 1, %1, c15, c9, 5" |
84 | : : "r" (va_start), "r" (va_end)); | 83 | : : "r" (va_start), "r" (va_end)); |
85 | raw_local_irq_restore(flags); | 84 | raw_local_irq_restore(flags); |
85 | l2_put_va(va_start); | ||
86 | } | 86 | } |
87 | 87 | ||
88 | static inline void l2_clean_inv_pa(unsigned long addr) | 88 | static inline void l2_clean_inv_pa(unsigned long addr) |
@@ -106,13 +106,14 @@ static inline void l2_inv_pa_range(unsigned long start, unsigned long end) | |||
106 | */ | 106 | */ |
107 | BUG_ON((start ^ end) >> PAGE_SHIFT); | 107 | BUG_ON((start ^ end) >> PAGE_SHIFT); |
108 | 108 | ||
109 | raw_local_irq_save(flags); | 109 | va_start = l2_get_va(start); |
110 | va_start = l2_start_va(start); | ||
111 | va_end = va_start + (end - start); | 110 | va_end = va_start + (end - start); |
111 | raw_local_irq_save(flags); | ||
112 | __asm__("mcr p15, 1, %0, c15, c11, 4\n\t" | 112 | __asm__("mcr p15, 1, %0, c15, c11, 4\n\t" |
113 | "mcr p15, 1, %1, c15, c11, 5" | 113 | "mcr p15, 1, %1, c15, c11, 5" |
114 | : : "r" (va_start), "r" (va_end)); | 114 | : : "r" (va_start), "r" (va_end)); |
115 | raw_local_irq_restore(flags); | 115 | raw_local_irq_restore(flags); |
116 | l2_put_va(va_start); | ||
116 | } | 117 | } |
117 | 118 | ||
118 | static inline void l2_inv_all(void) | 119 | static inline void l2_inv_all(void) |
diff --git a/arch/arm/mm/cache-v6.S b/arch/arm/mm/cache-v6.S index 99fa688dfadd..c96fa1b3f49f 100644 --- a/arch/arm/mm/cache-v6.S +++ b/arch/arm/mm/cache-v6.S | |||
@@ -203,6 +203,10 @@ ENTRY(v6_flush_kern_dcache_area) | |||
203 | * - end - virtual end address of region | 203 | * - end - virtual end address of region |
204 | */ | 204 | */ |
205 | v6_dma_inv_range: | 205 | v6_dma_inv_range: |
206 | #ifdef CONFIG_DMA_CACHE_RWFO | ||
207 | ldrb r2, [r0] @ read for ownership | ||
208 | strb r2, [r0] @ write for ownership | ||
209 | #endif | ||
206 | tst r0, #D_CACHE_LINE_SIZE - 1 | 210 | tst r0, #D_CACHE_LINE_SIZE - 1 |
207 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 | 211 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 |
208 | #ifdef HARVARD_CACHE | 212 | #ifdef HARVARD_CACHE |
@@ -211,6 +215,10 @@ v6_dma_inv_range: | |||
211 | mcrne p15, 0, r0, c7, c11, 1 @ clean unified line | 215 | mcrne p15, 0, r0, c7, c11, 1 @ clean unified line |
212 | #endif | 216 | #endif |
213 | tst r1, #D_CACHE_LINE_SIZE - 1 | 217 | tst r1, #D_CACHE_LINE_SIZE - 1 |
218 | #ifdef CONFIG_DMA_CACHE_RWFO | ||
219 | ldrneb r2, [r1, #-1] @ read for ownership | ||
220 | strneb r2, [r1, #-1] @ write for ownership | ||
221 | #endif | ||
214 | bic r1, r1, #D_CACHE_LINE_SIZE - 1 | 222 | bic r1, r1, #D_CACHE_LINE_SIZE - 1 |
215 | #ifdef HARVARD_CACHE | 223 | #ifdef HARVARD_CACHE |
216 | mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D line | 224 | mcrne p15, 0, r1, c7, c14, 1 @ clean & invalidate D line |
@@ -218,10 +226,6 @@ v6_dma_inv_range: | |||
218 | mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line | 226 | mcrne p15, 0, r1, c7, c15, 1 @ clean & invalidate unified line |
219 | #endif | 227 | #endif |
220 | 1: | 228 | 1: |
221 | #ifdef CONFIG_DMA_CACHE_RWFO | ||
222 | ldr r2, [r0] @ read for ownership | ||
223 | str r2, [r0] @ write for ownership | ||
224 | #endif | ||
225 | #ifdef HARVARD_CACHE | 229 | #ifdef HARVARD_CACHE |
226 | mcr p15, 0, r0, c7, c6, 1 @ invalidate D line | 230 | mcr p15, 0, r0, c7, c6, 1 @ invalidate D line |
227 | #else | 231 | #else |
@@ -229,6 +233,10 @@ v6_dma_inv_range: | |||
229 | #endif | 233 | #endif |
230 | add r0, r0, #D_CACHE_LINE_SIZE | 234 | add r0, r0, #D_CACHE_LINE_SIZE |
231 | cmp r0, r1 | 235 | cmp r0, r1 |
236 | #ifdef CONFIG_DMA_CACHE_RWFO | ||
237 | ldrlo r2, [r0] @ read for ownership | ||
238 | strlo r2, [r0] @ write for ownership | ||
239 | #endif | ||
232 | blo 1b | 240 | blo 1b |
233 | mov r0, #0 | 241 | mov r0, #0 |
234 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer | 242 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer |
@@ -263,12 +271,12 @@ v6_dma_clean_range: | |||
263 | * - end - virtual end address of region | 271 | * - end - virtual end address of region |
264 | */ | 272 | */ |
265 | ENTRY(v6_dma_flush_range) | 273 | ENTRY(v6_dma_flush_range) |
266 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 | ||
267 | 1: | ||
268 | #ifdef CONFIG_DMA_CACHE_RWFO | 274 | #ifdef CONFIG_DMA_CACHE_RWFO |
269 | ldr r2, [r0] @ read for ownership | 275 | ldrb r2, [r0] @ read for ownership |
270 | str r2, [r0] @ write for ownership | 276 | strb r2, [r0] @ write for ownership |
271 | #endif | 277 | #endif |
278 | bic r0, r0, #D_CACHE_LINE_SIZE - 1 | ||
279 | 1: | ||
272 | #ifdef HARVARD_CACHE | 280 | #ifdef HARVARD_CACHE |
273 | mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line | 281 | mcr p15, 0, r0, c7, c14, 1 @ clean & invalidate D line |
274 | #else | 282 | #else |
@@ -276,6 +284,10 @@ ENTRY(v6_dma_flush_range) | |||
276 | #endif | 284 | #endif |
277 | add r0, r0, #D_CACHE_LINE_SIZE | 285 | add r0, r0, #D_CACHE_LINE_SIZE |
278 | cmp r0, r1 | 286 | cmp r0, r1 |
287 | #ifdef CONFIG_DMA_CACHE_RWFO | ||
288 | ldrlob r2, [r0] @ read for ownership | ||
289 | strlob r2, [r0] @ write for ownership | ||
290 | #endif | ||
279 | blo 1b | 291 | blo 1b |
280 | mov r0, #0 | 292 | mov r0, #0 |
281 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer | 293 | mcr p15, 0, r0, c7, c10, 4 @ drain write buffer |
diff --git a/arch/arm/mm/cache-v7.S b/arch/arm/mm/cache-v7.S index a3ebf7a4f49b..6136e68ce953 100644 --- a/arch/arm/mm/cache-v7.S +++ b/arch/arm/mm/cache-v7.S | |||
@@ -173,15 +173,22 @@ ENTRY(v7_coherent_user_range) | |||
173 | UNWIND(.fnstart ) | 173 | UNWIND(.fnstart ) |
174 | dcache_line_size r2, r3 | 174 | dcache_line_size r2, r3 |
175 | sub r3, r2, #1 | 175 | sub r3, r2, #1 |
176 | bic r0, r0, r3 | 176 | bic r12, r0, r3 |
177 | 1: | 177 | 1: |
178 | USER( mcr p15, 0, r0, c7, c11, 1 ) @ clean D line to the point of unification | 178 | USER( mcr p15, 0, r12, c7, c11, 1 ) @ clean D line to the point of unification |
179 | add r12, r12, r2 | ||
180 | cmp r12, r1 | ||
181 | blo 1b | ||
179 | dsb | 182 | dsb |
180 | USER( mcr p15, 0, r0, c7, c5, 1 ) @ invalidate I line | 183 | icache_line_size r2, r3 |
181 | add r0, r0, r2 | 184 | sub r3, r2, #1 |
185 | bic r12, r0, r3 | ||
182 | 2: | 186 | 2: |
183 | cmp r0, r1 | 187 | USER( mcr p15, 0, r12, c7, c5, 1 ) @ invalidate I line |
184 | blo 1b | 188 | add r12, r12, r2 |
189 | cmp r12, r1 | ||
190 | blo 2b | ||
191 | 3: | ||
185 | mov r0, #0 | 192 | mov r0, #0 |
186 | ALT_SMP(mcr p15, 0, r0, c7, c1, 6) @ invalidate BTB Inner Shareable | 193 | ALT_SMP(mcr p15, 0, r0, c7, c1, 6) @ invalidate BTB Inner Shareable |
187 | ALT_UP(mcr p15, 0, r0, c7, c5, 6) @ invalidate BTB | 194 | ALT_UP(mcr p15, 0, r0, c7, c5, 6) @ invalidate BTB |
@@ -194,10 +201,10 @@ ENTRY(v7_coherent_user_range) | |||
194 | * isn't mapped, just try the next page. | 201 | * isn't mapped, just try the next page. |
195 | */ | 202 | */ |
196 | 9001: | 203 | 9001: |
197 | mov r0, r0, lsr #12 | 204 | mov r12, r12, lsr #12 |
198 | mov r0, r0, lsl #12 | 205 | mov r12, r12, lsl #12 |
199 | add r0, r0, #4096 | 206 | add r12, r12, #4096 |
200 | b 2b | 207 | b 3b |
201 | UNWIND(.fnend ) | 208 | UNWIND(.fnend ) |
202 | ENDPROC(v7_coherent_kern_range) | 209 | ENDPROC(v7_coherent_kern_range) |
203 | ENDPROC(v7_coherent_user_range) | 210 | ENDPROC(v7_coherent_user_range) |
diff --git a/arch/arm/mm/cache-xsc3l2.c b/arch/arm/mm/cache-xsc3l2.c index c3154928bccd..5a32020471e3 100644 --- a/arch/arm/mm/cache-xsc3l2.c +++ b/arch/arm/mm/cache-xsc3l2.c | |||
@@ -17,14 +17,10 @@ | |||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
18 | */ | 18 | */ |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/highmem.h> | ||
20 | #include <asm/system.h> | 21 | #include <asm/system.h> |
21 | #include <asm/cputype.h> | 22 | #include <asm/cputype.h> |
22 | #include <asm/cacheflush.h> | 23 | #include <asm/cacheflush.h> |
23 | #include <asm/kmap_types.h> | ||
24 | #include <asm/fixmap.h> | ||
25 | #include <asm/pgtable.h> | ||
26 | #include <asm/tlbflush.h> | ||
27 | #include "mm.h" | ||
28 | 24 | ||
29 | #define CR_L2 (1 << 26) | 25 | #define CR_L2 (1 << 26) |
30 | 26 | ||
@@ -71,16 +67,15 @@ static inline void xsc3_l2_inv_all(void) | |||
71 | dsb(); | 67 | dsb(); |
72 | } | 68 | } |
73 | 69 | ||
70 | static inline void l2_unmap_va(unsigned long va) | ||
71 | { | ||
74 | #ifdef CONFIG_HIGHMEM | 72 | #ifdef CONFIG_HIGHMEM |
75 | #define l2_map_save_flags(x) raw_local_save_flags(x) | 73 | if (va != -1) |
76 | #define l2_map_restore_flags(x) raw_local_irq_restore(x) | 74 | kunmap_atomic((void *)va); |
77 | #else | ||
78 | #define l2_map_save_flags(x) ((x) = 0) | ||
79 | #define l2_map_restore_flags(x) ((void)(x)) | ||
80 | #endif | 75 | #endif |
76 | } | ||
81 | 77 | ||
82 | static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va, | 78 | static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va) |
83 | unsigned long flags) | ||
84 | { | 79 | { |
85 | #ifdef CONFIG_HIGHMEM | 80 | #ifdef CONFIG_HIGHMEM |
86 | unsigned long va = prev_va & PAGE_MASK; | 81 | unsigned long va = prev_va & PAGE_MASK; |
@@ -89,17 +84,10 @@ static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va, | |||
89 | /* | 84 | /* |
90 | * Switching to a new page. Because cache ops are | 85 | * Switching to a new page. Because cache ops are |
91 | * using virtual addresses only, we must put a mapping | 86 | * using virtual addresses only, we must put a mapping |
92 | * in place for it. We also enable interrupts for a | 87 | * in place for it. |
93 | * short while and disable them again to protect this | ||
94 | * mapping. | ||
95 | */ | 88 | */ |
96 | unsigned long idx; | 89 | l2_unmap_va(prev_va); |
97 | raw_local_irq_restore(flags); | 90 | va = (unsigned long)kmap_atomic_pfn(pa >> PAGE_SHIFT); |
98 | idx = KM_L2_CACHE + KM_TYPE_NR * smp_processor_id(); | ||
99 | va = __fix_to_virt(FIX_KMAP_BEGIN + idx); | ||
100 | raw_local_irq_restore(flags | PSR_I_BIT); | ||
101 | set_pte_ext(TOP_PTE(va), pfn_pte(pa >> PAGE_SHIFT, PAGE_KERNEL), 0); | ||
102 | local_flush_tlb_kernel_page(va); | ||
103 | } | 91 | } |
104 | return va + (pa_offset >> (32 - PAGE_SHIFT)); | 92 | return va + (pa_offset >> (32 - PAGE_SHIFT)); |
105 | #else | 93 | #else |
@@ -109,7 +97,7 @@ static inline unsigned long l2_map_va(unsigned long pa, unsigned long prev_va, | |||
109 | 97 | ||
110 | static void xsc3_l2_inv_range(unsigned long start, unsigned long end) | 98 | static void xsc3_l2_inv_range(unsigned long start, unsigned long end) |
111 | { | 99 | { |
112 | unsigned long vaddr, flags; | 100 | unsigned long vaddr; |
113 | 101 | ||
114 | if (start == 0 && end == -1ul) { | 102 | if (start == 0 && end == -1ul) { |
115 | xsc3_l2_inv_all(); | 103 | xsc3_l2_inv_all(); |
@@ -117,13 +105,12 @@ static void xsc3_l2_inv_range(unsigned long start, unsigned long end) | |||
117 | } | 105 | } |
118 | 106 | ||
119 | vaddr = -1; /* to force the first mapping */ | 107 | vaddr = -1; /* to force the first mapping */ |
120 | l2_map_save_flags(flags); | ||
121 | 108 | ||
122 | /* | 109 | /* |
123 | * Clean and invalidate partial first cache line. | 110 | * Clean and invalidate partial first cache line. |
124 | */ | 111 | */ |
125 | if (start & (CACHE_LINE_SIZE - 1)) { | 112 | if (start & (CACHE_LINE_SIZE - 1)) { |
126 | vaddr = l2_map_va(start & ~(CACHE_LINE_SIZE - 1), vaddr, flags); | 113 | vaddr = l2_map_va(start & ~(CACHE_LINE_SIZE - 1), vaddr); |
127 | xsc3_l2_clean_mva(vaddr); | 114 | xsc3_l2_clean_mva(vaddr); |
128 | xsc3_l2_inv_mva(vaddr); | 115 | xsc3_l2_inv_mva(vaddr); |
129 | start = (start | (CACHE_LINE_SIZE - 1)) + 1; | 116 | start = (start | (CACHE_LINE_SIZE - 1)) + 1; |
@@ -133,7 +120,7 @@ static void xsc3_l2_inv_range(unsigned long start, unsigned long end) | |||
133 | * Invalidate all full cache lines between 'start' and 'end'. | 120 | * Invalidate all full cache lines between 'start' and 'end'. |
134 | */ | 121 | */ |
135 | while (start < (end & ~(CACHE_LINE_SIZE - 1))) { | 122 | while (start < (end & ~(CACHE_LINE_SIZE - 1))) { |
136 | vaddr = l2_map_va(start, vaddr, flags); | 123 | vaddr = l2_map_va(start, vaddr); |
137 | xsc3_l2_inv_mva(vaddr); | 124 | xsc3_l2_inv_mva(vaddr); |
138 | start += CACHE_LINE_SIZE; | 125 | start += CACHE_LINE_SIZE; |
139 | } | 126 | } |
@@ -142,31 +129,30 @@ static void xsc3_l2_inv_range(unsigned long start, unsigned long end) | |||
142 | * Clean and invalidate partial last cache line. | 129 | * Clean and invalidate partial last cache line. |
143 | */ | 130 | */ |
144 | if (start < end) { | 131 | if (start < end) { |
145 | vaddr = l2_map_va(start, vaddr, flags); | 132 | vaddr = l2_map_va(start, vaddr); |
146 | xsc3_l2_clean_mva(vaddr); | 133 | xsc3_l2_clean_mva(vaddr); |
147 | xsc3_l2_inv_mva(vaddr); | 134 | xsc3_l2_inv_mva(vaddr); |
148 | } | 135 | } |
149 | 136 | ||
150 | l2_map_restore_flags(flags); | 137 | l2_unmap_va(vaddr); |
151 | 138 | ||
152 | dsb(); | 139 | dsb(); |
153 | } | 140 | } |
154 | 141 | ||
155 | static void xsc3_l2_clean_range(unsigned long start, unsigned long end) | 142 | static void xsc3_l2_clean_range(unsigned long start, unsigned long end) |
156 | { | 143 | { |
157 | unsigned long vaddr, flags; | 144 | unsigned long vaddr; |
158 | 145 | ||
159 | vaddr = -1; /* to force the first mapping */ | 146 | vaddr = -1; /* to force the first mapping */ |
160 | l2_map_save_flags(flags); | ||
161 | 147 | ||
162 | start &= ~(CACHE_LINE_SIZE - 1); | 148 | start &= ~(CACHE_LINE_SIZE - 1); |
163 | while (start < end) { | 149 | while (start < end) { |
164 | vaddr = l2_map_va(start, vaddr, flags); | 150 | vaddr = l2_map_va(start, vaddr); |
165 | xsc3_l2_clean_mva(vaddr); | 151 | xsc3_l2_clean_mva(vaddr); |
166 | start += CACHE_LINE_SIZE; | 152 | start += CACHE_LINE_SIZE; |
167 | } | 153 | } |
168 | 154 | ||
169 | l2_map_restore_flags(flags); | 155 | l2_unmap_va(vaddr); |
170 | 156 | ||
171 | dsb(); | 157 | dsb(); |
172 | } | 158 | } |
@@ -193,7 +179,7 @@ static inline void xsc3_l2_flush_all(void) | |||
193 | 179 | ||
194 | static void xsc3_l2_flush_range(unsigned long start, unsigned long end) | 180 | static void xsc3_l2_flush_range(unsigned long start, unsigned long end) |
195 | { | 181 | { |
196 | unsigned long vaddr, flags; | 182 | unsigned long vaddr; |
197 | 183 | ||
198 | if (start == 0 && end == -1ul) { | 184 | if (start == 0 && end == -1ul) { |
199 | xsc3_l2_flush_all(); | 185 | xsc3_l2_flush_all(); |
@@ -201,17 +187,16 @@ static void xsc3_l2_flush_range(unsigned long start, unsigned long end) | |||
201 | } | 187 | } |
202 | 188 | ||
203 | vaddr = -1; /* to force the first mapping */ | 189 | vaddr = -1; /* to force the first mapping */ |
204 | l2_map_save_flags(flags); | ||
205 | 190 | ||
206 | start &= ~(CACHE_LINE_SIZE - 1); | 191 | start &= ~(CACHE_LINE_SIZE - 1); |
207 | while (start < end) { | 192 | while (start < end) { |
208 | vaddr = l2_map_va(start, vaddr, flags); | 193 | vaddr = l2_map_va(start, vaddr); |
209 | xsc3_l2_clean_mva(vaddr); | 194 | xsc3_l2_clean_mva(vaddr); |
210 | xsc3_l2_inv_mva(vaddr); | 195 | xsc3_l2_inv_mva(vaddr); |
211 | start += CACHE_LINE_SIZE; | 196 | start += CACHE_LINE_SIZE; |
212 | } | 197 | } |
213 | 198 | ||
214 | l2_map_restore_flags(flags); | 199 | l2_unmap_va(vaddr); |
215 | 200 | ||
216 | dsb(); | 201 | dsb(); |
217 | } | 202 | } |
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index ac6a36142fcd..809f1bf9fa29 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/device.h> | 18 | #include <linux/device.h> |
19 | #include <linux/dma-mapping.h> | 19 | #include <linux/dma-mapping.h> |
20 | #include <linux/highmem.h> | ||
20 | 21 | ||
21 | #include <asm/memory.h> | 22 | #include <asm/memory.h> |
22 | #include <asm/highmem.h> | 23 | #include <asm/highmem.h> |
@@ -480,10 +481,10 @@ static void dma_cache_maint_page(struct page *page, unsigned long offset, | |||
480 | op(vaddr, len, dir); | 481 | op(vaddr, len, dir); |
481 | kunmap_high(page); | 482 | kunmap_high(page); |
482 | } else if (cache_is_vipt()) { | 483 | } else if (cache_is_vipt()) { |
483 | pte_t saved_pte; | 484 | /* unmapped pages might still be cached */ |
484 | vaddr = kmap_high_l1_vipt(page, &saved_pte); | 485 | vaddr = kmap_atomic(page); |
485 | op(vaddr + offset, len, dir); | 486 | op(vaddr + offset, len, dir); |
486 | kunmap_high_l1_vipt(page, saved_pte); | 487 | kunmap_atomic(vaddr); |
487 | } | 488 | } |
488 | } else { | 489 | } else { |
489 | vaddr = page_address(page) + offset; | 490 | vaddr = page_address(page) + offset; |
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 391ffae75098..c29f2839f1d2 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/mm.h> | 11 | #include <linux/mm.h> |
12 | #include <linux/pagemap.h> | 12 | #include <linux/pagemap.h> |
13 | #include <linux/highmem.h> | ||
13 | 14 | ||
14 | #include <asm/cacheflush.h> | 15 | #include <asm/cacheflush.h> |
15 | #include <asm/cachetype.h> | 16 | #include <asm/cachetype.h> |
@@ -180,10 +181,10 @@ void __flush_dcache_page(struct address_space *mapping, struct page *page) | |||
180 | __cpuc_flush_dcache_area(addr, PAGE_SIZE); | 181 | __cpuc_flush_dcache_area(addr, PAGE_SIZE); |
181 | kunmap_high(page); | 182 | kunmap_high(page); |
182 | } else if (cache_is_vipt()) { | 183 | } else if (cache_is_vipt()) { |
183 | pte_t saved_pte; | 184 | /* unmapped pages might still be cached */ |
184 | addr = kmap_high_l1_vipt(page, &saved_pte); | 185 | addr = kmap_atomic(page); |
185 | __cpuc_flush_dcache_area(addr, PAGE_SIZE); | 186 | __cpuc_flush_dcache_area(addr, PAGE_SIZE); |
186 | kunmap_high_l1_vipt(page, saved_pte); | 187 | kunmap_atomic(addr); |
187 | } | 188 | } |
188 | } | 189 | } |
189 | 190 | ||
diff --git a/arch/arm/mm/highmem.c b/arch/arm/mm/highmem.c index c435fd9e1da9..807c0573abbe 100644 --- a/arch/arm/mm/highmem.c +++ b/arch/arm/mm/highmem.c | |||
@@ -140,90 +140,3 @@ struct page *kmap_atomic_to_page(const void *ptr) | |||
140 | pte = TOP_PTE(vaddr); | 140 | pte = TOP_PTE(vaddr); |
141 | return pte_page(*pte); | 141 | return pte_page(*pte); |
142 | } | 142 | } |
143 | |||
144 | #ifdef CONFIG_CPU_CACHE_VIPT | ||
145 | |||
146 | #include <linux/percpu.h> | ||
147 | |||
148 | /* | ||
149 | * The VIVT cache of a highmem page is always flushed before the page | ||
150 | * is unmapped. Hence unmapped highmem pages need no cache maintenance | ||
151 | * in that case. | ||
152 | * | ||
153 | * However unmapped pages may still be cached with a VIPT cache, and | ||
154 | * it is not possible to perform cache maintenance on them using physical | ||
155 | * addresses unfortunately. So we have no choice but to set up a temporary | ||
156 | * virtual mapping for that purpose. | ||
157 | * | ||
158 | * Yet this VIPT cache maintenance may be triggered from DMA support | ||
159 | * functions which are possibly called from interrupt context. As we don't | ||
160 | * want to keep interrupt disabled all the time when such maintenance is | ||
161 | * taking place, we therefore allow for some reentrancy by preserving and | ||
162 | * restoring the previous fixmap entry before the interrupted context is | ||
163 | * resumed. If the reentrancy depth is 0 then there is no need to restore | ||
164 | * the previous fixmap, and leaving the current one in place allow it to | ||
165 | * be reused the next time without a TLB flush (common with DMA). | ||
166 | */ | ||
167 | |||
168 | static DEFINE_PER_CPU(int, kmap_high_l1_vipt_depth); | ||
169 | |||
170 | void *kmap_high_l1_vipt(struct page *page, pte_t *saved_pte) | ||
171 | { | ||
172 | unsigned int idx, cpu; | ||
173 | int *depth; | ||
174 | unsigned long vaddr, flags; | ||
175 | pte_t pte, *ptep; | ||
176 | |||
177 | if (!in_interrupt()) | ||
178 | preempt_disable(); | ||
179 | |||
180 | cpu = smp_processor_id(); | ||
181 | depth = &per_cpu(kmap_high_l1_vipt_depth, cpu); | ||
182 | |||
183 | idx = KM_L1_CACHE + KM_TYPE_NR * cpu; | ||
184 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | ||
185 | ptep = TOP_PTE(vaddr); | ||
186 | pte = mk_pte(page, kmap_prot); | ||
187 | |||
188 | raw_local_irq_save(flags); | ||
189 | (*depth)++; | ||
190 | if (pte_val(*ptep) == pte_val(pte)) { | ||
191 | *saved_pte = pte; | ||
192 | } else { | ||
193 | *saved_pte = *ptep; | ||
194 | set_pte_ext(ptep, pte, 0); | ||
195 | local_flush_tlb_kernel_page(vaddr); | ||
196 | } | ||
197 | raw_local_irq_restore(flags); | ||
198 | |||
199 | return (void *)vaddr; | ||
200 | } | ||
201 | |||
202 | void kunmap_high_l1_vipt(struct page *page, pte_t saved_pte) | ||
203 | { | ||
204 | unsigned int idx, cpu = smp_processor_id(); | ||
205 | int *depth = &per_cpu(kmap_high_l1_vipt_depth, cpu); | ||
206 | unsigned long vaddr, flags; | ||
207 | pte_t pte, *ptep; | ||
208 | |||
209 | idx = KM_L1_CACHE + KM_TYPE_NR * cpu; | ||
210 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | ||
211 | ptep = TOP_PTE(vaddr); | ||
212 | pte = mk_pte(page, kmap_prot); | ||
213 | |||
214 | BUG_ON(pte_val(*ptep) != pte_val(pte)); | ||
215 | BUG_ON(*depth <= 0); | ||
216 | |||
217 | raw_local_irq_save(flags); | ||
218 | (*depth)--; | ||
219 | if (*depth != 0 && pte_val(pte) != pte_val(saved_pte)) { | ||
220 | set_pte_ext(ptep, saved_pte, 0); | ||
221 | local_flush_tlb_kernel_page(vaddr); | ||
222 | } | ||
223 | raw_local_irq_restore(flags); | ||
224 | |||
225 | if (!in_interrupt()) | ||
226 | preempt_enable(); | ||
227 | } | ||
228 | |||
229 | #endif /* CONFIG_CPU_CACHE_VIPT */ | ||
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S index 7d63beaf9745..b795afd0a2c6 100644 --- a/arch/arm/mm/proc-macros.S +++ b/arch/arm/mm/proc-macros.S | |||
@@ -61,17 +61,27 @@ | |||
61 | .endm | 61 | .endm |
62 | 62 | ||
63 | /* | 63 | /* |
64 | * cache_line_size - get the cache line size from the CSIDR register | 64 | * dcache_line_size - get the minimum D-cache line size from the CTR register |
65 | * (available on ARMv7+). It assumes that the CSSR register was configured | 65 | * on ARMv7. |
66 | * to access the L1 data cache CSIDR. | ||
67 | */ | 66 | */ |
68 | .macro dcache_line_size, reg, tmp | 67 | .macro dcache_line_size, reg, tmp |
69 | mrc p15, 1, \tmp, c0, c0, 0 @ read CSIDR | 68 | mrc p15, 0, \tmp, c0, c0, 1 @ read ctr |
70 | and \tmp, \tmp, #7 @ cache line size encoding | 69 | lsr \tmp, \tmp, #16 |
71 | mov \reg, #16 @ size offset | 70 | and \tmp, \tmp, #0xf @ cache line size encoding |
71 | mov \reg, #4 @ bytes per word | ||
72 | mov \reg, \reg, lsl \tmp @ actual cache line size | 72 | mov \reg, \reg, lsl \tmp @ actual cache line size |
73 | .endm | 73 | .endm |
74 | 74 | ||
75 | /* | ||
76 | * icache_line_size - get the minimum I-cache line size from the CTR register | ||
77 | * on ARMv7. | ||
78 | */ | ||
79 | .macro icache_line_size, reg, tmp | ||
80 | mrc p15, 0, \tmp, c0, c0, 1 @ read ctr | ||
81 | and \tmp, \tmp, #0xf @ cache line size encoding | ||
82 | mov \reg, #4 @ bytes per word | ||
83 | mov \reg, \reg, lsl \tmp @ actual cache line size | ||
84 | .endm | ||
75 | 85 | ||
76 | /* | 86 | /* |
77 | * Sanity check the PTE configuration for the code below - which makes | 87 | * Sanity check the PTE configuration for the code below - which makes |
diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c index 155fe43a672b..8722a136f3a5 100644 --- a/arch/arm/plat-omap/counter_32k.c +++ b/arch/arm/plat-omap/counter_32k.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/clk.h> | 17 | #include <linux/clk.h> |
18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
19 | #include <linux/err.h> | ||
19 | 20 | ||
20 | #include <plat/common.h> | 21 | #include <plat/common.h> |
21 | #include <plat/board.h> | 22 | #include <plat/board.h> |
@@ -164,7 +165,7 @@ static int __init omap_init_clocksource_32k(void) | |||
164 | return -ENODEV; | 165 | return -ENODEV; |
165 | 166 | ||
166 | sync_32k_ick = clk_get(NULL, "omap_32ksync_ick"); | 167 | sync_32k_ick = clk_get(NULL, "omap_32ksync_ick"); |
167 | if (sync_32k_ick) | 168 | if (!IS_ERR(sync_32k_ick)) |
168 | clk_enable(sync_32k_ick); | 169 | clk_enable(sync_32k_ick); |
169 | 170 | ||
170 | clocksource_32k.mult = clocksource_hz2mult(32768, | 171 | clocksource_32k.mult = clocksource_hz2mult(32768, |
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index e2c8eebe6b3a..74dac419d328 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c | |||
@@ -166,7 +166,7 @@ static void __init omap_detect_sram(void) | |||
166 | cpu_is_omap1710()) | 166 | cpu_is_omap1710()) |
167 | omap_sram_size = 0x4000; /* 16K */ | 167 | omap_sram_size = 0x4000; /* 16K */ |
168 | else if (cpu_is_omap1611()) | 168 | else if (cpu_is_omap1611()) |
169 | omap_sram_size = 0x3e800; /* 250K */ | 169 | omap_sram_size = SZ_256K; |
170 | else { | 170 | else { |
171 | printk(KERN_ERR "Could not detect SRAM size\n"); | 171 | printk(KERN_ERR "Could not detect SRAM size\n"); |
172 | omap_sram_size = 0x4000; | 172 | omap_sram_size = 0x4000; |
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig index 5a27b1b538f2..eb105e61c746 100644 --- a/arch/arm/plat-s3c24xx/Kconfig +++ b/arch/arm/plat-s3c24xx/Kconfig | |||
@@ -8,7 +8,7 @@ config PLAT_S3C24XX | |||
8 | default y | 8 | default y |
9 | select NO_IOPORT | 9 | select NO_IOPORT |
10 | select ARCH_REQUIRE_GPIOLIB | 10 | select ARCH_REQUIRE_GPIOLIB |
11 | select S3C_DEVICE_NAND | 11 | select S3C_DEV_NAND |
12 | select S3C_GPIO_CFG_S3C24XX | 12 | select S3C_GPIO_CFG_S3C24XX |
13 | help | 13 | help |
14 | Base platform code for any Samsung S3C24XX device | 14 | Base platform code for any Samsung S3C24XX device |
diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c index 76d0858c3cbb..4a10c0f684b2 100644 --- a/arch/arm/plat-s3c24xx/cpu.c +++ b/arch/arm/plat-s3c24xx/cpu.c | |||
@@ -88,7 +88,7 @@ static struct cpu_table cpu_ids[] __initdata = { | |||
88 | { | 88 | { |
89 | .idcode = 0x32440000, | 89 | .idcode = 0x32440000, |
90 | .idmask = 0xffffffff, | 90 | .idmask = 0xffffffff, |
91 | .map_io = s3c244x_map_io, | 91 | .map_io = s3c2440_map_io, |
92 | .init_clocks = s3c244x_init_clocks, | 92 | .init_clocks = s3c244x_init_clocks, |
93 | .init_uarts = s3c244x_init_uarts, | 93 | .init_uarts = s3c244x_init_uarts, |
94 | .init = s3c2440_init, | 94 | .init = s3c2440_init, |
@@ -97,7 +97,7 @@ static struct cpu_table cpu_ids[] __initdata = { | |||
97 | { | 97 | { |
98 | .idcode = 0x32440001, | 98 | .idcode = 0x32440001, |
99 | .idmask = 0xffffffff, | 99 | .idmask = 0xffffffff, |
100 | .map_io = s3c244x_map_io, | 100 | .map_io = s3c2440_map_io, |
101 | .init_clocks = s3c244x_init_clocks, | 101 | .init_clocks = s3c244x_init_clocks, |
102 | .init_uarts = s3c244x_init_uarts, | 102 | .init_uarts = s3c244x_init_uarts, |
103 | .init = s3c2440_init, | 103 | .init = s3c2440_init, |
@@ -106,7 +106,7 @@ static struct cpu_table cpu_ids[] __initdata = { | |||
106 | { | 106 | { |
107 | .idcode = 0x32440aaa, | 107 | .idcode = 0x32440aaa, |
108 | .idmask = 0xffffffff, | 108 | .idmask = 0xffffffff, |
109 | .map_io = s3c244x_map_io, | 109 | .map_io = s3c2442_map_io, |
110 | .init_clocks = s3c244x_init_clocks, | 110 | .init_clocks = s3c244x_init_clocks, |
111 | .init_uarts = s3c244x_init_uarts, | 111 | .init_uarts = s3c244x_init_uarts, |
112 | .init = s3c2442_init, | 112 | .init = s3c2442_init, |
@@ -115,7 +115,7 @@ static struct cpu_table cpu_ids[] __initdata = { | |||
115 | { | 115 | { |
116 | .idcode = 0x32440aab, | 116 | .idcode = 0x32440aab, |
117 | .idmask = 0xffffffff, | 117 | .idmask = 0xffffffff, |
118 | .map_io = s3c244x_map_io, | 118 | .map_io = s3c2442_map_io, |
119 | .init_clocks = s3c244x_init_clocks, | 119 | .init_clocks = s3c244x_init_clocks, |
120 | .init_uarts = s3c244x_init_uarts, | 120 | .init_uarts = s3c244x_init_uarts, |
121 | .init = s3c2442_init, | 121 | .init = s3c2442_init, |
diff --git a/arch/arm/plat-s3c24xx/gpiolib.c b/arch/arm/plat-s3c24xx/gpiolib.c index 24c6f5a30596..243b6411050d 100644 --- a/arch/arm/plat-s3c24xx/gpiolib.c +++ b/arch/arm/plat-s3c24xx/gpiolib.c | |||
@@ -82,8 +82,6 @@ static struct s3c_gpio_cfg s3c24xx_gpiocfg_banka = { | |||
82 | struct s3c_gpio_cfg s3c24xx_gpiocfg_default = { | 82 | struct s3c_gpio_cfg s3c24xx_gpiocfg_default = { |
83 | .set_config = s3c_gpio_setcfg_s3c24xx, | 83 | .set_config = s3c_gpio_setcfg_s3c24xx, |
84 | .get_config = s3c_gpio_getcfg_s3c24xx, | 84 | .get_config = s3c_gpio_getcfg_s3c24xx, |
85 | .set_pull = s3c_gpio_setpull_1up, | ||
86 | .get_pull = s3c_gpio_getpull_1up, | ||
87 | }; | 85 | }; |
88 | 86 | ||
89 | struct s3c_gpio_chip s3c24xx_gpios[] = { | 87 | struct s3c_gpio_chip s3c24xx_gpios[] = { |
diff --git a/arch/arm/plat-s3c24xx/include/plat/s3c244x.h b/arch/arm/plat-s3c24xx/include/plat/s3c244x.h index 307248d1ccbb..89e8d0a25f87 100644 --- a/arch/arm/plat-s3c24xx/include/plat/s3c244x.h +++ b/arch/arm/plat-s3c24xx/include/plat/s3c244x.h | |||
@@ -21,17 +21,22 @@ extern void s3c244x_init_clocks(int xtal); | |||
21 | #else | 21 | #else |
22 | #define s3c244x_init_clocks NULL | 22 | #define s3c244x_init_clocks NULL |
23 | #define s3c244x_init_uarts NULL | 23 | #define s3c244x_init_uarts NULL |
24 | #define s3c244x_map_io NULL | ||
25 | #endif | 24 | #endif |
26 | 25 | ||
27 | #ifdef CONFIG_CPU_S3C2440 | 26 | #ifdef CONFIG_CPU_S3C2440 |
28 | extern int s3c2440_init(void); | 27 | extern int s3c2440_init(void); |
28 | |||
29 | extern void s3c2440_map_io(void); | ||
29 | #else | 30 | #else |
30 | #define s3c2440_init NULL | 31 | #define s3c2440_init NULL |
32 | #define s3c2440_map_io NULL | ||
31 | #endif | 33 | #endif |
32 | 34 | ||
33 | #ifdef CONFIG_CPU_S3C2442 | 35 | #ifdef CONFIG_CPU_S3C2442 |
34 | extern int s3c2442_init(void); | 36 | extern int s3c2442_init(void); |
37 | |||
38 | extern void s3c2442_map_io(void); | ||
35 | #else | 39 | #else |
36 | #define s3c2442_init NULL | 40 | #define s3c2442_init NULL |
41 | #define s3c2442_map_io NULL | ||
37 | #endif | 42 | #endif |
diff --git a/arch/arm/plat-samsung/gpio-config.c b/arch/arm/plat-samsung/gpio-config.c index b732b773b9af..0aa32f242ee4 100644 --- a/arch/arm/plat-samsung/gpio-config.c +++ b/arch/arm/plat-samsung/gpio-config.c | |||
@@ -280,18 +280,17 @@ s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip, | |||
280 | } | 280 | } |
281 | #endif | 281 | #endif |
282 | 282 | ||
283 | #ifdef CONFIG_S3C_GPIO_PULL_UP | 283 | #if defined(CONFIG_S3C_GPIO_PULL_UP) || defined(CONFIG_S3C_GPIO_PULL_DOWN) |
284 | int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip, | 284 | static int s3c_gpio_setpull_1(struct s3c_gpio_chip *chip, |
285 | unsigned int off, s3c_gpio_pull_t pull) | 285 | unsigned int off, s3c_gpio_pull_t pull, |
286 | s3c_gpio_pull_t updown) | ||
286 | { | 287 | { |
287 | void __iomem *reg = chip->base + 0x08; | 288 | void __iomem *reg = chip->base + 0x08; |
288 | u32 pup = __raw_readl(reg); | 289 | u32 pup = __raw_readl(reg); |
289 | 290 | ||
290 | pup = __raw_readl(reg); | 291 | if (pull == updown) |
291 | |||
292 | if (pup == S3C_GPIO_PULL_UP) | ||
293 | pup &= ~(1 << off); | 292 | pup &= ~(1 << off); |
294 | else if (pup == S3C_GPIO_PULL_NONE) | 293 | else if (pull == S3C_GPIO_PULL_NONE) |
295 | pup |= (1 << off); | 294 | pup |= (1 << off); |
296 | else | 295 | else |
297 | return -EINVAL; | 296 | return -EINVAL; |
@@ -300,17 +299,45 @@ int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip, | |||
300 | return 0; | 299 | return 0; |
301 | } | 300 | } |
302 | 301 | ||
303 | s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip, | 302 | static s3c_gpio_pull_t s3c_gpio_getpull_1(struct s3c_gpio_chip *chip, |
304 | unsigned int off) | 303 | unsigned int off, s3c_gpio_pull_t updown) |
305 | { | 304 | { |
306 | void __iomem *reg = chip->base + 0x08; | 305 | void __iomem *reg = chip->base + 0x08; |
307 | u32 pup = __raw_readl(reg); | 306 | u32 pup = __raw_readl(reg); |
308 | 307 | ||
309 | pup &= (1 << off); | 308 | pup &= (1 << off); |
310 | return pup ? S3C_GPIO_PULL_NONE : S3C_GPIO_PULL_UP; | 309 | return pup ? S3C_GPIO_PULL_NONE : updown; |
310 | } | ||
311 | #endif /* CONFIG_S3C_GPIO_PULL_UP || CONFIG_S3C_GPIO_PULL_DOWN */ | ||
312 | |||
313 | #ifdef CONFIG_S3C_GPIO_PULL_UP | ||
314 | s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip, | ||
315 | unsigned int off) | ||
316 | { | ||
317 | return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_UP); | ||
318 | } | ||
319 | |||
320 | int s3c_gpio_setpull_1up(struct s3c_gpio_chip *chip, | ||
321 | unsigned int off, s3c_gpio_pull_t pull) | ||
322 | { | ||
323 | return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_UP); | ||
311 | } | 324 | } |
312 | #endif /* CONFIG_S3C_GPIO_PULL_UP */ | 325 | #endif /* CONFIG_S3C_GPIO_PULL_UP */ |
313 | 326 | ||
327 | #ifdef CONFIG_S3C_GPIO_PULL_DOWN | ||
328 | s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip, | ||
329 | unsigned int off) | ||
330 | { | ||
331 | return s3c_gpio_getpull_1(chip, off, S3C_GPIO_PULL_DOWN); | ||
332 | } | ||
333 | |||
334 | int s3c_gpio_setpull_1down(struct s3c_gpio_chip *chip, | ||
335 | unsigned int off, s3c_gpio_pull_t pull) | ||
336 | { | ||
337 | return s3c_gpio_setpull_1(chip, off, pull, S3C_GPIO_PULL_DOWN); | ||
338 | } | ||
339 | #endif /* CONFIG_S3C_GPIO_PULL_DOWN */ | ||
340 | |||
314 | #ifdef CONFIG_S5P_GPIO_DRVSTR | 341 | #ifdef CONFIG_S5P_GPIO_DRVSTR |
315 | s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin) | 342 | s5p_gpio_drvstr_t s5p_gpio_get_drvstr(unsigned int pin) |
316 | { | 343 | { |
diff --git a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h index 8fd65d8b5863..0d2c5703f1ee 100644 --- a/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h +++ b/arch/arm/plat-samsung/include/plat/gpio-cfg-helpers.h | |||
@@ -210,6 +210,17 @@ extern s3c_gpio_pull_t s3c_gpio_getpull_1up(struct s3c_gpio_chip *chip, | |||
210 | unsigned int off); | 210 | unsigned int off); |
211 | 211 | ||
212 | /** | 212 | /** |
213 | * s3c_gpio_getpull_1down() - Get configuration for choice of down or none | ||
214 | * @chip: The gpio chip that the GPIO pin belongs to | ||
215 | * @off: The offset to the pin to get the configuration of. | ||
216 | * | ||
217 | * This helper function reads the state of the pull-down resistor for the | ||
218 | * given GPIO in the same case as s3c_gpio_setpull_1down. | ||
219 | */ | ||
220 | extern s3c_gpio_pull_t s3c_gpio_getpull_1down(struct s3c_gpio_chip *chip, | ||
221 | unsigned int off); | ||
222 | |||
223 | /** | ||
213 | * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443. | 224 | * s3c_gpio_setpull_s3c2443() - Pull configuration for s3c2443. |
214 | * @chip: The gpio chip that is being configured. | 225 | * @chip: The gpio chip that is being configured. |
215 | * @off: The offset for the GPIO being configured. | 226 | * @off: The offset for the GPIO being configured. |
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 55590a4d87c9..2fea897ebeb1 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: Thu Sep 9 22:43:01 2010 | 15 | # Last update: Sun Dec 12 23:24:27 2010 |
16 | # | 16 | # |
17 | # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number | 17 | # machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number |
18 | # | 18 | # |
@@ -2321,7 +2321,7 @@ mx31txtr MACH_MX31TXTR MX31TXTR 2332 | |||
2321 | u380 MACH_U380 U380 2333 | 2321 | u380 MACH_U380 U380 2333 |
2322 | oamp3_hualu MACH_HUALU_BOARD HUALU_BOARD 2334 | 2322 | oamp3_hualu MACH_HUALU_BOARD HUALU_BOARD 2334 |
2323 | npcmx50 MACH_NPCMX50 NPCMX50 2335 | 2323 | npcmx50 MACH_NPCMX50 NPCMX50 2335 |
2324 | mx51_lange51 MACH_MX51_LANGE51 MX51_LANGE51 2336 | 2324 | mx51_efikamx MACH_MX51_EFIKAMX MX51_EFIKAMX 2336 |
2325 | mx51_lange52 MACH_MX51_LANGE52 MX51_LANGE52 2337 | 2325 | mx51_lange52 MACH_MX51_LANGE52 MX51_LANGE52 2337 |
2326 | riom MACH_RIOM RIOM 2338 | 2326 | riom MACH_RIOM RIOM 2338 |
2327 | comcas MACH_COMCAS COMCAS 2339 | 2327 | comcas MACH_COMCAS COMCAS 2339 |
@@ -2355,7 +2355,7 @@ at91sam9263cs MACH_AT91SAM9263CS AT91SAM9263CS 2366 | |||
2355 | csb732 MACH_CSB732 CSB732 2367 | 2355 | csb732 MACH_CSB732 CSB732 2367 |
2356 | u8500 MACH_U8500 U8500 2368 | 2356 | u8500 MACH_U8500 U8500 2368 |
2357 | huqiu MACH_HUQIU HUQIU 2369 | 2357 | huqiu MACH_HUQIU HUQIU 2369 |
2358 | mx51_kunlun MACH_MX51_KUNLUN MX51_KUNLUN 2370 | 2358 | mx51_efikasb MACH_MX51_EFIKASB MX51_EFIKASB 2370 |
2359 | pmt1g MACH_PMT1G PMT1G 2371 | 2359 | pmt1g MACH_PMT1G PMT1G 2371 |
2360 | htcelf MACH_HTCELF HTCELF 2372 | 2360 | htcelf MACH_HTCELF HTCELF 2372 |
2361 | armadillo420 MACH_ARMADILLO420 ARMADILLO420 2373 | 2361 | armadillo420 MACH_ARMADILLO420 ARMADILLO420 2373 |
@@ -2971,7 +2971,7 @@ premierwave_en MACH_PREMIERWAVE_EN PREMIERWAVE_EN 2985 | |||
2971 | wasabi MACH_WASABI WASABI 2986 | 2971 | wasabi MACH_WASABI WASABI 2986 |
2972 | vivow MACH_VIVOW VIVOW 2987 | 2972 | vivow MACH_VIVOW VIVOW 2987 |
2973 | mx50_rdp MACH_MX50_RDP MX50_RDP 2988 | 2973 | mx50_rdp MACH_MX50_RDP MX50_RDP 2988 |
2974 | universal MACH_UNIVERSAL UNIVERSAL 2989 | 2974 | universal_c210 MACH_UNIVERSAL_C210 UNIVERSAL_C210 2989 |
2975 | real6410 MACH_REAL6410 REAL6410 2990 | 2975 | real6410 MACH_REAL6410 REAL6410 2990 |
2976 | spx_sakura MACH_SPX_SAKURA SPX_SAKURA 2991 | 2976 | spx_sakura MACH_SPX_SAKURA SPX_SAKURA 2991 |
2977 | ij3k_2440 MACH_IJ3K_2440 IJ3K_2440 2992 | 2977 | ij3k_2440 MACH_IJ3K_2440 IJ3K_2440 2992 |
@@ -3044,3 +3044,178 @@ harvest_desoto MACH_HARVEST_DESOTO HARVEST_DESOTO 3059 | |||
3044 | msm8x60_qrdc MACH_MSM8X60_QRDC MSM8X60_QRDC 3060 | 3044 | msm8x60_qrdc MACH_MSM8X60_QRDC MSM8X60_QRDC 3060 |
3045 | spear900 MACH_SPEAR900 SPEAR900 3061 | 3045 | spear900 MACH_SPEAR900 SPEAR900 3061 |
3046 | pcontrol_g20 MACH_PCONTROL_G20 PCONTROL_G20 3062 | 3046 | pcontrol_g20 MACH_PCONTROL_G20 PCONTROL_G20 3062 |
3047 | rdstor MACH_RDSTOR RDSTOR 3063 | ||
3048 | usdloader MACH_USDLOADER USDLOADER 3064 | ||
3049 | tsoploader MACH_TSOPLOADER TSOPLOADER 3065 | ||
3050 | kronos MACH_KRONOS KRONOS 3066 | ||
3051 | ffcore MACH_FFCORE FFCORE 3067 | ||
3052 | mone MACH_MONE MONE 3068 | ||
3053 | unit2s MACH_UNIT2S UNIT2S 3069 | ||
3054 | acer_a5 MACH_ACER_A5 ACER_A5 3070 | ||
3055 | etherpro_isp MACH_ETHERPRO_ISP ETHERPRO_ISP 3071 | ||
3056 | stretchs7000 MACH_STRETCHS7000 STRETCHS7000 3072 | ||
3057 | p87_smartsim MACH_P87_SMARTSIM P87_SMARTSIM 3073 | ||
3058 | tulip MACH_TULIP TULIP 3074 | ||
3059 | sunflower MACH_SUNFLOWER SUNFLOWER 3075 | ||
3060 | rib MACH_RIB RIB 3076 | ||
3061 | clod MACH_CLOD CLOD 3077 | ||
3062 | rump MACH_RUMP RUMP 3078 | ||
3063 | tenderloin MACH_TENDERLOIN TENDERLOIN 3079 | ||
3064 | shortloin MACH_SHORTLOIN SHORTLOIN 3080 | ||
3065 | crespo MACH_CRESPO CRESPO 3081 | ||
3066 | antares MACH_ANTARES ANTARES 3082 | ||
3067 | wb40n MACH_WB40N WB40N 3083 | ||
3068 | herring MACH_HERRING HERRING 3084 | ||
3069 | naxy400 MACH_NAXY400 NAXY400 3085 | ||
3070 | naxy1200 MACH_NAXY1200 NAXY1200 3086 | ||
3071 | vpr200 MACH_VPR200 VPR200 3087 | ||
3072 | bug20 MACH_BUG20 BUG20 3088 | ||
3073 | goflexnet MACH_GOFLEXNET GOFLEXNET 3089 | ||
3074 | torbreck MACH_TORBRECK TORBRECK 3090 | ||
3075 | saarb_mg1 MACH_SAARB_MG1 SAARB_MG1 3091 | ||
3076 | callisto MACH_CALLISTO CALLISTO 3092 | ||
3077 | multhsu MACH_MULTHSU MULTHSU 3093 | ||
3078 | saluda MACH_SALUDA SALUDA 3094 | ||
3079 | pemp_omap3_apollo MACH_PEMP_OMAP3_APOLLO PEMP_OMAP3_APOLLO 3095 | ||
3080 | vc0718 MACH_VC0718 VC0718 3096 | ||
3081 | mvblx MACH_MVBLX MVBLX 3097 | ||
3082 | inhand_apeiron MACH_INHAND_APEIRON INHAND_APEIRON 3098 | ||
3083 | inhand_fury MACH_INHAND_FURY INHAND_FURY 3099 | ||
3084 | inhand_siren MACH_INHAND_SIREN INHAND_SIREN 3100 | ||
3085 | hdnvp MACH_HDNVP HDNVP 3101 | ||
3086 | softwinner MACH_SOFTWINNER SOFTWINNER 3102 | ||
3087 | prima2_evb MACH_PRIMA2_EVB PRIMA2_EVB 3103 | ||
3088 | nas6210 MACH_NAS6210 NAS6210 3104 | ||
3089 | unisdev MACH_UNISDEV UNISDEV 3105 | ||
3090 | sbca11 MACH_SBCA11 SBCA11 3106 | ||
3091 | saga MACH_SAGA SAGA 3107 | ||
3092 | ns_k330 MACH_NS_K330 NS_K330 3108 | ||
3093 | tanna MACH_TANNA TANNA 3109 | ||
3094 | imate8502 MACH_IMATE8502 IMATE8502 3110 | ||
3095 | aspen MACH_ASPEN ASPEN 3111 | ||
3096 | daintree_cwac MACH_DAINTREE_CWAC DAINTREE_CWAC 3112 | ||
3097 | zmx25 MACH_ZMX25 ZMX25 3113 | ||
3098 | maple1 MACH_MAPLE1 MAPLE1 3114 | ||
3099 | qsd8x72_surf MACH_QSD8X72_SURF QSD8X72_SURF 3115 | ||
3100 | qsd8x72_ffa MACH_QSD8X72_FFA QSD8X72_FFA 3116 | ||
3101 | abilene MACH_ABILENE ABILENE 3117 | ||
3102 | eigen_ttr MACH_EIGEN_TTR EIGEN_TTR 3118 | ||
3103 | iomega_ix2_200 MACH_IOMEGA_IX2_200 IOMEGA_IX2_200 3119 | ||
3104 | coretec_vcx7400 MACH_CORETEC_VCX7400 CORETEC_VCX7400 3120 | ||
3105 | santiago MACH_SANTIAGO SANTIAGO 3121 | ||
3106 | mx257sol MACH_MX257SOL MX257SOL 3122 | ||
3107 | strasbourg MACH_STRASBOURG STRASBOURG 3123 | ||
3108 | msm8x60_fluid MACH_MSM8X60_FLUID MSM8X60_FLUID 3124 | ||
3109 | smartqv5 MACH_SMARTQV5 SMARTQV5 3125 | ||
3110 | smartqv3 MACH_SMARTQV3 SMARTQV3 3126 | ||
3111 | smartqv7 MACH_SMARTQV7 SMARTQV7 3127 | ||
3112 | paz00 MACH_PAZ00 PAZ00 3128 | ||
3113 | acmenetusfoxg20 MACH_ACMENETUSFOXG20 ACMENETUSFOXG20 3129 | ||
3114 | htcwillow MACH_HTCWILLOW HTCWILLOW 3130 | ||
3115 | fwbd_0404 MACH_FWBD_0404 FWBD_0404 3131 | ||
3116 | hdgu MACH_HDGU HDGU 3132 | ||
3117 | pyramid MACH_PYRAMID PYRAMID 3133 | ||
3118 | epiphan MACH_EPIPHAN EPIPHAN 3134 | ||
3119 | omap_bender MACH_OMAP_BENDER OMAP_BENDER 3135 | ||
3120 | gurnard MACH_GURNARD GURNARD 3136 | ||
3121 | gtl_it5100 MACH_GTL_IT5100 GTL_IT5100 3137 | ||
3122 | bcm2708 MACH_BCM2708 BCM2708 3138 | ||
3123 | mx51_ggc MACH_MX51_GGC MX51_GGC 3139 | ||
3124 | sharespace MACH_SHARESPACE SHARESPACE 3140 | ||
3125 | haba_knx_explorer MACH_HABA_KNX_EXPLORER HABA_KNX_EXPLORER 3141 | ||
3126 | simtec_kirkmod MACH_SIMTEC_KIRKMOD SIMTEC_KIRKMOD 3142 | ||
3127 | crux MACH_CRUX CRUX 3143 | ||
3128 | mx51_bravo MACH_MX51_BRAVO MX51_BRAVO 3144 | ||
3129 | charon MACH_CHARON CHARON 3145 | ||
3130 | picocom3 MACH_PICOCOM3 PICOCOM3 3146 | ||
3131 | picocom4 MACH_PICOCOM4 PICOCOM4 3147 | ||
3132 | serrano MACH_SERRANO SERRANO 3148 | ||
3133 | doubleshot MACH_DOUBLESHOT DOUBLESHOT 3149 | ||
3134 | evsy MACH_EVSY EVSY 3150 | ||
3135 | huashan MACH_HUASHAN HUASHAN 3151 | ||
3136 | lausanne MACH_LAUSANNE LAUSANNE 3152 | ||
3137 | emerald MACH_EMERALD EMERALD 3153 | ||
3138 | tqma35 MACH_TQMA35 TQMA35 3154 | ||
3139 | marvel MACH_MARVEL MARVEL 3155 | ||
3140 | manuae MACH_MANUAE MANUAE 3156 | ||
3141 | chacha MACH_CHACHA CHACHA 3157 | ||
3142 | lemon MACH_LEMON LEMON 3158 | ||
3143 | csc MACH_CSC CSC 3159 | ||
3144 | gira_knxip_router MACH_GIRA_KNXIP_ROUTER GIRA_KNXIP_ROUTER 3160 | ||
3145 | t20 MACH_T20 T20 3161 | ||
3146 | hdmini MACH_HDMINI HDMINI 3162 | ||
3147 | sciphone_g2 MACH_SCIPHONE_G2 SCIPHONE_G2 3163 | ||
3148 | express MACH_EXPRESS EXPRESS 3164 | ||
3149 | express_kt MACH_EXPRESS_KT EXPRESS_KT 3165 | ||
3150 | maximasp MACH_MAXIMASP MAXIMASP 3166 | ||
3151 | nitrogen_imx51 MACH_NITROGEN_IMX51 NITROGEN_IMX51 3167 | ||
3152 | nitrogen_imx53 MACH_NITROGEN_IMX53 NITROGEN_IMX53 3168 | ||
3153 | sunfire MACH_SUNFIRE SUNFIRE 3169 | ||
3154 | arowana MACH_AROWANA AROWANA 3170 | ||
3155 | tegra_daytona MACH_TEGRA_DAYTONA TEGRA_DAYTONA 3171 | ||
3156 | tegra_swordfish MACH_TEGRA_SWORDFISH TEGRA_SWORDFISH 3172 | ||
3157 | edison MACH_EDISON EDISON 3173 | ||
3158 | svp8500v1 MACH_SVP8500V1 SVP8500V1 3174 | ||
3159 | svp8500v2 MACH_SVP8500V2 SVP8500V2 3175 | ||
3160 | svp5500 MACH_SVP5500 SVP5500 3176 | ||
3161 | b5500 MACH_B5500 B5500 3177 | ||
3162 | s5500 MACH_S5500 S5500 3178 | ||
3163 | icon MACH_ICON ICON 3179 | ||
3164 | elephant MACH_ELEPHANT ELEPHANT 3180 | ||
3165 | msm8x60_fusion MACH_MSM8X60_FUSION MSM8X60_FUSION 3181 | ||
3166 | shooter MACH_SHOOTER SHOOTER 3182 | ||
3167 | spade_lte MACH_SPADE_LTE SPADE_LTE 3183 | ||
3168 | philhwani MACH_PHILHWANI PHILHWANI 3184 | ||
3169 | gsncomm MACH_GSNCOMM GSNCOMM 3185 | ||
3170 | strasbourg_a2 MACH_STRASBOURG_A2 STRASBOURG_A2 3186 | ||
3171 | mmm MACH_MMM MMM 3187 | ||
3172 | davinci_dm365_bv MACH_DAVINCI_DM365_BV DAVINCI_DM365_BV 3188 | ||
3173 | ag5evm MACH_AG5EVM AG5EVM 3189 | ||
3174 | sc575plc MACH_SC575PLC SC575PLC 3190 | ||
3175 | sc575hmi MACH_SC575IPC SC575IPC 3191 | ||
3176 | omap3_tdm3730 MACH_OMAP3_TDM3730 OMAP3_TDM3730 3192 | ||
3177 | g7 MACH_G7 G7 3193 | ||
3178 | top9000_eval MACH_TOP9000_EVAL TOP9000_EVAL 3194 | ||
3179 | top9000_su MACH_TOP9000_SU TOP9000_SU 3195 | ||
3180 | utm300 MACH_UTM300 UTM300 3196 | ||
3181 | tsunagi MACH_TSUNAGI TSUNAGI 3197 | ||
3182 | ts75xx MACH_TS75XX TS75XX 3198 | ||
3183 | msm8x60_fusn_ffa MACH_MSM8X60_FUSN_FFA MSM8X60_FUSN_FFA 3199 | ||
3184 | ts47xx MACH_TS47XX TS47XX 3200 | ||
3185 | da850_k5 MACH_DA850_K5 DA850_K5 3201 | ||
3186 | ax502 MACH_AX502 AX502 3202 | ||
3187 | igep0032 MACH_IGEP0032 IGEP0032 3203 | ||
3188 | antero MACH_ANTERO ANTERO 3204 | ||
3189 | synergy MACH_SYNERGY SYNERGY 3205 | ||
3190 | ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206 | ||
3191 | wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207 | ||
3192 | punica MACH_PUNICA PUNICA 3208 | ||
3193 | sbc_nt250 MACH_SBC_NT250 SBC_NT250 3209 | ||
3194 | mx27_wmultra MACH_MX27_WMULTRA MX27_WMULTRA 3210 | ||
3195 | mackerel MACH_MACKEREL MACKEREL 3211 | ||
3196 | fa9x27 MACH_FA9X27 FA9X27 3213 | ||
3197 | ns2816tb MACH_NS2816TB NS2816TB 3214 | ||
3198 | ns2816_ntpad MACH_NS2816_NTPAD NS2816_NTPAD 3215 | ||
3199 | ns2816_ntnb MACH_NS2816_NTNB NS2816_NTNB 3216 | ||
3200 | kaen MACH_KAEN KAEN 3217 | ||
3201 | nv1000 MACH_NV1000 NV1000 3218 | ||
3202 | nuc950ts MACH_NUC950TS NUC950TS 3219 | ||
3203 | nokia_rm680 MACH_NOKIA_RM680 NOKIA_RM680 3220 | ||
3204 | ast2200 MACH_AST2200 AST2200 3221 | ||
3205 | lead MACH_LEAD LEAD 3222 | ||
3206 | unino1 MACH_UNINO1 UNINO1 3223 | ||
3207 | greeco MACH_GREECO GREECO 3224 | ||
3208 | verdi MACH_VERDI VERDI 3225 | ||
3209 | dm6446_adbox MACH_DM6446_ADBOX DM6446_ADBOX 3226 | ||
3210 | quad_salsa MACH_QUAD_SALSA QUAD_SALSA 3227 | ||
3211 | abb_gma_1_1 MACH_ABB_GMA_1_1 ABB_GMA_1_1 3228 | ||
3212 | svcid MACH_SVCID SVCID 3229 | ||
3213 | msm8960_sim MACH_MSM8960_SIM MSM8960_SIM 3230 | ||
3214 | msm8960_rumi3 MACH_MSM8960_RUMI3 MSM8960_RUMI3 3231 | ||
3215 | icon_g MACH_ICON_G ICON_G 3232 | ||
3216 | mb3 MACH_MB3 MB3 3233 | ||
3217 | gsia18s MACH_GSIA18S GSIA18S 3234 | ||
3218 | pivicc MACH_PIVICC PIVICC 3235 | ||
3219 | pcm048 MACH_PCM048 PCM048 3236 | ||
3220 | dds MACH_DDS DDS 3237 | ||
3221 | chalten_xa1 MACH_CHALTEN_XA1 CHALTEN_XA1 3238 | ||
diff --git a/arch/ia64/include/asm/io.h b/arch/ia64/include/asm/io.h index cc8335eb3110..e5a6c3530c6c 100644 --- a/arch/ia64/include/asm/io.h +++ b/arch/ia64/include/asm/io.h | |||
@@ -426,6 +426,11 @@ extern void __iomem * ioremap_nocache (unsigned long offset, unsigned long size) | |||
426 | extern void iounmap (volatile void __iomem *addr); | 426 | extern void iounmap (volatile void __iomem *addr); |
427 | extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size); | 427 | extern void __iomem * early_ioremap (unsigned long phys_addr, unsigned long size); |
428 | extern void early_iounmap (volatile void __iomem *addr, unsigned long size); | 428 | extern void early_iounmap (volatile void __iomem *addr, unsigned long size); |
429 | static inline void __iomem * ioremap_cache (unsigned long phys_addr, unsigned long size) | ||
430 | { | ||
431 | return ioremap(phys_addr, size); | ||
432 | } | ||
433 | |||
429 | 434 | ||
430 | /* | 435 | /* |
431 | * String version of IO memory access ops: | 436 | * String version of IO memory access ops: |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 67a2fa2caa49..0a9b5b8b2a19 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -19,6 +19,8 @@ config MIPS | |||
19 | select GENERIC_ATOMIC64 if !64BIT | 19 | select GENERIC_ATOMIC64 if !64BIT |
20 | select HAVE_DMA_ATTRS | 20 | select HAVE_DMA_ATTRS |
21 | select HAVE_DMA_API_DEBUG | 21 | select HAVE_DMA_API_DEBUG |
22 | select HAVE_GENERIC_HARDIRQS | ||
23 | select GENERIC_IRQ_PROBE | ||
22 | 24 | ||
23 | menu "Machine selection" | 25 | menu "Machine selection" |
24 | 26 | ||
@@ -1664,6 +1666,28 @@ config PAGE_SIZE_64KB | |||
1664 | 1666 | ||
1665 | endchoice | 1667 | endchoice |
1666 | 1668 | ||
1669 | config FORCE_MAX_ZONEORDER | ||
1670 | int "Maximum zone order" | ||
1671 | range 13 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB | ||
1672 | default "13" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_32KB | ||
1673 | range 12 64 if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB | ||
1674 | default "12" if SYS_SUPPORTS_HUGETLBFS && PAGE_SIZE_16KB | ||
1675 | range 11 64 | ||
1676 | default "11" | ||
1677 | help | ||
1678 | The kernel memory allocator divides physically contiguous memory | ||
1679 | blocks into "zones", where each zone is a power of two number of | ||
1680 | pages. This option selects the largest power of two that the kernel | ||
1681 | keeps in the memory allocator. If you need to allocate very large | ||
1682 | blocks of physically contiguous memory, then you may need to | ||
1683 | increase this value. | ||
1684 | |||
1685 | This config option is actually maximum order plus one. For example, | ||
1686 | a value of 11 means that the largest free memory block is 2^10 pages. | ||
1687 | |||
1688 | The page size is not necessarily 4KB. Keep this in mind | ||
1689 | when choosing a value for this option. | ||
1690 | |||
1667 | config BOARD_SCACHE | 1691 | config BOARD_SCACHE |
1668 | bool | 1692 | bool |
1669 | 1693 | ||
@@ -1922,20 +1946,6 @@ config CPU_R4400_WORKAROUNDS | |||
1922 | bool | 1946 | bool |
1923 | 1947 | ||
1924 | # | 1948 | # |
1925 | # Use the generic interrupt handling code in kernel/irq/: | ||
1926 | # | ||
1927 | config GENERIC_HARDIRQS | ||
1928 | bool | ||
1929 | default y | ||
1930 | |||
1931 | config GENERIC_IRQ_PROBE | ||
1932 | bool | ||
1933 | default y | ||
1934 | |||
1935 | config IRQ_PER_CPU | ||
1936 | bool | ||
1937 | |||
1938 | # | ||
1939 | # - Highmem only makes sense for the 32-bit kernel. | 1949 | # - Highmem only makes sense for the 32-bit kernel. |
1940 | # - The current highmem code will only work properly on physically indexed | 1950 | # - The current highmem code will only work properly on physically indexed |
1941 | # caches such as R3000, SB1, R7000 or those that look like they're virtually | 1951 | # caches such as R3000, SB1, R7000 or those that look like they're virtually |
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c index 3691630931d6..9e7814db3d03 100644 --- a/arch/mips/alchemy/common/platform.c +++ b/arch/mips/alchemy/common/platform.c | |||
@@ -27,6 +27,7 @@ | |||
27 | static void alchemy_8250_pm(struct uart_port *port, unsigned int state, | 27 | static void alchemy_8250_pm(struct uart_port *port, unsigned int state, |
28 | unsigned int old_state) | 28 | unsigned int old_state) |
29 | { | 29 | { |
30 | #ifdef CONFIG_SERIAL_8250 | ||
30 | switch (state) { | 31 | switch (state) { |
31 | case 0: | 32 | case 0: |
32 | if ((__raw_readl(port->membase + UART_MOD_CNTRL) & 3) != 3) { | 33 | if ((__raw_readl(port->membase + UART_MOD_CNTRL) & 3) != 3) { |
@@ -49,6 +50,7 @@ static void alchemy_8250_pm(struct uart_port *port, unsigned int state, | |||
49 | serial8250_do_pm(port, state, old_state); | 50 | serial8250_do_pm(port, state, old_state); |
50 | break; | 51 | break; |
51 | } | 52 | } |
53 | #endif | ||
52 | } | 54 | } |
53 | 55 | ||
54 | #define PORT(_base, _irq) \ | 56 | #define PORT(_base, _irq) \ |
diff --git a/arch/mips/alchemy/devboards/prom.c b/arch/mips/alchemy/devboards/prom.c index b30df5c97ad3..baeb21385058 100644 --- a/arch/mips/alchemy/devboards/prom.c +++ b/arch/mips/alchemy/devboards/prom.c | |||
@@ -54,10 +54,9 @@ void __init prom_init(void) | |||
54 | 54 | ||
55 | prom_init_cmdline(); | 55 | prom_init_cmdline(); |
56 | memsize_str = prom_getenv("memsize"); | 56 | memsize_str = prom_getenv("memsize"); |
57 | if (!memsize_str) | 57 | if (!memsize_str || strict_strtoul(memsize_str, 0, &memsize)) |
58 | memsize = ALCHEMY_BOARD_DEFAULT_MEMSIZE; | 58 | memsize = ALCHEMY_BOARD_DEFAULT_MEMSIZE; |
59 | else | 59 | |
60 | strict_strtoul(memsize_str, 0, &memsize); | ||
61 | add_memory_region(0, memsize, BOOT_MEM_RAM); | 60 | add_memory_region(0, memsize, BOOT_MEM_RAM); |
62 | } | 61 | } |
63 | 62 | ||
diff --git a/arch/mips/ar7/clock.c b/arch/mips/ar7/clock.c index fc0e7154e8d6..2ca4ada1c291 100644 --- a/arch/mips/ar7/clock.c +++ b/arch/mips/ar7/clock.c | |||
@@ -239,12 +239,12 @@ static void tnetd7300_set_clock(u32 shift, struct tnetd7300_clock *clock, | |||
239 | calculate(base_clock, frequency, &prediv, &postdiv, &mul); | 239 | calculate(base_clock, frequency, &prediv, &postdiv, &mul); |
240 | 240 | ||
241 | writel(((prediv - 1) << PREDIV_SHIFT) | (postdiv - 1), &clock->ctrl); | 241 | writel(((prediv - 1) << PREDIV_SHIFT) | (postdiv - 1), &clock->ctrl); |
242 | msleep(1); | 242 | mdelay(1); |
243 | writel(4, &clock->pll); | 243 | writel(4, &clock->pll); |
244 | while (readl(&clock->pll) & PLL_STATUS) | 244 | while (readl(&clock->pll) & PLL_STATUS) |
245 | ; | 245 | ; |
246 | writel(((mul - 1) << MUL_SHIFT) | (0xff << 3) | 0x0e, &clock->pll); | 246 | writel(((mul - 1) << MUL_SHIFT) | (0xff << 3) | 0x0e, &clock->pll); |
247 | msleep(75); | 247 | mdelay(75); |
248 | } | 248 | } |
249 | 249 | ||
250 | static void __init tnetd7300_init_clocks(void) | 250 | static void __init tnetd7300_init_clocks(void) |
@@ -456,7 +456,7 @@ void clk_put(struct clk *clk) | |||
456 | } | 456 | } |
457 | EXPORT_SYMBOL(clk_put); | 457 | EXPORT_SYMBOL(clk_put); |
458 | 458 | ||
459 | int __init ar7_init_clocks(void) | 459 | void __init ar7_init_clocks(void) |
460 | { | 460 | { |
461 | switch (ar7_chip_id()) { | 461 | switch (ar7_chip_id()) { |
462 | case AR7_CHIP_7100: | 462 | case AR7_CHIP_7100: |
@@ -472,7 +472,4 @@ int __init ar7_init_clocks(void) | |||
472 | } | 472 | } |
473 | /* adjust vbus clock rate */ | 473 | /* adjust vbus clock rate */ |
474 | vbus_clk.rate = bus_clk.rate / 2; | 474 | vbus_clk.rate = bus_clk.rate / 2; |
475 | |||
476 | return 0; | ||
477 | } | 475 | } |
478 | arch_initcall(ar7_init_clocks); | ||
diff --git a/arch/mips/ar7/time.c b/arch/mips/ar7/time.c index 5fb8a0134085..22c93213b233 100644 --- a/arch/mips/ar7/time.c +++ b/arch/mips/ar7/time.c | |||
@@ -30,6 +30,9 @@ void __init plat_time_init(void) | |||
30 | { | 30 | { |
31 | struct clk *cpu_clk; | 31 | struct clk *cpu_clk; |
32 | 32 | ||
33 | /* Initialize ar7 clocks so the CPU clock frequency is correct */ | ||
34 | ar7_init_clocks(); | ||
35 | |||
33 | cpu_clk = clk_get(NULL, "cpu"); | 36 | cpu_clk = clk_get(NULL, "cpu"); |
34 | if (IS_ERR(cpu_clk)) { | 37 | if (IS_ERR(cpu_clk)) { |
35 | printk(KERN_ERR "unable to get cpu clock\n"); | 38 | printk(KERN_ERR "unable to get cpu clock\n"); |
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index b1aee33efd11..c95f90bf734c 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c | |||
@@ -32,7 +32,6 @@ | |||
32 | #include <asm/reboot.h> | 32 | #include <asm/reboot.h> |
33 | #include <asm/time.h> | 33 | #include <asm/time.h> |
34 | #include <bcm47xx.h> | 34 | #include <bcm47xx.h> |
35 | #include <asm/fw/cfe/cfe_api.h> | ||
36 | #include <asm/mach-bcm47xx/nvram.h> | 35 | #include <asm/mach-bcm47xx/nvram.h> |
37 | 36 | ||
38 | struct ssb_bus ssb_bcm47xx; | 37 | struct ssb_bus ssb_bcm47xx; |
@@ -57,68 +56,112 @@ static void bcm47xx_machine_halt(void) | |||
57 | cpu_relax(); | 56 | cpu_relax(); |
58 | } | 57 | } |
59 | 58 | ||
60 | static void str2eaddr(char *str, char *dest) | 59 | #define READ_FROM_NVRAM(_outvar, name, buf) \ |
61 | { | 60 | if (nvram_getenv(name, buf, sizeof(buf)) >= 0)\ |
62 | int i = 0; | 61 | sprom->_outvar = simple_strtoul(buf, NULL, 0); |
63 | 62 | ||
64 | if (str == NULL) { | 63 | static void bcm47xx_fill_sprom(struct ssb_sprom *sprom) |
65 | memset(dest, 0, 6); | 64 | { |
66 | return; | 65 | char buf[100]; |
66 | u32 boardflags; | ||
67 | |||
68 | memset(sprom, 0, sizeof(struct ssb_sprom)); | ||
69 | |||
70 | sprom->revision = 1; /* Fallback: Old hardware does not define this. */ | ||
71 | READ_FROM_NVRAM(revision, "sromrev", buf); | ||
72 | if (nvram_getenv("il0macaddr", buf, sizeof(buf)) >= 0) | ||
73 | nvram_parse_macaddr(buf, sprom->il0mac); | ||
74 | if (nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0) | ||
75 | nvram_parse_macaddr(buf, sprom->et0mac); | ||
76 | if (nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0) | ||
77 | nvram_parse_macaddr(buf, sprom->et1mac); | ||
78 | READ_FROM_NVRAM(et0phyaddr, "et0phyaddr", buf); | ||
79 | READ_FROM_NVRAM(et1phyaddr, "et1phyaddr", buf); | ||
80 | READ_FROM_NVRAM(et0mdcport, "et0mdcport", buf); | ||
81 | READ_FROM_NVRAM(et1mdcport, "et1mdcport", buf); | ||
82 | READ_FROM_NVRAM(board_rev, "boardrev", buf); | ||
83 | READ_FROM_NVRAM(country_code, "ccode", buf); | ||
84 | READ_FROM_NVRAM(ant_available_a, "aa5g", buf); | ||
85 | READ_FROM_NVRAM(ant_available_bg, "aa2g", buf); | ||
86 | READ_FROM_NVRAM(pa0b0, "pa0b0", buf); | ||
87 | READ_FROM_NVRAM(pa0b1, "pa0b1", buf); | ||
88 | READ_FROM_NVRAM(pa0b2, "pa0b2", buf); | ||
89 | READ_FROM_NVRAM(pa1b0, "pa1b0", buf); | ||
90 | READ_FROM_NVRAM(pa1b1, "pa1b1", buf); | ||
91 | READ_FROM_NVRAM(pa1b2, "pa1b2", buf); | ||
92 | READ_FROM_NVRAM(pa1lob0, "pa1lob0", buf); | ||
93 | READ_FROM_NVRAM(pa1lob2, "pa1lob1", buf); | ||
94 | READ_FROM_NVRAM(pa1lob1, "pa1lob2", buf); | ||
95 | READ_FROM_NVRAM(pa1hib0, "pa1hib0", buf); | ||
96 | READ_FROM_NVRAM(pa1hib2, "pa1hib1", buf); | ||
97 | READ_FROM_NVRAM(pa1hib1, "pa1hib2", buf); | ||
98 | READ_FROM_NVRAM(gpio0, "wl0gpio0", buf); | ||
99 | READ_FROM_NVRAM(gpio1, "wl0gpio1", buf); | ||
100 | READ_FROM_NVRAM(gpio2, "wl0gpio2", buf); | ||
101 | READ_FROM_NVRAM(gpio3, "wl0gpio3", buf); | ||
102 | READ_FROM_NVRAM(maxpwr_bg, "pa0maxpwr", buf); | ||
103 | READ_FROM_NVRAM(maxpwr_al, "pa1lomaxpwr", buf); | ||
104 | READ_FROM_NVRAM(maxpwr_a, "pa1maxpwr", buf); | ||
105 | READ_FROM_NVRAM(maxpwr_ah, "pa1himaxpwr", buf); | ||
106 | READ_FROM_NVRAM(itssi_a, "pa1itssit", buf); | ||
107 | READ_FROM_NVRAM(itssi_bg, "pa0itssit", buf); | ||
108 | READ_FROM_NVRAM(tri2g, "tri2g", buf); | ||
109 | READ_FROM_NVRAM(tri5gl, "tri5gl", buf); | ||
110 | READ_FROM_NVRAM(tri5g, "tri5g", buf); | ||
111 | READ_FROM_NVRAM(tri5gh, "tri5gh", buf); | ||
112 | READ_FROM_NVRAM(rxpo2g, "rxpo2g", buf); | ||
113 | READ_FROM_NVRAM(rxpo5g, "rxpo5g", buf); | ||
114 | READ_FROM_NVRAM(rssisav2g, "rssisav2g", buf); | ||
115 | READ_FROM_NVRAM(rssismc2g, "rssismc2g", buf); | ||
116 | READ_FROM_NVRAM(rssismf2g, "rssismf2g", buf); | ||
117 | READ_FROM_NVRAM(bxa2g, "bxa2g", buf); | ||
118 | READ_FROM_NVRAM(rssisav5g, "rssisav5g", buf); | ||
119 | READ_FROM_NVRAM(rssismc5g, "rssismc5g", buf); | ||
120 | READ_FROM_NVRAM(rssismf5g, "rssismf5g", buf); | ||
121 | READ_FROM_NVRAM(bxa5g, "bxa5g", buf); | ||
122 | READ_FROM_NVRAM(cck2gpo, "cck2gpo", buf); | ||
123 | READ_FROM_NVRAM(ofdm2gpo, "ofdm2gpo", buf); | ||
124 | READ_FROM_NVRAM(ofdm5glpo, "ofdm5glpo", buf); | ||
125 | READ_FROM_NVRAM(ofdm5gpo, "ofdm5gpo", buf); | ||
126 | READ_FROM_NVRAM(ofdm5ghpo, "ofdm5ghpo", buf); | ||
127 | |||
128 | if (nvram_getenv("boardflags", buf, sizeof(buf)) >= 0) { | ||
129 | boardflags = simple_strtoul(buf, NULL, 0); | ||
130 | if (boardflags) { | ||
131 | sprom->boardflags_lo = (boardflags & 0x0000FFFFU); | ||
132 | sprom->boardflags_hi = (boardflags & 0xFFFF0000U) >> 16; | ||
133 | } | ||
67 | } | 134 | } |
68 | 135 | if (nvram_getenv("boardflags2", buf, sizeof(buf)) >= 0) { | |
69 | for (;;) { | 136 | boardflags = simple_strtoul(buf, NULL, 0); |
70 | dest[i++] = (char) simple_strtoul(str, NULL, 16); | 137 | if (boardflags) { |
71 | str += 2; | 138 | sprom->boardflags2_lo = (boardflags & 0x0000FFFFU); |
72 | if (!*str++ || i == 6) | 139 | sprom->boardflags2_hi = (boardflags & 0xFFFF0000U) >> 16; |
73 | break; | 140 | } |
74 | } | 141 | } |
75 | } | 142 | } |
76 | 143 | ||
77 | static int bcm47xx_get_invariants(struct ssb_bus *bus, | 144 | static int bcm47xx_get_invariants(struct ssb_bus *bus, |
78 | struct ssb_init_invariants *iv) | 145 | struct ssb_init_invariants *iv) |
79 | { | 146 | { |
80 | char buf[100]; | 147 | char buf[20]; |
81 | 148 | ||
82 | /* Fill boardinfo structure */ | 149 | /* Fill boardinfo structure */ |
83 | memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo)); | 150 | memset(&(iv->boardinfo), 0 , sizeof(struct ssb_boardinfo)); |
84 | 151 | ||
85 | if (cfe_getenv("boardvendor", buf, sizeof(buf)) >= 0 || | 152 | if (nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0) |
86 | nvram_getenv("boardvendor", buf, sizeof(buf)) >= 0) | 153 | iv->boardinfo.vendor = (u16)simple_strtoul(buf, NULL, 0); |
87 | iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0); | 154 | else |
88 | if (cfe_getenv("boardtype", buf, sizeof(buf)) >= 0 || | 155 | iv->boardinfo.vendor = SSB_BOARDVENDOR_BCM; |
89 | nvram_getenv("boardtype", buf, sizeof(buf)) >= 0) | 156 | if (nvram_getenv("boardtype", buf, sizeof(buf)) >= 0) |
90 | iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0); | 157 | iv->boardinfo.type = (u16)simple_strtoul(buf, NULL, 0); |
91 | if (cfe_getenv("boardrev", buf, sizeof(buf)) >= 0 || | 158 | if (nvram_getenv("boardrev", buf, sizeof(buf)) >= 0) |
92 | nvram_getenv("boardrev", buf, sizeof(buf)) >= 0) | ||
93 | iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0); | 159 | iv->boardinfo.rev = (u16)simple_strtoul(buf, NULL, 0); |
94 | 160 | ||
95 | /* Fill sprom structure */ | 161 | bcm47xx_fill_sprom(&iv->sprom); |
96 | memset(&(iv->sprom), 0, sizeof(struct ssb_sprom)); | ||
97 | iv->sprom.revision = 3; | ||
98 | |||
99 | if (cfe_getenv("et0macaddr", buf, sizeof(buf)) >= 0 || | ||
100 | nvram_getenv("et0macaddr", buf, sizeof(buf)) >= 0) | ||
101 | str2eaddr(buf, iv->sprom.et0mac); | ||
102 | 162 | ||
103 | if (cfe_getenv("et1macaddr", buf, sizeof(buf)) >= 0 || | 163 | if (nvram_getenv("cardbus", buf, sizeof(buf)) >= 0) |
104 | nvram_getenv("et1macaddr", buf, sizeof(buf)) >= 0) | 164 | iv->has_cardbus_slot = !!simple_strtoul(buf, NULL, 10); |
105 | str2eaddr(buf, iv->sprom.et1mac); | ||
106 | |||
107 | if (cfe_getenv("et0phyaddr", buf, sizeof(buf)) >= 0 || | ||
108 | nvram_getenv("et0phyaddr", buf, sizeof(buf)) >= 0) | ||
109 | iv->sprom.et0phyaddr = simple_strtoul(buf, NULL, 0); | ||
110 | |||
111 | if (cfe_getenv("et1phyaddr", buf, sizeof(buf)) >= 0 || | ||
112 | nvram_getenv("et1phyaddr", buf, sizeof(buf)) >= 0) | ||
113 | iv->sprom.et1phyaddr = simple_strtoul(buf, NULL, 0); | ||
114 | |||
115 | if (cfe_getenv("et0mdcport", buf, sizeof(buf)) >= 0 || | ||
116 | nvram_getenv("et0mdcport", buf, sizeof(buf)) >= 0) | ||
117 | iv->sprom.et0mdcport = simple_strtoul(buf, NULL, 10); | ||
118 | |||
119 | if (cfe_getenv("et1mdcport", buf, sizeof(buf)) >= 0 || | ||
120 | nvram_getenv("et1mdcport", buf, sizeof(buf)) >= 0) | ||
121 | iv->sprom.et1mdcport = simple_strtoul(buf, NULL, 10); | ||
122 | 165 | ||
123 | return 0; | 166 | return 0; |
124 | } | 167 | } |
@@ -126,12 +169,28 @@ static int bcm47xx_get_invariants(struct ssb_bus *bus, | |||
126 | void __init plat_mem_setup(void) | 169 | void __init plat_mem_setup(void) |
127 | { | 170 | { |
128 | int err; | 171 | int err; |
172 | char buf[100]; | ||
173 | struct ssb_mipscore *mcore; | ||
129 | 174 | ||
130 | err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE, | 175 | err = ssb_bus_ssbbus_register(&ssb_bcm47xx, SSB_ENUM_BASE, |
131 | bcm47xx_get_invariants); | 176 | bcm47xx_get_invariants); |
132 | if (err) | 177 | if (err) |
133 | panic("Failed to initialize SSB bus (err %d)\n", err); | 178 | panic("Failed to initialize SSB bus (err %d)\n", err); |
134 | 179 | ||
180 | mcore = &ssb_bcm47xx.mipscore; | ||
181 | if (nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) { | ||
182 | if (strstr(buf, "console=ttyS1")) { | ||
183 | struct ssb_serial_port port; | ||
184 | |||
185 | printk(KERN_DEBUG "Swapping serial ports!\n"); | ||
186 | /* swap serial ports */ | ||
187 | memcpy(&port, &mcore->serial_ports[0], sizeof(port)); | ||
188 | memcpy(&mcore->serial_ports[0], &mcore->serial_ports[1], | ||
189 | sizeof(port)); | ||
190 | memcpy(&mcore->serial_ports[1], &port, sizeof(port)); | ||
191 | } | ||
192 | } | ||
193 | |||
135 | _machine_restart = bcm47xx_machine_restart; | 194 | _machine_restart = bcm47xx_machine_restart; |
136 | _machine_halt = bcm47xx_machine_halt; | 195 | _machine_halt = bcm47xx_machine_halt; |
137 | pm_power_off = bcm47xx_machine_halt; | 196 | pm_power_off = bcm47xx_machine_halt; |
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index 06d59dcbe243..86877539c6e8 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h | |||
@@ -111,8 +111,8 @@ | |||
111 | * These are the PRID's for when 23:16 == PRID_COMP_BROADCOM | 111 | * These are the PRID's for when 23:16 == PRID_COMP_BROADCOM |
112 | */ | 112 | */ |
113 | 113 | ||
114 | #define PRID_IMP_BMIPS4KC 0x4000 | 114 | #define PRID_IMP_BMIPS32_REV4 0x4000 |
115 | #define PRID_IMP_BMIPS32 0x8000 | 115 | #define PRID_IMP_BMIPS32_REV8 0x8000 |
116 | #define PRID_IMP_BMIPS3300 0x9000 | 116 | #define PRID_IMP_BMIPS3300 0x9000 |
117 | #define PRID_IMP_BMIPS3300_ALT 0x9100 | 117 | #define PRID_IMP_BMIPS3300_ALT 0x9100 |
118 | #define PRID_IMP_BMIPS3300_BUG 0x0000 | 118 | #define PRID_IMP_BMIPS3300_BUG 0x0000 |
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index fd1d39eb7431..455c0ac7d4ea 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h | |||
@@ -249,7 +249,8 @@ extern struct mips_abi mips_abi_n32; | |||
249 | 249 | ||
250 | #define SET_PERSONALITY(ex) \ | 250 | #define SET_PERSONALITY(ex) \ |
251 | do { \ | 251 | do { \ |
252 | set_personality(PER_LINUX); \ | 252 | if (personality(current->personality) != PER_LINUX) \ |
253 | set_personality(PER_LINUX); \ | ||
253 | \ | 254 | \ |
254 | current->thread.abi = &mips_abi; \ | 255 | current->thread.abi = &mips_abi; \ |
255 | } while (0) | 256 | } while (0) |
@@ -296,6 +297,8 @@ do { \ | |||
296 | 297 | ||
297 | #define SET_PERSONALITY(ex) \ | 298 | #define SET_PERSONALITY(ex) \ |
298 | do { \ | 299 | do { \ |
300 | unsigned int p; \ | ||
301 | \ | ||
299 | clear_thread_flag(TIF_32BIT_REGS); \ | 302 | clear_thread_flag(TIF_32BIT_REGS); \ |
300 | clear_thread_flag(TIF_32BIT_ADDR); \ | 303 | clear_thread_flag(TIF_32BIT_ADDR); \ |
301 | \ | 304 | \ |
@@ -304,7 +307,8 @@ do { \ | |||
304 | else \ | 307 | else \ |
305 | current->thread.abi = &mips_abi; \ | 308 | current->thread.abi = &mips_abi; \ |
306 | \ | 309 | \ |
307 | if (current->personality != PER_LINUX32) \ | 310 | p = personality(current->personality); \ |
311 | if (p != PER_LINUX32 && p != PER_LINUX) \ | ||
308 | set_personality(PER_LINUX); \ | 312 | set_personality(PER_LINUX); \ |
309 | } while (0) | 313 | } while (0) |
310 | 314 | ||
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h index c98bf514ec7d..5b017f23e243 100644 --- a/arch/mips/include/asm/io.h +++ b/arch/mips/include/asm/io.h | |||
@@ -329,10 +329,14 @@ static inline void pfx##write##bwlq(type val, \ | |||
329 | "dsrl32 %L0, %L0, 0" "\n\t" \ | 329 | "dsrl32 %L0, %L0, 0" "\n\t" \ |
330 | "dsll32 %M0, %M0, 0" "\n\t" \ | 330 | "dsll32 %M0, %M0, 0" "\n\t" \ |
331 | "or %L0, %L0, %M0" "\n\t" \ | 331 | "or %L0, %L0, %M0" "\n\t" \ |
332 | ".set push" "\n\t" \ | ||
333 | ".set noreorder" "\n\t" \ | ||
334 | ".set nomacro" "\n\t" \ | ||
332 | "sd %L0, %2" "\n\t" \ | 335 | "sd %L0, %2" "\n\t" \ |
336 | ".set pop" "\n\t" \ | ||
333 | ".set mips0" "\n" \ | 337 | ".set mips0" "\n" \ |
334 | : "=r" (__tmp) \ | 338 | : "=r" (__tmp) \ |
335 | : "0" (__val), "m" (*__mem)); \ | 339 | : "0" (__val), "R" (*__mem)); \ |
336 | if (irq) \ | 340 | if (irq) \ |
337 | local_irq_restore(__flags); \ | 341 | local_irq_restore(__flags); \ |
338 | } else \ | 342 | } else \ |
@@ -355,12 +359,16 @@ static inline type pfx##read##bwlq(const volatile void __iomem *mem) \ | |||
355 | local_irq_save(__flags); \ | 359 | local_irq_save(__flags); \ |
356 | __asm__ __volatile__( \ | 360 | __asm__ __volatile__( \ |
357 | ".set mips3" "\t\t# __readq" "\n\t" \ | 361 | ".set mips3" "\t\t# __readq" "\n\t" \ |
362 | ".set push" "\n\t" \ | ||
363 | ".set noreorder" "\n\t" \ | ||
364 | ".set nomacro" "\n\t" \ | ||
358 | "ld %L0, %1" "\n\t" \ | 365 | "ld %L0, %1" "\n\t" \ |
366 | ".set pop" "\n\t" \ | ||
359 | "dsra32 %M0, %L0, 0" "\n\t" \ | 367 | "dsra32 %M0, %L0, 0" "\n\t" \ |
360 | "sll %L0, %L0, 0" "\n\t" \ | 368 | "sll %L0, %L0, 0" "\n\t" \ |
361 | ".set mips0" "\n" \ | 369 | ".set mips0" "\n" \ |
362 | : "=r" (__val) \ | 370 | : "=r" (__val) \ |
363 | : "m" (*__mem)); \ | 371 | : "R" (*__mem)); \ |
364 | if (irq) \ | 372 | if (irq) \ |
365 | local_irq_restore(__flags); \ | 373 | local_irq_restore(__flags); \ |
366 | } else { \ | 374 | } else { \ |
diff --git a/arch/mips/include/asm/mach-ar7/ar7.h b/arch/mips/include/asm/mach-ar7/ar7.h index 7919d76186bf..07d3fadb2443 100644 --- a/arch/mips/include/asm/mach-ar7/ar7.h +++ b/arch/mips/include/asm/mach-ar7/ar7.h | |||
@@ -201,7 +201,6 @@ static inline void ar7_device_off(u32 bit) | |||
201 | } | 201 | } |
202 | 202 | ||
203 | int __init ar7_gpio_init(void); | 203 | int __init ar7_gpio_init(void); |
204 | 204 | void __init ar7_init_clocks(void); | |
205 | int __init ar7_gpio_init(void); | ||
206 | 205 | ||
207 | #endif /* __AR7_H__ */ | 206 | #endif /* __AR7_H__ */ |
diff --git a/arch/mips/include/asm/mach-bcm47xx/nvram.h b/arch/mips/include/asm/mach-bcm47xx/nvram.h index c58ebd8bc155..9759588ba3cf 100644 --- a/arch/mips/include/asm/mach-bcm47xx/nvram.h +++ b/arch/mips/include/asm/mach-bcm47xx/nvram.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #define __NVRAM_H | 12 | #define __NVRAM_H |
13 | 13 | ||
14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
15 | #include <linux/kernel.h> | ||
15 | 16 | ||
16 | struct nvram_header { | 17 | struct nvram_header { |
17 | u32 magic; | 18 | u32 magic; |
@@ -36,4 +37,10 @@ struct nvram_header { | |||
36 | 37 | ||
37 | extern int nvram_getenv(char *name, char *val, size_t val_len); | 38 | extern int nvram_getenv(char *name, char *val, size_t val_len); |
38 | 39 | ||
40 | static inline void nvram_parse_macaddr(char *buf, u8 *macaddr) | ||
41 | { | ||
42 | sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &macaddr[0], &macaddr[1], | ||
43 | &macaddr[2], &macaddr[3], &macaddr[4], &macaddr[5]); | ||
44 | } | ||
45 | |||
39 | #endif | 46 | #endif |
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c index 5742bb4d78f4..5c0a3575877c 100644 --- a/arch/mips/jz4740/board-qi_lb60.c +++ b/arch/mips/jz4740/board-qi_lb60.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * Copyright (c) 2009 Qi Hardware inc., | 6 | * Copyright (c) 2009 Qi Hardware inc., |
7 | * Author: Xiangfu Liu <xiangfu@qi-hardware.com> | 7 | * Author: Xiangfu Liu <xiangfu@qi-hardware.com> |
8 | * Copyright 2010, Lars-Petrer Clausen <lars@metafoo.de> | 8 | * Copyright 2010, Lars-Peter Clausen <lars@metafoo.de> |
9 | * | 9 | * |
10 | * This program is free software; you can redistribute it and/or modify | 10 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License version 2 or later | 11 | * it under the terms of the GNU General Public License version 2 or later |
@@ -235,7 +235,7 @@ static const unsigned int qi_lb60_keypad_rows[] = { | |||
235 | QI_LB60_GPIO_KEYIN(3), | 235 | QI_LB60_GPIO_KEYIN(3), |
236 | QI_LB60_GPIO_KEYIN(4), | 236 | QI_LB60_GPIO_KEYIN(4), |
237 | QI_LB60_GPIO_KEYIN(5), | 237 | QI_LB60_GPIO_KEYIN(5), |
238 | QI_LB60_GPIO_KEYIN(7), | 238 | QI_LB60_GPIO_KEYIN(6), |
239 | QI_LB60_GPIO_KEYIN8, | 239 | QI_LB60_GPIO_KEYIN8, |
240 | }; | 240 | }; |
241 | 241 | ||
diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c index 95bc2b5b14f1..1cc9e544d16b 100644 --- a/arch/mips/jz4740/platform.c +++ b/arch/mips/jz4740/platform.c | |||
@@ -208,7 +208,7 @@ struct platform_device jz4740_i2s_device = { | |||
208 | 208 | ||
209 | /* PCM */ | 209 | /* PCM */ |
210 | struct platform_device jz4740_pcm_device = { | 210 | struct platform_device jz4740_pcm_device = { |
211 | .name = "jz4740-pcm", | 211 | .name = "jz4740-pcm-audio", |
212 | .id = -1, | 212 | .id = -1, |
213 | }; | 213 | }; |
214 | 214 | ||
diff --git a/arch/mips/jz4740/prom.c b/arch/mips/jz4740/prom.c index cfeac15eb2e4..4a70407f55bb 100644 --- a/arch/mips/jz4740/prom.c +++ b/arch/mips/jz4740/prom.c | |||
@@ -23,7 +23,7 @@ | |||
23 | #include <asm/bootinfo.h> | 23 | #include <asm/bootinfo.h> |
24 | #include <asm/mach-jz4740/base.h> | 24 | #include <asm/mach-jz4740/base.h> |
25 | 25 | ||
26 | void jz4740_init_cmdline(int argc, char *argv[]) | 26 | static __init void jz4740_init_cmdline(int argc, char *argv[]) |
27 | { | 27 | { |
28 | unsigned int count = COMMAND_LINE_SIZE - 1; | 28 | unsigned int count = COMMAND_LINE_SIZE - 1; |
29 | int i; | 29 | int i; |
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c index 2f4d7a99bcc2..98c5a9737c14 100644 --- a/arch/mips/kernel/cevt-r4k.c +++ b/arch/mips/kernel/cevt-r4k.c | |||
@@ -32,7 +32,7 @@ static int mips_next_event(unsigned long delta, | |||
32 | cnt = read_c0_count(); | 32 | cnt = read_c0_count(); |
33 | cnt += delta; | 33 | cnt += delta; |
34 | write_c0_compare(cnt); | 34 | write_c0_compare(cnt); |
35 | res = ((int)(read_c0_count() - cnt) > 0) ? -ETIME : 0; | 35 | res = ((int)(read_c0_count() - cnt) >= 0) ? -ETIME : 0; |
36 | return res; | 36 | return res; |
37 | } | 37 | } |
38 | 38 | ||
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 71620e19827a..68dae7b6b5db 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -905,7 +905,8 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu) | |||
905 | { | 905 | { |
906 | decode_configs(c); | 906 | decode_configs(c); |
907 | switch (c->processor_id & 0xff00) { | 907 | switch (c->processor_id & 0xff00) { |
908 | case PRID_IMP_BMIPS32: | 908 | case PRID_IMP_BMIPS32_REV4: |
909 | case PRID_IMP_BMIPS32_REV8: | ||
909 | c->cputype = CPU_BMIPS32; | 910 | c->cputype = CPU_BMIPS32; |
910 | __cpu_name[cpu] = "Broadcom BMIPS32"; | 911 | __cpu_name[cpu] = "Broadcom BMIPS32"; |
911 | break; | 912 | break; |
@@ -933,10 +934,6 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu) | |||
933 | __cpu_name[cpu] = "Broadcom BMIPS5000"; | 934 | __cpu_name[cpu] = "Broadcom BMIPS5000"; |
934 | c->options |= MIPS_CPU_ULRI; | 935 | c->options |= MIPS_CPU_ULRI; |
935 | break; | 936 | break; |
936 | case PRID_IMP_BMIPS4KC: | ||
937 | c->cputype = CPU_4KC; | ||
938 | __cpu_name[cpu] = "MIPS 4Kc"; | ||
939 | break; | ||
940 | } | 937 | } |
941 | } | 938 | } |
942 | 939 | ||
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 6343b4a5b835..876a75cc376f 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c | |||
@@ -251,14 +251,15 @@ SYSCALL_DEFINE5(n32_msgrcv, int, msqid, u32, msgp, size_t, msgsz, | |||
251 | 251 | ||
252 | SYSCALL_DEFINE1(32_personality, unsigned long, personality) | 252 | SYSCALL_DEFINE1(32_personality, unsigned long, personality) |
253 | { | 253 | { |
254 | unsigned int p = personality & 0xffffffff; | ||
254 | int ret; | 255 | int ret; |
255 | personality &= 0xffffffff; | 256 | |
256 | if (personality(current->personality) == PER_LINUX32 && | 257 | if (personality(current->personality) == PER_LINUX32 && |
257 | personality == PER_LINUX) | 258 | personality(p) == PER_LINUX) |
258 | personality = PER_LINUX32; | 259 | p = (p & ~PER_MASK) | PER_LINUX32; |
259 | ret = sys_personality(personality); | 260 | ret = sys_personality(p); |
260 | if (ret == PER_LINUX32) | 261 | if (ret != -1 && personality(ret) == PER_LINUX32) |
261 | ret = PER_LINUX; | 262 | ret = (ret & ~PER_MASK) | PER_LINUX; |
262 | return ret; | 263 | return ret; |
263 | } | 264 | } |
264 | 265 | ||
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 99960940d4a4..ae167df73ddd 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
@@ -142,7 +142,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
142 | childregs->regs[7] = 0; /* Clear error flag */ | 142 | childregs->regs[7] = 0; /* Clear error flag */ |
143 | 143 | ||
144 | childregs->regs[2] = 0; /* Child gets zero as return value */ | 144 | childregs->regs[2] = 0; /* Child gets zero as return value */ |
145 | regs->regs[2] = p->pid; | ||
146 | 145 | ||
147 | if (childregs->cp0_status & ST0_CU0) { | 146 | if (childregs->cp0_status & ST0_CU0) { |
148 | childregs->regs[28] = (unsigned long) ti; | 147 | childregs->regs[28] = (unsigned long) ti; |
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c index e000b278f024..9dbe58368953 100644 --- a/arch/mips/kernel/prom.c +++ b/arch/mips/kernel/prom.c | |||
@@ -100,7 +100,7 @@ void __init device_tree_init(void) | |||
100 | return; | 100 | return; |
101 | 101 | ||
102 | base = virt_to_phys((void *)initial_boot_params); | 102 | base = virt_to_phys((void *)initial_boot_params); |
103 | size = initial_boot_params->totalsize; | 103 | size = be32_to_cpu(initial_boot_params->totalsize); |
104 | 104 | ||
105 | /* Before we do anything, lets reserve the dt blob */ | 105 | /* Before we do anything, lets reserve the dt blob */ |
106 | reserve_mem_mach(base, size); | 106 | reserve_mem_mach(base, size); |
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 43e7cdc5ded2..c0e81418ba21 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c | |||
@@ -153,7 +153,7 @@ static void __cpuinit vsmp_init_secondary(void) | |||
153 | { | 153 | { |
154 | extern int gic_present; | 154 | extern int gic_present; |
155 | 155 | ||
156 | /* This is Malta specific: IPI,performance and timer inetrrupts */ | 156 | /* This is Malta specific: IPI,performance and timer interrupts */ |
157 | if (gic_present) | 157 | if (gic_present) |
158 | change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | | 158 | change_c0_status(ST0_IM, STATUSF_IP3 | STATUSF_IP4 | |
159 | STATUSF_IP6 | STATUSF_IP7); | 159 | STATUSF_IP6 | STATUSF_IP7); |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 8e9fbe75894e..e97104302541 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -83,7 +83,8 @@ extern asmlinkage void handle_mcheck(void); | |||
83 | extern asmlinkage void handle_reserved(void); | 83 | extern asmlinkage void handle_reserved(void); |
84 | 84 | ||
85 | extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, | 85 | extern int fpu_emulator_cop1Handler(struct pt_regs *xcp, |
86 | struct mips_fpu_struct *ctx, int has_fpu); | 86 | struct mips_fpu_struct *ctx, int has_fpu, |
87 | void *__user *fault_addr); | ||
87 | 88 | ||
88 | void (*board_be_init)(void); | 89 | void (*board_be_init)(void); |
89 | int (*board_be_handler)(struct pt_regs *regs, int is_fixup); | 90 | int (*board_be_handler)(struct pt_regs *regs, int is_fixup); |
@@ -661,12 +662,36 @@ asmlinkage void do_ov(struct pt_regs *regs) | |||
661 | force_sig_info(SIGFPE, &info, current); | 662 | force_sig_info(SIGFPE, &info, current); |
662 | } | 663 | } |
663 | 664 | ||
665 | static int process_fpemu_return(int sig, void __user *fault_addr) | ||
666 | { | ||
667 | if (sig == SIGSEGV || sig == SIGBUS) { | ||
668 | struct siginfo si = {0}; | ||
669 | si.si_addr = fault_addr; | ||
670 | si.si_signo = sig; | ||
671 | if (sig == SIGSEGV) { | ||
672 | if (find_vma(current->mm, (unsigned long)fault_addr)) | ||
673 | si.si_code = SEGV_ACCERR; | ||
674 | else | ||
675 | si.si_code = SEGV_MAPERR; | ||
676 | } else { | ||
677 | si.si_code = BUS_ADRERR; | ||
678 | } | ||
679 | force_sig_info(sig, &si, current); | ||
680 | return 1; | ||
681 | } else if (sig) { | ||
682 | force_sig(sig, current); | ||
683 | return 1; | ||
684 | } else { | ||
685 | return 0; | ||
686 | } | ||
687 | } | ||
688 | |||
664 | /* | 689 | /* |
665 | * XXX Delayed fp exceptions when doing a lazy ctx switch XXX | 690 | * XXX Delayed fp exceptions when doing a lazy ctx switch XXX |
666 | */ | 691 | */ |
667 | asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) | 692 | asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) |
668 | { | 693 | { |
669 | siginfo_t info; | 694 | siginfo_t info = {0}; |
670 | 695 | ||
671 | if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE) | 696 | if (notify_die(DIE_FP, "FP exception", regs, 0, regs_to_trapnr(regs), SIGFPE) |
672 | == NOTIFY_STOP) | 697 | == NOTIFY_STOP) |
@@ -675,6 +700,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) | |||
675 | 700 | ||
676 | if (fcr31 & FPU_CSR_UNI_X) { | 701 | if (fcr31 & FPU_CSR_UNI_X) { |
677 | int sig; | 702 | int sig; |
703 | void __user *fault_addr = NULL; | ||
678 | 704 | ||
679 | /* | 705 | /* |
680 | * Unimplemented operation exception. If we've got the full | 706 | * Unimplemented operation exception. If we've got the full |
@@ -690,7 +716,8 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) | |||
690 | lose_fpu(1); | 716 | lose_fpu(1); |
691 | 717 | ||
692 | /* Run the emulator */ | 718 | /* Run the emulator */ |
693 | sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1); | 719 | sig = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1, |
720 | &fault_addr); | ||
694 | 721 | ||
695 | /* | 722 | /* |
696 | * We can't allow the emulated instruction to leave any of | 723 | * We can't allow the emulated instruction to leave any of |
@@ -702,8 +729,7 @@ asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31) | |||
702 | own_fpu(1); /* Using the FPU again. */ | 729 | own_fpu(1); /* Using the FPU again. */ |
703 | 730 | ||
704 | /* If something went wrong, signal */ | 731 | /* If something went wrong, signal */ |
705 | if (sig) | 732 | process_fpemu_return(sig, fault_addr); |
706 | force_sig(sig, current); | ||
707 | 733 | ||
708 | return; | 734 | return; |
709 | } else if (fcr31 & FPU_CSR_INV_X) | 735 | } else if (fcr31 & FPU_CSR_INV_X) |
@@ -996,11 +1022,11 @@ asmlinkage void do_cpu(struct pt_regs *regs) | |||
996 | 1022 | ||
997 | if (!raw_cpu_has_fpu) { | 1023 | if (!raw_cpu_has_fpu) { |
998 | int sig; | 1024 | int sig; |
1025 | void __user *fault_addr = NULL; | ||
999 | sig = fpu_emulator_cop1Handler(regs, | 1026 | sig = fpu_emulator_cop1Handler(regs, |
1000 | ¤t->thread.fpu, 0); | 1027 | ¤t->thread.fpu, |
1001 | if (sig) | 1028 | 0, &fault_addr); |
1002 | force_sig(sig, current); | 1029 | if (!process_fpemu_return(sig, fault_addr)) |
1003 | else | ||
1004 | mt_ase_fp_affinity(); | 1030 | mt_ase_fp_affinity(); |
1005 | } | 1031 | } |
1006 | 1032 | ||
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 3eb3cde2f661..6a1fdfef8fde 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c | |||
@@ -1092,6 +1092,10 @@ static int vpe_open(struct inode *inode, struct file *filp) | |||
1092 | 1092 | ||
1093 | /* this of-course trashes what was there before... */ | 1093 | /* this of-course trashes what was there before... */ |
1094 | v->pbuffer = vmalloc(P_SIZE); | 1094 | v->pbuffer = vmalloc(P_SIZE); |
1095 | if (!v->pbuffer) { | ||
1096 | pr_warning("VPE loader: unable to allocate memory\n"); | ||
1097 | return -ENOMEM; | ||
1098 | } | ||
1095 | v->plen = P_SIZE; | 1099 | v->plen = P_SIZE; |
1096 | v->load_addr = NULL; | 1100 | v->load_addr = NULL; |
1097 | v->len = 0; | 1101 | v->len = 0; |
@@ -1149,10 +1153,9 @@ static int vpe_release(struct inode *inode, struct file *filp) | |||
1149 | if (ret < 0) | 1153 | if (ret < 0) |
1150 | v->shared_ptr = NULL; | 1154 | v->shared_ptr = NULL; |
1151 | 1155 | ||
1152 | // cleanup any temp buffers | 1156 | vfree(v->pbuffer); |
1153 | if (v->pbuffer) | ||
1154 | vfree(v->pbuffer); | ||
1155 | v->plen = 0; | 1157 | v->plen = 0; |
1158 | |||
1156 | return ret; | 1159 | return ret; |
1157 | } | 1160 | } |
1158 | 1161 | ||
@@ -1169,11 +1172,6 @@ static ssize_t vpe_write(struct file *file, const char __user * buffer, | |||
1169 | if (v == NULL) | 1172 | if (v == NULL) |
1170 | return -ENODEV; | 1173 | return -ENODEV; |
1171 | 1174 | ||
1172 | if (v->pbuffer == NULL) { | ||
1173 | printk(KERN_ERR "VPE loader: no buffer for program\n"); | ||
1174 | return -ENOMEM; | ||
1175 | } | ||
1176 | |||
1177 | if ((count + v->len) > v->plen) { | 1175 | if ((count + v->len) > v->plen) { |
1178 | printk(KERN_WARNING | 1176 | printk(KERN_WARNING |
1179 | "VPE loader: elf size too big. Perhaps strip uneeded symbols\n"); | 1177 | "VPE loader: elf size too big. Perhaps strip uneeded symbols\n"); |
diff --git a/arch/mips/lib/memset.S b/arch/mips/lib/memset.S index 77dc3b20110a..606c8a9efe3b 100644 --- a/arch/mips/lib/memset.S +++ b/arch/mips/lib/memset.S | |||
@@ -161,16 +161,16 @@ FEXPORT(__bzero) | |||
161 | 161 | ||
162 | .Lfwd_fixup: | 162 | .Lfwd_fixup: |
163 | PTR_L t0, TI_TASK($28) | 163 | PTR_L t0, TI_TASK($28) |
164 | LONG_L t0, THREAD_BUADDR(t0) | ||
165 | andi a2, 0x3f | 164 | andi a2, 0x3f |
165 | LONG_L t0, THREAD_BUADDR(t0) | ||
166 | LONG_ADDU a2, t1 | 166 | LONG_ADDU a2, t1 |
167 | jr ra | 167 | jr ra |
168 | LONG_SUBU a2, t0 | 168 | LONG_SUBU a2, t0 |
169 | 169 | ||
170 | .Lpartial_fixup: | 170 | .Lpartial_fixup: |
171 | PTR_L t0, TI_TASK($28) | 171 | PTR_L t0, TI_TASK($28) |
172 | LONG_L t0, THREAD_BUADDR(t0) | ||
173 | andi a2, LONGMASK | 172 | andi a2, LONGMASK |
173 | LONG_L t0, THREAD_BUADDR(t0) | ||
174 | LONG_ADDU a2, t1 | 174 | LONG_ADDU a2, t1 |
175 | jr ra | 175 | jr ra |
176 | LONG_SUBU a2, t0 | 176 | LONG_SUBU a2, t0 |
diff --git a/arch/mips/loongson/common/env.c b/arch/mips/loongson/common/env.c index ae4cff97a56c..11b193f848f8 100644 --- a/arch/mips/loongson/common/env.c +++ b/arch/mips/loongson/common/env.c | |||
@@ -29,9 +29,9 @@ unsigned long memsize, highmemsize; | |||
29 | 29 | ||
30 | #define parse_even_earlier(res, option, p) \ | 30 | #define parse_even_earlier(res, option, p) \ |
31 | do { \ | 31 | do { \ |
32 | int ret; \ | ||
32 | if (strncmp(option, (char *)p, strlen(option)) == 0) \ | 33 | if (strncmp(option, (char *)p, strlen(option)) == 0) \ |
33 | strict_strtol((char *)p + strlen(option"="), \ | 34 | ret = strict_strtol((char *)p + strlen(option"="), 10, &res); \ |
34 | 10, &res); \ | ||
35 | } while (0) | 35 | } while (0) |
36 | 36 | ||
37 | void __init prom_init_env(void) | 37 | void __init prom_init_env(void) |
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index b2ad1b0910ff..d32cb0503110 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c | |||
@@ -64,7 +64,7 @@ static int fpu_emu(struct pt_regs *, struct mips_fpu_struct *, | |||
64 | 64 | ||
65 | #if __mips >= 4 && __mips != 32 | 65 | #if __mips >= 4 && __mips != 32 |
66 | static int fpux_emu(struct pt_regs *, | 66 | static int fpux_emu(struct pt_regs *, |
67 | struct mips_fpu_struct *, mips_instruction); | 67 | struct mips_fpu_struct *, mips_instruction, void *__user *); |
68 | #endif | 68 | #endif |
69 | 69 | ||
70 | /* Further private data for which no space exists in mips_fpu_struct */ | 70 | /* Further private data for which no space exists in mips_fpu_struct */ |
@@ -208,16 +208,23 @@ static inline int cop1_64bit(struct pt_regs *xcp) | |||
208 | * Two instructions if the instruction is in a branch delay slot. | 208 | * Two instructions if the instruction is in a branch delay slot. |
209 | */ | 209 | */ |
210 | 210 | ||
211 | static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | 211 | static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx, |
212 | void *__user *fault_addr) | ||
212 | { | 213 | { |
213 | mips_instruction ir; | 214 | mips_instruction ir; |
214 | unsigned long emulpc, contpc; | 215 | unsigned long emulpc, contpc; |
215 | unsigned int cond; | 216 | unsigned int cond; |
216 | 217 | ||
217 | if (get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) { | 218 | if (!access_ok(VERIFY_READ, xcp->cp0_epc, sizeof(mips_instruction))) { |
218 | MIPS_FPU_EMU_INC_STATS(errors); | 219 | MIPS_FPU_EMU_INC_STATS(errors); |
220 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | ||
219 | return SIGBUS; | 221 | return SIGBUS; |
220 | } | 222 | } |
223 | if (__get_user(ir, (mips_instruction __user *) xcp->cp0_epc)) { | ||
224 | MIPS_FPU_EMU_INC_STATS(errors); | ||
225 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | ||
226 | return SIGSEGV; | ||
227 | } | ||
221 | 228 | ||
222 | /* XXX NEC Vr54xx bug workaround */ | 229 | /* XXX NEC Vr54xx bug workaround */ |
223 | if ((xcp->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir)) | 230 | if ((xcp->cp0_cause & CAUSEF_BD) && !isBranchInstr(&ir)) |
@@ -245,10 +252,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
245 | #endif | 252 | #endif |
246 | return SIGILL; | 253 | return SIGILL; |
247 | } | 254 | } |
248 | if (get_user(ir, (mips_instruction __user *) emulpc)) { | 255 | if (!access_ok(VERIFY_READ, emulpc, sizeof(mips_instruction))) { |
249 | MIPS_FPU_EMU_INC_STATS(errors); | 256 | MIPS_FPU_EMU_INC_STATS(errors); |
257 | *fault_addr = (mips_instruction __user *)emulpc; | ||
250 | return SIGBUS; | 258 | return SIGBUS; |
251 | } | 259 | } |
260 | if (__get_user(ir, (mips_instruction __user *) emulpc)) { | ||
261 | MIPS_FPU_EMU_INC_STATS(errors); | ||
262 | *fault_addr = (mips_instruction __user *)emulpc; | ||
263 | return SIGSEGV; | ||
264 | } | ||
252 | /* __compute_return_epc() will have updated cp0_epc */ | 265 | /* __compute_return_epc() will have updated cp0_epc */ |
253 | contpc = xcp->cp0_epc; | 266 | contpc = xcp->cp0_epc; |
254 | /* In order not to confuse ptrace() et al, tweak context */ | 267 | /* In order not to confuse ptrace() et al, tweak context */ |
@@ -269,10 +282,17 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
269 | u64 val; | 282 | u64 val; |
270 | 283 | ||
271 | MIPS_FPU_EMU_INC_STATS(loads); | 284 | MIPS_FPU_EMU_INC_STATS(loads); |
272 | if (get_user(val, va)) { | 285 | |
286 | if (!access_ok(VERIFY_READ, va, sizeof(u64))) { | ||
273 | MIPS_FPU_EMU_INC_STATS(errors); | 287 | MIPS_FPU_EMU_INC_STATS(errors); |
288 | *fault_addr = va; | ||
274 | return SIGBUS; | 289 | return SIGBUS; |
275 | } | 290 | } |
291 | if (__get_user(val, va)) { | ||
292 | MIPS_FPU_EMU_INC_STATS(errors); | ||
293 | *fault_addr = va; | ||
294 | return SIGSEGV; | ||
295 | } | ||
276 | DITOREG(val, MIPSInst_RT(ir)); | 296 | DITOREG(val, MIPSInst_RT(ir)); |
277 | break; | 297 | break; |
278 | } | 298 | } |
@@ -284,10 +304,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
284 | 304 | ||
285 | MIPS_FPU_EMU_INC_STATS(stores); | 305 | MIPS_FPU_EMU_INC_STATS(stores); |
286 | DIFROMREG(val, MIPSInst_RT(ir)); | 306 | DIFROMREG(val, MIPSInst_RT(ir)); |
287 | if (put_user(val, va)) { | 307 | if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) { |
288 | MIPS_FPU_EMU_INC_STATS(errors); | 308 | MIPS_FPU_EMU_INC_STATS(errors); |
309 | *fault_addr = va; | ||
289 | return SIGBUS; | 310 | return SIGBUS; |
290 | } | 311 | } |
312 | if (__put_user(val, va)) { | ||
313 | MIPS_FPU_EMU_INC_STATS(errors); | ||
314 | *fault_addr = va; | ||
315 | return SIGSEGV; | ||
316 | } | ||
291 | break; | 317 | break; |
292 | } | 318 | } |
293 | 319 | ||
@@ -297,10 +323,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
297 | u32 val; | 323 | u32 val; |
298 | 324 | ||
299 | MIPS_FPU_EMU_INC_STATS(loads); | 325 | MIPS_FPU_EMU_INC_STATS(loads); |
300 | if (get_user(val, va)) { | 326 | if (!access_ok(VERIFY_READ, va, sizeof(u32))) { |
301 | MIPS_FPU_EMU_INC_STATS(errors); | 327 | MIPS_FPU_EMU_INC_STATS(errors); |
328 | *fault_addr = va; | ||
302 | return SIGBUS; | 329 | return SIGBUS; |
303 | } | 330 | } |
331 | if (__get_user(val, va)) { | ||
332 | MIPS_FPU_EMU_INC_STATS(errors); | ||
333 | *fault_addr = va; | ||
334 | return SIGSEGV; | ||
335 | } | ||
304 | SITOREG(val, MIPSInst_RT(ir)); | 336 | SITOREG(val, MIPSInst_RT(ir)); |
305 | break; | 337 | break; |
306 | } | 338 | } |
@@ -312,10 +344,16 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
312 | 344 | ||
313 | MIPS_FPU_EMU_INC_STATS(stores); | 345 | MIPS_FPU_EMU_INC_STATS(stores); |
314 | SIFROMREG(val, MIPSInst_RT(ir)); | 346 | SIFROMREG(val, MIPSInst_RT(ir)); |
315 | if (put_user(val, va)) { | 347 | if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) { |
316 | MIPS_FPU_EMU_INC_STATS(errors); | 348 | MIPS_FPU_EMU_INC_STATS(errors); |
349 | *fault_addr = va; | ||
317 | return SIGBUS; | 350 | return SIGBUS; |
318 | } | 351 | } |
352 | if (__put_user(val, va)) { | ||
353 | MIPS_FPU_EMU_INC_STATS(errors); | ||
354 | *fault_addr = va; | ||
355 | return SIGSEGV; | ||
356 | } | ||
319 | break; | 357 | break; |
320 | } | 358 | } |
321 | 359 | ||
@@ -440,11 +478,18 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
440 | contpc = (xcp->cp0_epc + | 478 | contpc = (xcp->cp0_epc + |
441 | (MIPSInst_SIMM(ir) << 2)); | 479 | (MIPSInst_SIMM(ir) << 2)); |
442 | 480 | ||
443 | if (get_user(ir, | 481 | if (!access_ok(VERIFY_READ, xcp->cp0_epc, |
444 | (mips_instruction __user *) xcp->cp0_epc)) { | 482 | sizeof(mips_instruction))) { |
445 | MIPS_FPU_EMU_INC_STATS(errors); | 483 | MIPS_FPU_EMU_INC_STATS(errors); |
484 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | ||
446 | return SIGBUS; | 485 | return SIGBUS; |
447 | } | 486 | } |
487 | if (__get_user(ir, | ||
488 | (mips_instruction __user *) xcp->cp0_epc)) { | ||
489 | MIPS_FPU_EMU_INC_STATS(errors); | ||
490 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | ||
491 | return SIGSEGV; | ||
492 | } | ||
448 | 493 | ||
449 | switch (MIPSInst_OPCODE(ir)) { | 494 | switch (MIPSInst_OPCODE(ir)) { |
450 | case lwc1_op: | 495 | case lwc1_op: |
@@ -506,9 +551,8 @@ static int cop1Emulate(struct pt_regs *xcp, struct mips_fpu_struct *ctx) | |||
506 | 551 | ||
507 | #if __mips >= 4 && __mips != 32 | 552 | #if __mips >= 4 && __mips != 32 |
508 | case cop1x_op:{ | 553 | case cop1x_op:{ |
509 | int sig; | 554 | int sig = fpux_emu(xcp, ctx, ir, fault_addr); |
510 | 555 | if (sig) | |
511 | if ((sig = fpux_emu(xcp, ctx, ir))) | ||
512 | return sig; | 556 | return sig; |
513 | break; | 557 | break; |
514 | } | 558 | } |
@@ -604,7 +648,7 @@ DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg); | |||
604 | DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg); | 648 | DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg); |
605 | 649 | ||
606 | static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | 650 | static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, |
607 | mips_instruction ir) | 651 | mips_instruction ir, void *__user *fault_addr) |
608 | { | 652 | { |
609 | unsigned rcsr = 0; /* resulting csr */ | 653 | unsigned rcsr = 0; /* resulting csr */ |
610 | 654 | ||
@@ -624,10 +668,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
624 | xcp->regs[MIPSInst_FT(ir)]); | 668 | xcp->regs[MIPSInst_FT(ir)]); |
625 | 669 | ||
626 | MIPS_FPU_EMU_INC_STATS(loads); | 670 | MIPS_FPU_EMU_INC_STATS(loads); |
627 | if (get_user(val, va)) { | 671 | if (!access_ok(VERIFY_READ, va, sizeof(u32))) { |
628 | MIPS_FPU_EMU_INC_STATS(errors); | 672 | MIPS_FPU_EMU_INC_STATS(errors); |
673 | *fault_addr = va; | ||
629 | return SIGBUS; | 674 | return SIGBUS; |
630 | } | 675 | } |
676 | if (__get_user(val, va)) { | ||
677 | MIPS_FPU_EMU_INC_STATS(errors); | ||
678 | *fault_addr = va; | ||
679 | return SIGSEGV; | ||
680 | } | ||
631 | SITOREG(val, MIPSInst_FD(ir)); | 681 | SITOREG(val, MIPSInst_FD(ir)); |
632 | break; | 682 | break; |
633 | 683 | ||
@@ -638,10 +688,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
638 | MIPS_FPU_EMU_INC_STATS(stores); | 688 | MIPS_FPU_EMU_INC_STATS(stores); |
639 | 689 | ||
640 | SIFROMREG(val, MIPSInst_FS(ir)); | 690 | SIFROMREG(val, MIPSInst_FS(ir)); |
641 | if (put_user(val, va)) { | 691 | if (!access_ok(VERIFY_WRITE, va, sizeof(u32))) { |
642 | MIPS_FPU_EMU_INC_STATS(errors); | 692 | MIPS_FPU_EMU_INC_STATS(errors); |
693 | *fault_addr = va; | ||
643 | return SIGBUS; | 694 | return SIGBUS; |
644 | } | 695 | } |
696 | if (put_user(val, va)) { | ||
697 | MIPS_FPU_EMU_INC_STATS(errors); | ||
698 | *fault_addr = va; | ||
699 | return SIGSEGV; | ||
700 | } | ||
645 | break; | 701 | break; |
646 | 702 | ||
647 | case madd_s_op: | 703 | case madd_s_op: |
@@ -701,10 +757,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
701 | xcp->regs[MIPSInst_FT(ir)]); | 757 | xcp->regs[MIPSInst_FT(ir)]); |
702 | 758 | ||
703 | MIPS_FPU_EMU_INC_STATS(loads); | 759 | MIPS_FPU_EMU_INC_STATS(loads); |
704 | if (get_user(val, va)) { | 760 | if (!access_ok(VERIFY_READ, va, sizeof(u64))) { |
705 | MIPS_FPU_EMU_INC_STATS(errors); | 761 | MIPS_FPU_EMU_INC_STATS(errors); |
762 | *fault_addr = va; | ||
706 | return SIGBUS; | 763 | return SIGBUS; |
707 | } | 764 | } |
765 | if (__get_user(val, va)) { | ||
766 | MIPS_FPU_EMU_INC_STATS(errors); | ||
767 | *fault_addr = va; | ||
768 | return SIGSEGV; | ||
769 | } | ||
708 | DITOREG(val, MIPSInst_FD(ir)); | 770 | DITOREG(val, MIPSInst_FD(ir)); |
709 | break; | 771 | break; |
710 | 772 | ||
@@ -714,10 +776,16 @@ static int fpux_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
714 | 776 | ||
715 | MIPS_FPU_EMU_INC_STATS(stores); | 777 | MIPS_FPU_EMU_INC_STATS(stores); |
716 | DIFROMREG(val, MIPSInst_FS(ir)); | 778 | DIFROMREG(val, MIPSInst_FS(ir)); |
717 | if (put_user(val, va)) { | 779 | if (!access_ok(VERIFY_WRITE, va, sizeof(u64))) { |
718 | MIPS_FPU_EMU_INC_STATS(errors); | 780 | MIPS_FPU_EMU_INC_STATS(errors); |
781 | *fault_addr = va; | ||
719 | return SIGBUS; | 782 | return SIGBUS; |
720 | } | 783 | } |
784 | if (__put_user(val, va)) { | ||
785 | MIPS_FPU_EMU_INC_STATS(errors); | ||
786 | *fault_addr = va; | ||
787 | return SIGSEGV; | ||
788 | } | ||
721 | break; | 789 | break; |
722 | 790 | ||
723 | case madd_d_op: | 791 | case madd_d_op: |
@@ -1242,7 +1310,7 @@ static int fpu_emu(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
1242 | } | 1310 | } |
1243 | 1311 | ||
1244 | int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | 1312 | int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, |
1245 | int has_fpu) | 1313 | int has_fpu, void *__user *fault_addr) |
1246 | { | 1314 | { |
1247 | unsigned long oldepc, prevepc; | 1315 | unsigned long oldepc, prevepc; |
1248 | mips_instruction insn; | 1316 | mips_instruction insn; |
@@ -1252,10 +1320,16 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
1252 | do { | 1320 | do { |
1253 | prevepc = xcp->cp0_epc; | 1321 | prevepc = xcp->cp0_epc; |
1254 | 1322 | ||
1255 | if (get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) { | 1323 | if (!access_ok(VERIFY_READ, xcp->cp0_epc, sizeof(mips_instruction))) { |
1256 | MIPS_FPU_EMU_INC_STATS(errors); | 1324 | MIPS_FPU_EMU_INC_STATS(errors); |
1325 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | ||
1257 | return SIGBUS; | 1326 | return SIGBUS; |
1258 | } | 1327 | } |
1328 | if (__get_user(insn, (mips_instruction __user *) xcp->cp0_epc)) { | ||
1329 | MIPS_FPU_EMU_INC_STATS(errors); | ||
1330 | *fault_addr = (mips_instruction __user *)xcp->cp0_epc; | ||
1331 | return SIGSEGV; | ||
1332 | } | ||
1259 | if (insn == 0) | 1333 | if (insn == 0) |
1260 | xcp->cp0_epc += 4; /* skip nops */ | 1334 | xcp->cp0_epc += 4; /* skip nops */ |
1261 | else { | 1335 | else { |
@@ -1267,7 +1341,7 @@ int fpu_emulator_cop1Handler(struct pt_regs *xcp, struct mips_fpu_struct *ctx, | |||
1267 | */ | 1341 | */ |
1268 | /* convert to ieee library modes */ | 1342 | /* convert to ieee library modes */ |
1269 | ieee754_csr.rm = ieee_rm[ieee754_csr.rm]; | 1343 | ieee754_csr.rm = ieee_rm[ieee754_csr.rm]; |
1270 | sig = cop1Emulate(xcp, ctx); | 1344 | sig = cop1Emulate(xcp, ctx, fault_addr); |
1271 | /* revert to mips rounding mode */ | 1345 | /* revert to mips rounding mode */ |
1272 | ieee754_csr.rm = mips_rm[ieee754_csr.rm]; | 1346 | ieee754_csr.rm = mips_rm[ieee754_csr.rm]; |
1273 | } | 1347 | } |
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c index 4fc1a0fbe007..21ea14efb837 100644 --- a/arch/mips/mm/dma-default.c +++ b/arch/mips/mm/dma-default.c | |||
@@ -288,7 +288,7 @@ int mips_dma_supported(struct device *dev, u64 mask) | |||
288 | return plat_dma_supported(dev, mask); | 288 | return plat_dma_supported(dev, mask); |
289 | } | 289 | } |
290 | 290 | ||
291 | void mips_dma_cache_sync(struct device *dev, void *vaddr, size_t size, | 291 | void dma_cache_sync(struct device *dev, void *vaddr, size_t size, |
292 | enum dma_data_direction direction) | 292 | enum dma_data_direction direction) |
293 | { | 293 | { |
294 | BUG_ON(direction == DMA_NONE); | 294 | BUG_ON(direction == DMA_NONE); |
@@ -298,6 +298,8 @@ void mips_dma_cache_sync(struct device *dev, void *vaddr, size_t size, | |||
298 | __dma_sync((unsigned long)vaddr, size, direction); | 298 | __dma_sync((unsigned long)vaddr, size, direction); |
299 | } | 299 | } |
300 | 300 | ||
301 | EXPORT_SYMBOL(dma_cache_sync); | ||
302 | |||
301 | static struct dma_map_ops mips_default_dma_map_ops = { | 303 | static struct dma_map_ops mips_default_dma_map_ops = { |
302 | .alloc_coherent = mips_dma_alloc_coherent, | 304 | .alloc_coherent = mips_dma_alloc_coherent, |
303 | .free_coherent = mips_dma_free_coherent, | 305 | .free_coherent = mips_dma_free_coherent, |
diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c index 505fecad4684..9cca8de00545 100644 --- a/arch/mips/mm/sc-mips.c +++ b/arch/mips/mm/sc-mips.c | |||
@@ -68,6 +68,9 @@ static struct bcache_ops mips_sc_ops = { | |||
68 | */ | 68 | */ |
69 | static inline int mips_sc_is_activated(struct cpuinfo_mips *c) | 69 | static inline int mips_sc_is_activated(struct cpuinfo_mips *c) |
70 | { | 70 | { |
71 | unsigned int config2 = read_c0_config2(); | ||
72 | unsigned int tmp; | ||
73 | |||
71 | /* Check the bypass bit (L2B) */ | 74 | /* Check the bypass bit (L2B) */ |
72 | switch (c->cputype) { | 75 | switch (c->cputype) { |
73 | case CPU_34K: | 76 | case CPU_34K: |
@@ -83,6 +86,7 @@ static inline int mips_sc_is_activated(struct cpuinfo_mips *c) | |||
83 | c->scache.linesz = 2 << tmp; | 86 | c->scache.linesz = 2 << tmp; |
84 | else | 87 | else |
85 | return 0; | 88 | return 0; |
89 | return 1; | ||
86 | } | 90 | } |
87 | 91 | ||
88 | static inline int __init mips_sc_probe(void) | 92 | static inline int __init mips_sc_probe(void) |
diff --git a/arch/mips/pmc-sierra/yosemite/py-console.c b/arch/mips/pmc-sierra/yosemite/py-console.c index b7f1d9c4a8a3..434d7b1a8c6a 100644 --- a/arch/mips/pmc-sierra/yosemite/py-console.c +++ b/arch/mips/pmc-sierra/yosemite/py-console.c | |||
@@ -65,11 +65,15 @@ static unsigned char readb_outer_space(unsigned long long phys) | |||
65 | 65 | ||
66 | __asm__ __volatile__ ( | 66 | __asm__ __volatile__ ( |
67 | " .set mips3 \n" | 67 | " .set mips3 \n" |
68 | " .set push \n" | ||
69 | " .set noreorder \n" | ||
70 | " .set nomacro \n" | ||
68 | " ld %0, %1 \n" | 71 | " ld %0, %1 \n" |
72 | " .set pop \n" | ||
69 | " lbu %0, (%0) \n" | 73 | " lbu %0, (%0) \n" |
70 | " .set mips0 \n" | 74 | " .set mips0 \n" |
71 | : "=r" (res) | 75 | : "=r" (res) |
72 | : "m" (vaddr)); | 76 | : "R" (vaddr)); |
73 | 77 | ||
74 | write_c0_status(sr); | 78 | write_c0_status(sr); |
75 | ssnop_4(); | 79 | ssnop_4(); |
@@ -89,11 +93,15 @@ static void writeb_outer_space(unsigned long long phys, unsigned char c) | |||
89 | 93 | ||
90 | __asm__ __volatile__ ( | 94 | __asm__ __volatile__ ( |
91 | " .set mips3 \n" | 95 | " .set mips3 \n" |
96 | " .set push \n" | ||
97 | " .set noreorder \n" | ||
98 | " .set nomacro \n" | ||
92 | " ld %0, %1 \n" | 99 | " ld %0, %1 \n" |
100 | " .set pop \n" | ||
93 | " sb %2, (%0) \n" | 101 | " sb %2, (%0) \n" |
94 | " .set mips0 \n" | 102 | " .set mips0 \n" |
95 | : "=&r" (tmp) | 103 | : "=&r" (tmp) |
96 | : "m" (vaddr), "r" (c)); | 104 | : "R" (vaddr), "r" (c)); |
97 | 105 | ||
98 | write_c0_status(sr); | 106 | write_c0_status(sr); |
99 | ssnop_4(); | 107 | ssnop_4(); |
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c index c308989fc464..41707a245dea 100644 --- a/arch/mips/sibyte/swarm/setup.c +++ b/arch/mips/sibyte/swarm/setup.c | |||
@@ -82,7 +82,7 @@ int swarm_be_handler(struct pt_regs *regs, int is_fixup) | |||
82 | enum swarm_rtc_type { | 82 | enum swarm_rtc_type { |
83 | RTC_NONE, | 83 | RTC_NONE, |
84 | RTC_XICOR, | 84 | RTC_XICOR, |
85 | RTC_M4LT81 | 85 | RTC_M41T81, |
86 | }; | 86 | }; |
87 | 87 | ||
88 | enum swarm_rtc_type swarm_rtc_type; | 88 | enum swarm_rtc_type swarm_rtc_type; |
@@ -96,7 +96,7 @@ void read_persistent_clock(struct timespec *ts) | |||
96 | sec = xicor_get_time(); | 96 | sec = xicor_get_time(); |
97 | break; | 97 | break; |
98 | 98 | ||
99 | case RTC_M4LT81: | 99 | case RTC_M41T81: |
100 | sec = m41t81_get_time(); | 100 | sec = m41t81_get_time(); |
101 | break; | 101 | break; |
102 | 102 | ||
@@ -115,7 +115,7 @@ int rtc_mips_set_time(unsigned long sec) | |||
115 | case RTC_XICOR: | 115 | case RTC_XICOR: |
116 | return xicor_set_time(sec); | 116 | return xicor_set_time(sec); |
117 | 117 | ||
118 | case RTC_M4LT81: | 118 | case RTC_M41T81: |
119 | return m41t81_set_time(sec); | 119 | return m41t81_set_time(sec); |
120 | 120 | ||
121 | case RTC_NONE: | 121 | case RTC_NONE: |
@@ -141,7 +141,7 @@ void __init plat_mem_setup(void) | |||
141 | if (xicor_probe()) | 141 | if (xicor_probe()) |
142 | swarm_rtc_type = RTC_XICOR; | 142 | swarm_rtc_type = RTC_XICOR; |
143 | if (m41t81_probe()) | 143 | if (m41t81_probe()) |
144 | swarm_rtc_type = RTC_M4LT81; | 144 | swarm_rtc_type = RTC_M41T81; |
145 | 145 | ||
146 | #ifdef CONFIG_VT | 146 | #ifdef CONFIG_VT |
147 | screen_info = (struct screen_info) { | 147 | screen_info = (struct screen_info) { |
diff --git a/arch/mn10300/kernel/gdb-io-serial.c b/arch/mn10300/kernel/gdb-io-serial.c index 0d5d63c91dc3..f28dc99c6f72 100644 --- a/arch/mn10300/kernel/gdb-io-serial.c +++ b/arch/mn10300/kernel/gdb-io-serial.c | |||
@@ -73,7 +73,8 @@ void gdbstub_io_init(void) | |||
73 | GDBPORT_SERIAL_IER = UART_IER_RDI | UART_IER_RLSI; | 73 | GDBPORT_SERIAL_IER = UART_IER_RDI | UART_IER_RLSI; |
74 | 74 | ||
75 | /* permit level 0 IRQs to take place */ | 75 | /* permit level 0 IRQs to take place */ |
76 | local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); | 76 | arch_local_change_intr_mask_level( |
77 | NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); | ||
77 | } | 78 | } |
78 | 79 | ||
79 | /* | 80 | /* |
diff --git a/arch/mn10300/kernel/gdb-io-ttysm.c b/arch/mn10300/kernel/gdb-io-ttysm.c index 97dfda23342c..abdeea153c89 100644 --- a/arch/mn10300/kernel/gdb-io-ttysm.c +++ b/arch/mn10300/kernel/gdb-io-ttysm.c | |||
@@ -87,7 +87,8 @@ void __init gdbstub_io_init(void) | |||
87 | tmp = *gdbstub_port->_control; | 87 | tmp = *gdbstub_port->_control; |
88 | 88 | ||
89 | /* permit level 0 IRQs only */ | 89 | /* permit level 0 IRQs only */ |
90 | local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); | 90 | arch_local_change_intr_mask_level( |
91 | NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); | ||
91 | } | 92 | } |
92 | 93 | ||
93 | /* | 94 | /* |
diff --git a/arch/mn10300/kernel/gdb-stub.c b/arch/mn10300/kernel/gdb-stub.c index a5fc3f05309b..b169d99d9f20 100644 --- a/arch/mn10300/kernel/gdb-stub.c +++ b/arch/mn10300/kernel/gdb-stub.c | |||
@@ -1194,7 +1194,8 @@ static int gdbstub(struct pt_regs *regs, enum exception_code excep) | |||
1194 | 1194 | ||
1195 | asm volatile("mov mdr,%0" : "=d"(mdr)); | 1195 | asm volatile("mov mdr,%0" : "=d"(mdr)); |
1196 | local_save_flags(epsw); | 1196 | local_save_flags(epsw); |
1197 | local_change_intr_mask_level(NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); | 1197 | arch_local_change_intr_mask_level( |
1198 | NUM2EPSW_IM(CONFIG_GDBSTUB_IRQ_LEVEL + 1)); | ||
1198 | 1199 | ||
1199 | gdbstub_store_fpu(); | 1200 | gdbstub_store_fpu(); |
1200 | 1201 | ||
diff --git a/arch/mn10300/kernel/irq.c b/arch/mn10300/kernel/irq.c index c2e44597c22b..ac11754ecec5 100644 --- a/arch/mn10300/kernel/irq.c +++ b/arch/mn10300/kernel/irq.c | |||
@@ -459,7 +459,7 @@ void migrate_irqs(void) | |||
459 | tmp = CROSS_GxICR(irq, new); | 459 | tmp = CROSS_GxICR(irq, new); |
460 | 460 | ||
461 | x &= GxICR_LEVEL | GxICR_ENABLE; | 461 | x &= GxICR_LEVEL | GxICR_ENABLE; |
462 | if (GxICR(irq) & GxICR_REQUEST) { | 462 | if (GxICR(irq) & GxICR_REQUEST) |
463 | x |= GxICR_REQUEST | GxICR_DETECT; | 463 | x |= GxICR_REQUEST | GxICR_DETECT; |
464 | CROSS_GxICR(irq, new) = x; | 464 | CROSS_GxICR(irq, new) = x; |
465 | tmp = CROSS_GxICR(irq, new); | 465 | tmp = CROSS_GxICR(irq, new); |
diff --git a/arch/mn10300/kernel/time.c b/arch/mn10300/kernel/time.c index f860a340acc9..75da468090b9 100644 --- a/arch/mn10300/kernel/time.c +++ b/arch/mn10300/kernel/time.c | |||
@@ -40,21 +40,17 @@ unsigned long long sched_clock(void) | |||
40 | unsigned long long ll; | 40 | unsigned long long ll; |
41 | unsigned l[2]; | 41 | unsigned l[2]; |
42 | } tsc64, result; | 42 | } tsc64, result; |
43 | unsigned long tsc, tmp; | 43 | unsigned long tmp; |
44 | unsigned product[3]; /* 96-bit intermediate value */ | 44 | unsigned product[3]; /* 96-bit intermediate value */ |
45 | 45 | ||
46 | /* cnt32_to_63() is not safe with preemption */ | 46 | /* cnt32_to_63() is not safe with preemption */ |
47 | preempt_disable(); | 47 | preempt_disable(); |
48 | 48 | ||
49 | /* read the TSC value | 49 | /* expand the tsc to 64-bits. |
50 | */ | ||
51 | tsc = get_cycles(); | ||
52 | |||
53 | /* expand to 64-bits. | ||
54 | * - sched_clock() must be called once a minute or better or the | 50 | * - sched_clock() must be called once a minute or better or the |
55 | * following will go horribly wrong - see cnt32_to_63() | 51 | * following will go horribly wrong - see cnt32_to_63() |
56 | */ | 52 | */ |
57 | tsc64.ll = cnt32_to_63(tsc) & 0x7fffffffffffffffULL; | 53 | tsc64.ll = cnt32_to_63(get_cycles()) & 0x7fffffffffffffffULL; |
58 | 54 | ||
59 | preempt_enable(); | 55 | preempt_enable(); |
60 | 56 | ||
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c index fea833e18ad5..e0d703c7fdf7 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_gpt.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_gpt.c | |||
@@ -63,6 +63,7 @@ | |||
63 | #include <linux/of_gpio.h> | 63 | #include <linux/of_gpio.h> |
64 | #include <linux/kernel.h> | 64 | #include <linux/kernel.h> |
65 | #include <linux/slab.h> | 65 | #include <linux/slab.h> |
66 | #include <linux/fs.h> | ||
66 | #include <linux/watchdog.h> | 67 | #include <linux/watchdog.h> |
67 | #include <linux/miscdevice.h> | 68 | #include <linux/miscdevice.h> |
68 | #include <linux/uaccess.h> | 69 | #include <linux/uaccess.h> |
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 56c8687b29b3..7eff9b7347c0 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/kernel_stat.h> | 19 | #include <linux/kernel_stat.h> |
20 | #include <linux/rcupdate.h> | 20 | #include <linux/rcupdate.h> |
21 | #include <linux/posix-timers.h> | 21 | #include <linux/posix-timers.h> |
22 | #include <linux/cpu.h> | ||
22 | 23 | ||
23 | #include <asm/s390_ext.h> | 24 | #include <asm/s390_ext.h> |
24 | #include <asm/timer.h> | 25 | #include <asm/timer.h> |
@@ -566,6 +567,23 @@ void init_cpu_vtimer(void) | |||
566 | __ctl_set_bit(0,10); | 567 | __ctl_set_bit(0,10); |
567 | } | 568 | } |
568 | 569 | ||
570 | static int __cpuinit s390_nohz_notify(struct notifier_block *self, | ||
571 | unsigned long action, void *hcpu) | ||
572 | { | ||
573 | struct s390_idle_data *idle; | ||
574 | long cpu = (long) hcpu; | ||
575 | |||
576 | idle = &per_cpu(s390_idle, cpu); | ||
577 | switch (action) { | ||
578 | case CPU_DYING: | ||
579 | case CPU_DYING_FROZEN: | ||
580 | idle->nohz_delay = 0; | ||
581 | default: | ||
582 | break; | ||
583 | } | ||
584 | return NOTIFY_OK; | ||
585 | } | ||
586 | |||
569 | void __init vtime_init(void) | 587 | void __init vtime_init(void) |
570 | { | 588 | { |
571 | /* request the cpu timer external interrupt */ | 589 | /* request the cpu timer external interrupt */ |
@@ -574,5 +592,6 @@ void __init vtime_init(void) | |||
574 | 592 | ||
575 | /* Enable cpu timer interrupts on the boot cpu. */ | 593 | /* Enable cpu timer interrupts on the boot cpu. */ |
576 | init_cpu_vtimer(); | 594 | init_cpu_vtimer(); |
595 | cpu_notifier(s390_nohz_notify, 0); | ||
577 | } | 596 | } |
578 | 597 | ||
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 7f217b3a50a8..2e9d78d21fd3 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
@@ -22,7 +22,8 @@ config SUPERH | |||
22 | select HAVE_SPARSE_IRQ | 22 | select HAVE_SPARSE_IRQ |
23 | select RTC_LIB | 23 | select RTC_LIB |
24 | select GENERIC_ATOMIC64 | 24 | select GENERIC_ATOMIC64 |
25 | select GENERIC_HARDIRQS_NO_DEPRECATED | 25 | # Support the deprecated APIs until MFD and GPIOLIB catch up. |
26 | select GENERIC_HARDIRQS_NO_DEPRECATED if !MFD_SUPPORT && !GPIOLIB | ||
26 | help | 27 | help |
27 | The SuperH is a RISC processor targeted for use in embedded systems | 28 | The SuperH is a RISC processor targeted for use in embedded systems |
28 | and consumer electronics; it was also used in the Sega Dreamcast | 29 | and consumer electronics; it was also used in the Sega Dreamcast |
diff --git a/arch/sh/boards/mach-se/7206/irq.c b/arch/sh/boards/mach-se/7206/irq.c index d961949600fd..9070d7e60704 100644 --- a/arch/sh/boards/mach-se/7206/irq.c +++ b/arch/sh/boards/mach-se/7206/irq.c | |||
@@ -140,7 +140,7 @@ void __init init_se7206_IRQ(void) | |||
140 | make_se7206_irq(IRQ1_IRQ); /* ATA */ | 140 | make_se7206_irq(IRQ1_IRQ); /* ATA */ |
141 | make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */ | 141 | make_se7206_irq(IRQ3_IRQ); /* SLOT / PCM */ |
142 | 142 | ||
143 | __raw_writew(__raw_readw(INTC_ICR1) | 0x000b, INTC_ICR); /* ICR1 */ | 143 | __raw_writew(__raw_readw(INTC_ICR1) | 0x000b, INTC_ICR1); /* ICR1 */ |
144 | 144 | ||
145 | /* FPGA System register setup*/ | 145 | /* FPGA System register setup*/ |
146 | __raw_writew(0x0000,INTSTS0); /* Clear INTSTS0 */ | 146 | __raw_writew(0x0000,INTSTS0); /* Clear INTSTS0 */ |
diff --git a/arch/sh/include/asm/unistd_32.h b/arch/sh/include/asm/unistd_32.h index 903cd618eb74..d6741fca89a4 100644 --- a/arch/sh/include/asm/unistd_32.h +++ b/arch/sh/include/asm/unistd_32.h | |||
@@ -368,8 +368,9 @@ | |||
368 | #define __NR_sendmsg 355 | 368 | #define __NR_sendmsg 355 |
369 | #define __NR_recvmsg 356 | 369 | #define __NR_recvmsg 356 |
370 | #define __NR_recvmmsg 357 | 370 | #define __NR_recvmmsg 357 |
371 | #define __NR_accept4 358 | ||
371 | 372 | ||
372 | #define NR_syscalls 358 | 373 | #define NR_syscalls 359 |
373 | 374 | ||
374 | #ifdef __KERNEL__ | 375 | #ifdef __KERNEL__ |
375 | 376 | ||
diff --git a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c index b26264dc2aef..c509c40cba4b 100644 --- a/arch/sh/kernel/cpu/sh2a/clock-sh7201.c +++ b/arch/sh/kernel/cpu/sh2a/clock-sh7201.c | |||
@@ -34,7 +34,7 @@ static const int pfc_divisors[]={1,2,3,4,6,8,12}; | |||
34 | 34 | ||
35 | static void master_clk_init(struct clk *clk) | 35 | static void master_clk_init(struct clk *clk) |
36 | { | 36 | { |
37 | return 10000000 * PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007]; | 37 | clk->rate = 10000000 * PLL2 * pll1rate[(__raw_readw(FREQCR) >> 8) & 0x0007]; |
38 | } | 38 | } |
39 | 39 | ||
40 | static struct clk_ops sh7201_master_clk_ops = { | 40 | static struct clk_ops sh7201_master_clk_ops = { |
diff --git a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c index b601fa3978d1..6282a839e08e 100644 --- a/arch/sh/kernel/cpu/sh4/clock-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/clock-sh4-202.c | |||
@@ -81,8 +81,7 @@ static void shoc_clk_init(struct clk *clk) | |||
81 | for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) { | 81 | for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) { |
82 | int divisor = frqcr3_divisors[i]; | 82 | int divisor = frqcr3_divisors[i]; |
83 | 83 | ||
84 | if (clk->ops->set_rate(clk, clk->parent->rate / | 84 | if (clk->ops->set_rate(clk, clk->parent->rate / divisor) == 0) |
85 | divisor, 0) == 0) | ||
86 | break; | 85 | break; |
87 | } | 86 | } |
88 | 87 | ||
diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S index e872e81add8a..6fc347ebe59d 100644 --- a/arch/sh/kernel/syscalls_32.S +++ b/arch/sh/kernel/syscalls_32.S | |||
@@ -375,3 +375,4 @@ ENTRY(sys_call_table) | |||
375 | .long sys_sendmsg /* 355 */ | 375 | .long sys_sendmsg /* 355 */ |
376 | .long sys_recvmsg | 376 | .long sys_recvmsg |
377 | .long sys_recvmmsg | 377 | .long sys_recvmmsg |
378 | .long sys_accept4 | ||
diff --git a/arch/sparc/include/asm/openprom.h b/arch/sparc/include/asm/openprom.h index 81cd43432dc0..47eaafad15ce 100644 --- a/arch/sparc/include/asm/openprom.h +++ b/arch/sparc/include/asm/openprom.h | |||
@@ -39,7 +39,7 @@ struct linux_dev_v2_funcs { | |||
39 | int (*v2_dev_open)(char *devpath); | 39 | int (*v2_dev_open)(char *devpath); |
40 | void (*v2_dev_close)(int d); | 40 | void (*v2_dev_close)(int d); |
41 | int (*v2_dev_read)(int d, char *buf, int nbytes); | 41 | int (*v2_dev_read)(int d, char *buf, int nbytes); |
42 | int (*v2_dev_write)(int d, char *buf, int nbytes); | 42 | int (*v2_dev_write)(int d, const char *buf, int nbytes); |
43 | int (*v2_dev_seek)(int d, int hi, int lo); | 43 | int (*v2_dev_seek)(int d, int hi, int lo); |
44 | 44 | ||
45 | /* Never issued (multistage load support) */ | 45 | /* Never issued (multistage load support) */ |
diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h index 51296a6f5005..9e5c64084b86 100644 --- a/arch/sparc/include/asm/oplib_32.h +++ b/arch/sparc/include/asm/oplib_32.h | |||
@@ -60,25 +60,6 @@ extern char *prom_getbootargs(void); | |||
60 | extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes); | 60 | extern char *prom_mapio(char *virt_hint, int io_space, unsigned int phys_addr, unsigned int num_bytes); |
61 | extern void prom_unmapio(char *virt_addr, unsigned int num_bytes); | 61 | extern void prom_unmapio(char *virt_addr, unsigned int num_bytes); |
62 | 62 | ||
63 | /* Device operations. */ | ||
64 | |||
65 | /* Open the device described by the passed string. Note, that the format | ||
66 | * of the string is different on V0 vs. V2->higher proms. The caller must | ||
67 | * know what he/she is doing! Returns the device descriptor, an int. | ||
68 | */ | ||
69 | extern int prom_devopen(char *device_string); | ||
70 | |||
71 | /* Close a previously opened device described by the passed integer | ||
72 | * descriptor. | ||
73 | */ | ||
74 | extern int prom_devclose(int device_handle); | ||
75 | |||
76 | /* Do a seek operation on the device described by the passed integer | ||
77 | * descriptor. | ||
78 | */ | ||
79 | extern void prom_seek(int device_handle, unsigned int seek_hival, | ||
80 | unsigned int seek_lowval); | ||
81 | |||
82 | /* Miscellaneous routines, don't really fit in any category per se. */ | 63 | /* Miscellaneous routines, don't really fit in any category per se. */ |
83 | 64 | ||
84 | /* Reboot the machine with the command line passed. */ | 65 | /* Reboot the machine with the command line passed. */ |
@@ -121,19 +102,8 @@ extern int prom_getrev(void); | |||
121 | /* Get the prom firmware revision. */ | 102 | /* Get the prom firmware revision. */ |
122 | extern int prom_getprev(void); | 103 | extern int prom_getprev(void); |
123 | 104 | ||
124 | /* Character operations to/from the console.... */ | 105 | /* Write a buffer of characters to the console. */ |
125 | 106 | extern void prom_console_write_buf(const char *buf, int len); | |
126 | /* Non-blocking get character from console. */ | ||
127 | extern int prom_nbgetchar(void); | ||
128 | |||
129 | /* Non-blocking put character to console. */ | ||
130 | extern int prom_nbputchar(char character); | ||
131 | |||
132 | /* Blocking get character from console. */ | ||
133 | extern char prom_getchar(void); | ||
134 | |||
135 | /* Blocking put character to console. */ | ||
136 | extern void prom_putchar(char character); | ||
137 | 107 | ||
138 | /* Prom's internal routines, don't use in kernel/boot code. */ | 108 | /* Prom's internal routines, don't use in kernel/boot code. */ |
139 | extern void prom_printf(const char *fmt, ...); | 109 | extern void prom_printf(const char *fmt, ...); |
@@ -238,7 +208,6 @@ extern int prom_node_has_property(phandle node, char *property); | |||
238 | extern int prom_setprop(phandle node, const char *prop_name, char *prop_value, | 208 | extern int prom_setprop(phandle node, const char *prop_name, char *prop_value, |
239 | int value_size); | 209 | int value_size); |
240 | 210 | ||
241 | extern phandle prom_pathtoinode(char *path); | ||
242 | extern phandle prom_inst2pkg(int); | 211 | extern phandle prom_inst2pkg(int); |
243 | 212 | ||
244 | /* Dorking with Bus ranges... */ | 213 | /* Dorking with Bus ranges... */ |
diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h index c9cc078e3e31..8cd0df34e82b 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h | |||
@@ -67,27 +67,6 @@ extern void prom_init(void *cif_handler, void *cif_stack); | |||
67 | /* Boot argument acquisition, returns the boot command line string. */ | 67 | /* Boot argument acquisition, returns the boot command line string. */ |
68 | extern char *prom_getbootargs(void); | 68 | extern char *prom_getbootargs(void); |
69 | 69 | ||
70 | /* Device utilities. */ | ||
71 | |||
72 | /* Device operations. */ | ||
73 | |||
74 | /* Open the device described by the passed string. Note, that the format | ||
75 | * of the string is different on V0 vs. V2->higher proms. The caller must | ||
76 | * know what he/she is doing! Returns the device descriptor, an int. | ||
77 | */ | ||
78 | extern int prom_devopen(const char *device_string); | ||
79 | |||
80 | /* Close a previously opened device described by the passed integer | ||
81 | * descriptor. | ||
82 | */ | ||
83 | extern int prom_devclose(int device_handle); | ||
84 | |||
85 | /* Do a seek operation on the device described by the passed integer | ||
86 | * descriptor. | ||
87 | */ | ||
88 | extern void prom_seek(int device_handle, unsigned int seek_hival, | ||
89 | unsigned int seek_lowval); | ||
90 | |||
91 | /* Miscellaneous routines, don't really fit in any category per se. */ | 70 | /* Miscellaneous routines, don't really fit in any category per se. */ |
92 | 71 | ||
93 | /* Reboot the machine with the command line passed. */ | 72 | /* Reboot the machine with the command line passed. */ |
@@ -109,33 +88,14 @@ extern void prom_halt(void) __attribute__ ((noreturn)); | |||
109 | /* Halt and power-off the machine. */ | 88 | /* Halt and power-off the machine. */ |
110 | extern void prom_halt_power_off(void) __attribute__ ((noreturn)); | 89 | extern void prom_halt_power_off(void) __attribute__ ((noreturn)); |
111 | 90 | ||
112 | /* Set the PROM 'sync' callback function to the passed function pointer. | ||
113 | * When the user gives the 'sync' command at the prom prompt while the | ||
114 | * kernel is still active, the prom will call this routine. | ||
115 | * | ||
116 | */ | ||
117 | typedef int (*callback_func_t)(long *cmd); | ||
118 | extern void prom_setcallback(callback_func_t func_ptr); | ||
119 | |||
120 | /* Acquire the IDPROM of the root node in the prom device tree. This | 91 | /* Acquire the IDPROM of the root node in the prom device tree. This |
121 | * gets passed a buffer where you would like it stuffed. The return value | 92 | * gets passed a buffer where you would like it stuffed. The return value |
122 | * is the format type of this idprom or 0xff on error. | 93 | * is the format type of this idprom or 0xff on error. |
123 | */ | 94 | */ |
124 | extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size); | 95 | extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size); |
125 | 96 | ||
126 | /* Character operations to/from the console.... */ | 97 | /* Write a buffer of characters to the console. */ |
127 | 98 | extern void prom_console_write_buf(const char *buf, int len); | |
128 | /* Non-blocking get character from console. */ | ||
129 | extern int prom_nbgetchar(void); | ||
130 | |||
131 | /* Non-blocking put character to console. */ | ||
132 | extern int prom_nbputchar(char character); | ||
133 | |||
134 | /* Blocking get character from console. */ | ||
135 | extern char prom_getchar(void); | ||
136 | |||
137 | /* Blocking put character to console. */ | ||
138 | extern void prom_putchar(char character); | ||
139 | 99 | ||
140 | /* Prom's internal routines, don't use in kernel/boot code. */ | 100 | /* Prom's internal routines, don't use in kernel/boot code. */ |
141 | extern void prom_printf(const char *fmt, ...); | 101 | extern void prom_printf(const char *fmt, ...); |
@@ -279,9 +239,7 @@ extern phandle prom_finddevice(const char *name); | |||
279 | extern int prom_setprop(phandle node, const char *prop_name, char *prop_value, | 239 | extern int prom_setprop(phandle node, const char *prop_name, char *prop_value, |
280 | int value_size); | 240 | int value_size); |
281 | 241 | ||
282 | extern phandle prom_pathtoinode(const char *path); | ||
283 | extern phandle prom_inst2pkg(int); | 242 | extern phandle prom_inst2pkg(int); |
284 | extern int prom_service_exists(const char *service_name); | ||
285 | extern void prom_sun4v_guest_soft_state(void); | 243 | extern void prom_sun4v_guest_soft_state(void); |
286 | 244 | ||
287 | extern int prom_ihandle2path(int handle, char *buffer, int bufsize); | 245 | extern int prom_ihandle2path(int handle, char *buffer, int bufsize); |
diff --git a/arch/sparc/kernel/leon_kernel.c b/arch/sparc/kernel/leon_kernel.c index 2d51527d810f..f01c42661ee5 100644 --- a/arch/sparc/kernel/leon_kernel.c +++ b/arch/sparc/kernel/leon_kernel.c | |||
@@ -114,7 +114,7 @@ void __init leon_init_timers(irq_handler_t counter_fn) | |||
114 | if (leon3_gptimer_regs && leon3_irqctrl_regs) { | 114 | if (leon3_gptimer_regs && leon3_irqctrl_regs) { |
115 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0); | 115 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].val, 0); |
116 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld, | 116 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].rld, |
117 | (((1000000 / 100) - 1))); | 117 | (((1000000 / HZ) - 1))); |
118 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0); | 118 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[0].ctrl, 0); |
119 | 119 | ||
120 | #ifdef CONFIG_SMP | 120 | #ifdef CONFIG_SMP |
@@ -128,7 +128,7 @@ void __init leon_init_timers(irq_handler_t counter_fn) | |||
128 | } | 128 | } |
129 | 129 | ||
130 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].val, 0); | 130 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].val, 0); |
131 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/100) - 1))); | 131 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].rld, (((1000000/HZ) - 1))); |
132 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0); | 132 | LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0); |
133 | # endif | 133 | # endif |
134 | 134 | ||
diff --git a/arch/sparc/prom/Makefile b/arch/sparc/prom/Makefile index 1b8c073adb44..816c0fa12dc0 100644 --- a/arch/sparc/prom/Makefile +++ b/arch/sparc/prom/Makefile | |||
@@ -6,7 +6,6 @@ ccflags := -Werror | |||
6 | 6 | ||
7 | lib-y := bootstr_$(BITS).o | 7 | lib-y := bootstr_$(BITS).o |
8 | lib-$(CONFIG_SPARC32) += devmap.o | 8 | lib-$(CONFIG_SPARC32) += devmap.o |
9 | lib-y += devops_$(BITS).o | ||
10 | lib-y += init_$(BITS).o | 9 | lib-y += init_$(BITS).o |
11 | lib-$(CONFIG_SPARC32) += memory.o | 10 | lib-$(CONFIG_SPARC32) += memory.o |
12 | lib-y += misc_$(BITS).o | 11 | lib-y += misc_$(BITS).o |
diff --git a/arch/sparc/prom/console_32.c b/arch/sparc/prom/console_32.c index 5340264b78f5..48863108a44c 100644 --- a/arch/sparc/prom/console_32.c +++ b/arch/sparc/prom/console_32.c | |||
@@ -16,63 +16,26 @@ | |||
16 | 16 | ||
17 | extern void restore_current(void); | 17 | extern void restore_current(void); |
18 | 18 | ||
19 | /* Non blocking get character from console input device, returns -1 | ||
20 | * if no input was taken. This can be used for polling. | ||
21 | */ | ||
22 | int | ||
23 | prom_nbgetchar(void) | ||
24 | { | ||
25 | static char inc; | ||
26 | int i = -1; | ||
27 | unsigned long flags; | ||
28 | |||
29 | spin_lock_irqsave(&prom_lock, flags); | ||
30 | switch(prom_vers) { | ||
31 | case PROM_V0: | ||
32 | i = (*(romvec->pv_nbgetchar))(); | ||
33 | break; | ||
34 | case PROM_V2: | ||
35 | case PROM_V3: | ||
36 | if( (*(romvec->pv_v2devops).v2_dev_read)(*romvec->pv_v2bootargs.fd_stdin , &inc, 0x1) == 1) { | ||
37 | i = inc; | ||
38 | } else { | ||
39 | i = -1; | ||
40 | } | ||
41 | break; | ||
42 | default: | ||
43 | i = -1; | ||
44 | break; | ||
45 | }; | ||
46 | restore_current(); | ||
47 | spin_unlock_irqrestore(&prom_lock, flags); | ||
48 | return i; /* Ugh, we could spin forever on unsupported proms ;( */ | ||
49 | } | ||
50 | |||
51 | /* Non blocking put character to console device, returns -1 if | 19 | /* Non blocking put character to console device, returns -1 if |
52 | * unsuccessful. | 20 | * unsuccessful. |
53 | */ | 21 | */ |
54 | int | 22 | static int prom_nbputchar(const char *buf) |
55 | prom_nbputchar(char c) | ||
56 | { | 23 | { |
57 | static char outc; | ||
58 | unsigned long flags; | 24 | unsigned long flags; |
59 | int i = -1; | 25 | int i = -1; |
60 | 26 | ||
61 | spin_lock_irqsave(&prom_lock, flags); | 27 | spin_lock_irqsave(&prom_lock, flags); |
62 | switch(prom_vers) { | 28 | switch(prom_vers) { |
63 | case PROM_V0: | 29 | case PROM_V0: |
64 | i = (*(romvec->pv_nbputchar))(c); | 30 | i = (*(romvec->pv_nbputchar))(*buf); |
65 | break; | 31 | break; |
66 | case PROM_V2: | 32 | case PROM_V2: |
67 | case PROM_V3: | 33 | case PROM_V3: |
68 | outc = c; | 34 | if ((*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout, |
69 | if( (*(romvec->pv_v2devops).v2_dev_write)(*romvec->pv_v2bootargs.fd_stdout, &outc, 0x1) == 1) | 35 | buf, 0x1) == 1) |
70 | i = 0; | 36 | i = 0; |
71 | else | ||
72 | i = -1; | ||
73 | break; | 37 | break; |
74 | default: | 38 | default: |
75 | i = -1; | ||
76 | break; | 39 | break; |
77 | }; | 40 | }; |
78 | restore_current(); | 41 | restore_current(); |
@@ -80,18 +43,14 @@ prom_nbputchar(char c) | |||
80 | return i; /* Ugh, we could spin forever on unsupported proms ;( */ | 43 | return i; /* Ugh, we could spin forever on unsupported proms ;( */ |
81 | } | 44 | } |
82 | 45 | ||
83 | /* Blocking version of get character routine above. */ | 46 | void prom_console_write_buf(const char *buf, int len) |
84 | char | ||
85 | prom_getchar(void) | ||
86 | { | 47 | { |
87 | int character; | 48 | while (len) { |
88 | while((character = prom_nbgetchar()) == -1) ; | 49 | int n = prom_nbputchar(buf); |
89 | return (char) character; | 50 | if (n) |
51 | continue; | ||
52 | len--; | ||
53 | buf++; | ||
54 | } | ||
90 | } | 55 | } |
91 | 56 | ||
92 | /* Blocking version of put character routine above. */ | ||
93 | void | ||
94 | prom_putchar(char c) | ||
95 | { | ||
96 | while(prom_nbputchar(c) == -1) ; | ||
97 | } | ||
diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c index 10322dc2f557..ed39e75828bd 100644 --- a/arch/sparc/prom/console_64.c +++ b/arch/sparc/prom/console_64.c | |||
@@ -15,85 +15,34 @@ | |||
15 | 15 | ||
16 | extern int prom_stdin, prom_stdout; | 16 | extern int prom_stdin, prom_stdout; |
17 | 17 | ||
18 | /* Non blocking get character from console input device, returns -1 | 18 | static int __prom_console_write_buf(const char *buf, int len) |
19 | * if no input was taken. This can be used for polling. | ||
20 | */ | ||
21 | inline int | ||
22 | prom_nbgetchar(void) | ||
23 | { | ||
24 | unsigned long args[7]; | ||
25 | char inc; | ||
26 | |||
27 | args[0] = (unsigned long) "read"; | ||
28 | args[1] = 3; | ||
29 | args[2] = 1; | ||
30 | args[3] = (unsigned int) prom_stdin; | ||
31 | args[4] = (unsigned long) &inc; | ||
32 | args[5] = 1; | ||
33 | args[6] = (unsigned long) -1; | ||
34 | |||
35 | p1275_cmd_direct(args); | ||
36 | |||
37 | if (args[6] == 1) | ||
38 | return inc; | ||
39 | return -1; | ||
40 | } | ||
41 | |||
42 | /* Non blocking put character to console device, returns -1 if | ||
43 | * unsuccessful. | ||
44 | */ | ||
45 | inline int | ||
46 | prom_nbputchar(char c) | ||
47 | { | 19 | { |
48 | unsigned long args[7]; | 20 | unsigned long args[7]; |
49 | char outc; | 21 | int ret; |
50 | |||
51 | outc = c; | ||
52 | 22 | ||
53 | args[0] = (unsigned long) "write"; | 23 | args[0] = (unsigned long) "write"; |
54 | args[1] = 3; | 24 | args[1] = 3; |
55 | args[2] = 1; | 25 | args[2] = 1; |
56 | args[3] = (unsigned int) prom_stdout; | 26 | args[3] = (unsigned int) prom_stdout; |
57 | args[4] = (unsigned long) &outc; | 27 | args[4] = (unsigned long) buf; |
58 | args[5] = 1; | 28 | args[5] = (unsigned int) len; |
59 | args[6] = (unsigned long) -1; | 29 | args[6] = (unsigned long) -1; |
60 | 30 | ||
61 | p1275_cmd_direct(args); | 31 | p1275_cmd_direct(args); |
62 | 32 | ||
63 | if (args[6] == 1) | 33 | ret = (int) args[6]; |
64 | return 0; | 34 | if (ret < 0) |
65 | else | ||
66 | return -1; | 35 | return -1; |
36 | return ret; | ||
67 | } | 37 | } |
68 | 38 | ||
69 | /* Blocking version of get character routine above. */ | 39 | void prom_console_write_buf(const char *buf, int len) |
70 | char | ||
71 | prom_getchar(void) | ||
72 | { | ||
73 | int character; | ||
74 | while((character = prom_nbgetchar()) == -1) ; | ||
75 | return (char) character; | ||
76 | } | ||
77 | |||
78 | /* Blocking version of put character routine above. */ | ||
79 | void | ||
80 | prom_putchar(char c) | ||
81 | { | 40 | { |
82 | prom_nbputchar(c); | 41 | while (len) { |
83 | } | 42 | int n = __prom_console_write_buf(buf, len); |
84 | 43 | if (n < 0) | |
85 | void | 44 | continue; |
86 | prom_puts(const char *s, int len) | 45 | len -= n; |
87 | { | 46 | buf += len; |
88 | unsigned long args[7]; | 47 | } |
89 | |||
90 | args[0] = (unsigned long) "write"; | ||
91 | args[1] = 3; | ||
92 | args[2] = 1; | ||
93 | args[3] = (unsigned int) prom_stdout; | ||
94 | args[4] = (unsigned long) s; | ||
95 | args[5] = len; | ||
96 | args[6] = (unsigned long) -1; | ||
97 | |||
98 | p1275_cmd_direct(args); | ||
99 | } | 48 | } |
diff --git a/arch/sparc/prom/devops_32.c b/arch/sparc/prom/devops_32.c deleted file mode 100644 index 9c5d4687242a..000000000000 --- a/arch/sparc/prom/devops_32.c +++ /dev/null | |||
@@ -1,87 +0,0 @@ | |||
1 | /* | ||
2 | * devops.c: Device operations using the PROM. | ||
3 | * | ||
4 | * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) | ||
5 | */ | ||
6 | #include <linux/types.h> | ||
7 | #include <linux/kernel.h> | ||
8 | #include <linux/sched.h> | ||
9 | |||
10 | #include <asm/openprom.h> | ||
11 | #include <asm/oplib.h> | ||
12 | |||
13 | extern void restore_current(void); | ||
14 | |||
15 | /* Open the device described by the string 'dstr'. Returns the handle | ||
16 | * to that device used for subsequent operations on that device. | ||
17 | * Returns -1 on failure. | ||
18 | */ | ||
19 | int | ||
20 | prom_devopen(char *dstr) | ||
21 | { | ||
22 | int handle; | ||
23 | unsigned long flags; | ||
24 | spin_lock_irqsave(&prom_lock, flags); | ||
25 | switch(prom_vers) { | ||
26 | case PROM_V0: | ||
27 | handle = (*(romvec->pv_v0devops.v0_devopen))(dstr); | ||
28 | if(handle == 0) handle = -1; | ||
29 | break; | ||
30 | case PROM_V2: | ||
31 | case PROM_V3: | ||
32 | handle = (*(romvec->pv_v2devops.v2_dev_open))(dstr); | ||
33 | break; | ||
34 | default: | ||
35 | handle = -1; | ||
36 | break; | ||
37 | }; | ||
38 | restore_current(); | ||
39 | spin_unlock_irqrestore(&prom_lock, flags); | ||
40 | |||
41 | return handle; | ||
42 | } | ||
43 | |||
44 | /* Close the device described by device handle 'dhandle'. */ | ||
45 | int | ||
46 | prom_devclose(int dhandle) | ||
47 | { | ||
48 | unsigned long flags; | ||
49 | spin_lock_irqsave(&prom_lock, flags); | ||
50 | switch(prom_vers) { | ||
51 | case PROM_V0: | ||
52 | (*(romvec->pv_v0devops.v0_devclose))(dhandle); | ||
53 | break; | ||
54 | case PROM_V2: | ||
55 | case PROM_V3: | ||
56 | (*(romvec->pv_v2devops.v2_dev_close))(dhandle); | ||
57 | break; | ||
58 | default: | ||
59 | break; | ||
60 | }; | ||
61 | restore_current(); | ||
62 | spin_unlock_irqrestore(&prom_lock, flags); | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | /* Seek to specified location described by 'seekhi' and 'seeklo' | ||
67 | * for device 'dhandle'. | ||
68 | */ | ||
69 | void | ||
70 | prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo) | ||
71 | { | ||
72 | unsigned long flags; | ||
73 | spin_lock_irqsave(&prom_lock, flags); | ||
74 | switch(prom_vers) { | ||
75 | case PROM_V0: | ||
76 | (*(romvec->pv_v0devops.v0_seekdev))(dhandle, seekhi, seeklo); | ||
77 | break; | ||
78 | case PROM_V2: | ||
79 | case PROM_V3: | ||
80 | (*(romvec->pv_v2devops.v2_dev_seek))(dhandle, seekhi, seeklo); | ||
81 | break; | ||
82 | default: | ||
83 | break; | ||
84 | }; | ||
85 | restore_current(); | ||
86 | spin_unlock_irqrestore(&prom_lock, flags); | ||
87 | } | ||
diff --git a/arch/sparc/prom/devops_64.c b/arch/sparc/prom/devops_64.c deleted file mode 100644 index a017119e7ef1..000000000000 --- a/arch/sparc/prom/devops_64.c +++ /dev/null | |||
@@ -1,67 +0,0 @@ | |||
1 | /* | ||
2 | * devops.c: Device operations using the PROM. | ||
3 | * | ||
4 | * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) | ||
5 | * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | ||
6 | */ | ||
7 | #include <linux/types.h> | ||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/sched.h> | ||
10 | |||
11 | #include <asm/openprom.h> | ||
12 | #include <asm/oplib.h> | ||
13 | |||
14 | /* Open the device described by the string 'dstr'. Returns the handle | ||
15 | * to that device used for subsequent operations on that device. | ||
16 | * Returns 0 on failure. | ||
17 | */ | ||
18 | int | ||
19 | prom_devopen(const char *dstr) | ||
20 | { | ||
21 | unsigned long args[5]; | ||
22 | |||
23 | args[0] = (unsigned long) "open"; | ||
24 | args[1] = 1; | ||
25 | args[2] = 1; | ||
26 | args[3] = (unsigned long) dstr; | ||
27 | args[4] = (unsigned long) -1; | ||
28 | |||
29 | p1275_cmd_direct(args); | ||
30 | |||
31 | return (int) args[4]; | ||
32 | } | ||
33 | |||
34 | /* Close the device described by device handle 'dhandle'. */ | ||
35 | int | ||
36 | prom_devclose(int dhandle) | ||
37 | { | ||
38 | unsigned long args[4]; | ||
39 | |||
40 | args[0] = (unsigned long) "close"; | ||
41 | args[1] = 1; | ||
42 | args[2] = 0; | ||
43 | args[3] = (unsigned int) dhandle; | ||
44 | |||
45 | p1275_cmd_direct(args); | ||
46 | |||
47 | return 0; | ||
48 | } | ||
49 | |||
50 | /* Seek to specified location described by 'seekhi' and 'seeklo' | ||
51 | * for device 'dhandle'. | ||
52 | */ | ||
53 | void | ||
54 | prom_seek(int dhandle, unsigned int seekhi, unsigned int seeklo) | ||
55 | { | ||
56 | unsigned long args[7]; | ||
57 | |||
58 | args[0] = (unsigned long) "seek"; | ||
59 | args[1] = 3; | ||
60 | args[2] = 1; | ||
61 | args[3] = (unsigned int) dhandle; | ||
62 | args[4] = seekhi; | ||
63 | args[5] = seeklo; | ||
64 | args[6] = (unsigned long) -1; | ||
65 | |||
66 | p1275_cmd_direct(args); | ||
67 | } | ||
diff --git a/arch/sparc/prom/misc_64.c b/arch/sparc/prom/misc_64.c index d24bc44e361e..e4f31d4d3715 100644 --- a/arch/sparc/prom/misc_64.c +++ b/arch/sparc/prom/misc_64.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <asm/system.h> | 18 | #include <asm/system.h> |
19 | #include <asm/ldc.h> | 19 | #include <asm/ldc.h> |
20 | 20 | ||
21 | int prom_service_exists(const char *service_name) | 21 | static int prom_service_exists(const char *service_name) |
22 | { | 22 | { |
23 | unsigned long args[5]; | 23 | unsigned long args[5]; |
24 | 24 | ||
@@ -150,20 +150,6 @@ void prom_halt_power_off(void) | |||
150 | prom_halt(); | 150 | prom_halt(); |
151 | } | 151 | } |
152 | 152 | ||
153 | /* Set prom sync handler to call function 'funcp'. */ | ||
154 | void prom_setcallback(callback_func_t funcp) | ||
155 | { | ||
156 | unsigned long args[5]; | ||
157 | if (!funcp) | ||
158 | return; | ||
159 | args[0] = (unsigned long) "set-callback"; | ||
160 | args[1] = 1; | ||
161 | args[2] = 1; | ||
162 | args[3] = (unsigned long) funcp; | ||
163 | args[4] = (unsigned long) -1; | ||
164 | p1275_cmd_direct(args); | ||
165 | } | ||
166 | |||
167 | /* Get the idprom and stuff it into buffer 'idbuf'. Returns the | 153 | /* Get the idprom and stuff it into buffer 'idbuf'. Returns the |
168 | * format type. 'num_bytes' is the number of bytes that your idbuf | 154 | * format type. 'num_bytes' is the number of bytes that your idbuf |
169 | * has space for. Returns 0xff on error. | 155 | * has space for. Returns 0xff on error. |
diff --git a/arch/sparc/prom/printf.c b/arch/sparc/prom/printf.c index ca869266b9f3..d9682f06b3b0 100644 --- a/arch/sparc/prom/printf.c +++ b/arch/sparc/prom/printf.c | |||
@@ -15,22 +15,45 @@ | |||
15 | 15 | ||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/compiler.h> | 17 | #include <linux/compiler.h> |
18 | #include <linux/spinlock.h> | ||
18 | 19 | ||
19 | #include <asm/openprom.h> | 20 | #include <asm/openprom.h> |
20 | #include <asm/oplib.h> | 21 | #include <asm/oplib.h> |
21 | 22 | ||
23 | #define CONSOLE_WRITE_BUF_SIZE 1024 | ||
24 | |||
22 | static char ppbuf[1024]; | 25 | static char ppbuf[1024]; |
26 | static char console_write_buf[CONSOLE_WRITE_BUF_SIZE]; | ||
27 | static DEFINE_RAW_SPINLOCK(console_write_lock); | ||
23 | 28 | ||
24 | void notrace prom_write(const char *buf, unsigned int n) | 29 | void notrace prom_write(const char *buf, unsigned int n) |
25 | { | 30 | { |
26 | char ch; | 31 | unsigned int dest_len; |
32 | unsigned long flags; | ||
33 | char *dest; | ||
34 | |||
35 | dest = console_write_buf; | ||
36 | raw_spin_lock_irqsave(&console_write_lock, flags); | ||
27 | 37 | ||
28 | while (n != 0) { | 38 | dest_len = 0; |
29 | --n; | 39 | while (n-- != 0) { |
30 | if ((ch = *buf++) == '\n') | 40 | char ch = *buf++; |
31 | prom_putchar('\r'); | 41 | if (ch == '\n') { |
32 | prom_putchar(ch); | 42 | *dest++ = '\r'; |
43 | dest_len++; | ||
44 | } | ||
45 | *dest++ = ch; | ||
46 | dest_len++; | ||
47 | if (dest_len >= CONSOLE_WRITE_BUF_SIZE - 1) { | ||
48 | prom_console_write_buf(console_write_buf, dest_len); | ||
49 | dest = console_write_buf; | ||
50 | dest_len = 0; | ||
51 | } | ||
33 | } | 52 | } |
53 | if (dest_len) | ||
54 | prom_console_write_buf(console_write_buf, dest_len); | ||
55 | |||
56 | raw_spin_unlock_irqrestore(&console_write_lock, flags); | ||
34 | } | 57 | } |
35 | 58 | ||
36 | void notrace prom_printf(const char *fmt, ...) | 59 | void notrace prom_printf(const char *fmt, ...) |
diff --git a/arch/sparc/prom/tree_32.c b/arch/sparc/prom/tree_32.c index 63e08e149774..535e2e69ac1d 100644 --- a/arch/sparc/prom/tree_32.c +++ b/arch/sparc/prom/tree_32.c | |||
@@ -342,19 +342,3 @@ phandle prom_inst2pkg(int inst) | |||
342 | if (node == -1) return 0; | 342 | if (node == -1) return 0; |
343 | return node; | 343 | return node; |
344 | } | 344 | } |
345 | |||
346 | /* Return 'node' assigned to a particular prom 'path' | ||
347 | * FIXME: Should work for v0 as well | ||
348 | */ | ||
349 | phandle prom_pathtoinode(char *path) | ||
350 | { | ||
351 | phandle node; | ||
352 | int inst; | ||
353 | |||
354 | inst = prom_devopen (path); | ||
355 | if (inst == -1) return 0; | ||
356 | node = prom_inst2pkg (inst); | ||
357 | prom_devclose (inst); | ||
358 | if (node == -1) return 0; | ||
359 | return node; | ||
360 | } | ||
diff --git a/arch/sparc/prom/tree_64.c b/arch/sparc/prom/tree_64.c index 691be68932f8..d93660048376 100644 --- a/arch/sparc/prom/tree_64.c +++ b/arch/sparc/prom/tree_64.c | |||
@@ -374,24 +374,6 @@ inline phandle prom_inst2pkg(int inst) | |||
374 | return node; | 374 | return node; |
375 | } | 375 | } |
376 | 376 | ||
377 | /* Return 'node' assigned to a particular prom 'path' | ||
378 | * FIXME: Should work for v0 as well | ||
379 | */ | ||
380 | phandle prom_pathtoinode(const char *path) | ||
381 | { | ||
382 | phandle node; | ||
383 | int inst; | ||
384 | |||
385 | inst = prom_devopen (path); | ||
386 | if (inst == 0) | ||
387 | return 0; | ||
388 | node = prom_inst2pkg(inst); | ||
389 | prom_devclose(inst); | ||
390 | if (node == -1) | ||
391 | return 0; | ||
392 | return node; | ||
393 | } | ||
394 | |||
395 | int prom_ihandle2path(int handle, char *buffer, int bufsize) | 377 | int prom_ihandle2path(int handle, char *buffer, int bufsize) |
396 | { | 378 | { |
397 | unsigned long args[7]; | 379 | unsigned long args[7]; |
diff --git a/arch/tile/include/asm/signal.h b/arch/tile/include/asm/signal.h index c1ee1d61d44c..81d92a45cd4b 100644 --- a/arch/tile/include/asm/signal.h +++ b/arch/tile/include/asm/signal.h | |||
@@ -25,7 +25,7 @@ | |||
25 | 25 | ||
26 | #if defined(__KERNEL__) && !defined(__ASSEMBLY__) | 26 | #if defined(__KERNEL__) && !defined(__ASSEMBLY__) |
27 | struct pt_regs; | 27 | struct pt_regs; |
28 | int restore_sigcontext(struct pt_regs *, struct sigcontext __user *, long *); | 28 | int restore_sigcontext(struct pt_regs *, struct sigcontext __user *); |
29 | int setup_sigcontext(struct sigcontext __user *, struct pt_regs *); | 29 | int setup_sigcontext(struct sigcontext __user *, struct pt_regs *); |
30 | void do_signal(struct pt_regs *regs); | 30 | void do_signal(struct pt_regs *regs); |
31 | #endif | 31 | #endif |
diff --git a/arch/tile/kernel/compat_signal.c b/arch/tile/kernel/compat_signal.c index 543d6a33aa26..dbb0dfc7bece 100644 --- a/arch/tile/kernel/compat_signal.c +++ b/arch/tile/kernel/compat_signal.c | |||
@@ -290,12 +290,12 @@ long compat_sys_sigaltstack(const struct compat_sigaltstack __user *uss_ptr, | |||
290 | return ret; | 290 | return ret; |
291 | } | 291 | } |
292 | 292 | ||
293 | /* The assembly shim for this function arranges to ignore the return value. */ | ||
293 | long compat_sys_rt_sigreturn(struct pt_regs *regs) | 294 | long compat_sys_rt_sigreturn(struct pt_regs *regs) |
294 | { | 295 | { |
295 | struct compat_rt_sigframe __user *frame = | 296 | struct compat_rt_sigframe __user *frame = |
296 | (struct compat_rt_sigframe __user *) compat_ptr(regs->sp); | 297 | (struct compat_rt_sigframe __user *) compat_ptr(regs->sp); |
297 | sigset_t set; | 298 | sigset_t set; |
298 | long r0; | ||
299 | 299 | ||
300 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | 300 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) |
301 | goto badframe; | 301 | goto badframe; |
@@ -308,13 +308,13 @@ long compat_sys_rt_sigreturn(struct pt_regs *regs) | |||
308 | recalc_sigpending(); | 308 | recalc_sigpending(); |
309 | spin_unlock_irq(¤t->sighand->siglock); | 309 | spin_unlock_irq(¤t->sighand->siglock); |
310 | 310 | ||
311 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0)) | 311 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) |
312 | goto badframe; | 312 | goto badframe; |
313 | 313 | ||
314 | if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0) | 314 | if (compat_sys_sigaltstack(&frame->uc.uc_stack, NULL, regs) != 0) |
315 | goto badframe; | 315 | goto badframe; |
316 | 316 | ||
317 | return r0; | 317 | return 0; |
318 | 318 | ||
319 | badframe: | 319 | badframe: |
320 | force_sig(SIGSEGV, current); | 320 | force_sig(SIGSEGV, current); |
diff --git a/arch/tile/kernel/intvec_32.S b/arch/tile/kernel/intvec_32.S index f5821626247f..5eed4a02bf62 100644 --- a/arch/tile/kernel/intvec_32.S +++ b/arch/tile/kernel/intvec_32.S | |||
@@ -1342,8 +1342,8 @@ handle_syscall: | |||
1342 | lw r20, r20 | 1342 | lw r20, r20 |
1343 | 1343 | ||
1344 | /* Jump to syscall handler. */ | 1344 | /* Jump to syscall handler. */ |
1345 | jalr r20; .Lhandle_syscall_link: | 1345 | jalr r20 |
1346 | FEEDBACK_REENTER(handle_syscall) | 1346 | .Lhandle_syscall_link: /* value of "lr" after "jalr r20" above */ |
1347 | 1347 | ||
1348 | /* | 1348 | /* |
1349 | * Write our r0 onto the stack so it gets restored instead | 1349 | * Write our r0 onto the stack so it gets restored instead |
@@ -1352,6 +1352,9 @@ handle_syscall: | |||
1352 | PTREGS_PTR(r29, PTREGS_OFFSET_REG(0)) | 1352 | PTREGS_PTR(r29, PTREGS_OFFSET_REG(0)) |
1353 | sw r29, r0 | 1353 | sw r29, r0 |
1354 | 1354 | ||
1355 | .Lsyscall_sigreturn_skip: | ||
1356 | FEEDBACK_REENTER(handle_syscall) | ||
1357 | |||
1355 | /* Do syscall trace again, if requested. */ | 1358 | /* Do syscall trace again, if requested. */ |
1356 | lw r30, r31 | 1359 | lw r30, r31 |
1357 | andi r30, r30, _TIF_SYSCALL_TRACE | 1360 | andi r30, r30, _TIF_SYSCALL_TRACE |
@@ -1536,9 +1539,24 @@ STD_ENTRY_LOCAL(bad_intr) | |||
1536 | }; \ | 1539 | }; \ |
1537 | STD_ENDPROC(_##x) | 1540 | STD_ENDPROC(_##x) |
1538 | 1541 | ||
1542 | /* | ||
1543 | * Special-case sigreturn to not write r0 to the stack on return. | ||
1544 | * This is technically more efficient, but it also avoids difficulties | ||
1545 | * in the 64-bit OS when handling 32-bit compat code, since we must not | ||
1546 | * sign-extend r0 for the sigreturn return-value case. | ||
1547 | */ | ||
1548 | #define PTREGS_SYSCALL_SIGRETURN(x, reg) \ | ||
1549 | STD_ENTRY(_##x); \ | ||
1550 | addli lr, lr, .Lsyscall_sigreturn_skip - .Lhandle_syscall_link; \ | ||
1551 | { \ | ||
1552 | PTREGS_PTR(reg, PTREGS_OFFSET_BASE); \ | ||
1553 | j x \ | ||
1554 | }; \ | ||
1555 | STD_ENDPROC(_##x) | ||
1556 | |||
1539 | PTREGS_SYSCALL(sys_execve, r3) | 1557 | PTREGS_SYSCALL(sys_execve, r3) |
1540 | PTREGS_SYSCALL(sys_sigaltstack, r2) | 1558 | PTREGS_SYSCALL(sys_sigaltstack, r2) |
1541 | PTREGS_SYSCALL(sys_rt_sigreturn, r0) | 1559 | PTREGS_SYSCALL_SIGRETURN(sys_rt_sigreturn, r0) |
1542 | PTREGS_SYSCALL(sys_cmpxchg_badaddr, r1) | 1560 | PTREGS_SYSCALL(sys_cmpxchg_badaddr, r1) |
1543 | 1561 | ||
1544 | /* Save additional callee-saves to pt_regs, put address in r4 and jump. */ | 1562 | /* Save additional callee-saves to pt_regs, put address in r4 and jump. */ |
diff --git a/arch/tile/kernel/process.c b/arch/tile/kernel/process.c index 8430f45daea6..e90eb53173b0 100644 --- a/arch/tile/kernel/process.c +++ b/arch/tile/kernel/process.c | |||
@@ -212,6 +212,13 @@ int copy_thread(unsigned long clone_flags, unsigned long sp, | |||
212 | childregs->sp = sp; /* override with new user stack pointer */ | 212 | childregs->sp = sp; /* override with new user stack pointer */ |
213 | 213 | ||
214 | /* | 214 | /* |
215 | * If CLONE_SETTLS is set, set "tp" in the new task to "r4", | ||
216 | * which is passed in as arg #5 to sys_clone(). | ||
217 | */ | ||
218 | if (clone_flags & CLONE_SETTLS) | ||
219 | childregs->tp = regs->regs[4]; | ||
220 | |||
221 | /* | ||
215 | * Copy the callee-saved registers from the passed pt_regs struct | 222 | * Copy the callee-saved registers from the passed pt_regs struct |
216 | * into the context-switch callee-saved registers area. | 223 | * into the context-switch callee-saved registers area. |
217 | * This way when we start the interrupt-return sequence, the | 224 | * This way when we start the interrupt-return sequence, the |
@@ -539,6 +546,7 @@ struct task_struct *__sched _switch_to(struct task_struct *prev, | |||
539 | return __switch_to(prev, next, next_current_ksp0(next)); | 546 | return __switch_to(prev, next, next_current_ksp0(next)); |
540 | } | 547 | } |
541 | 548 | ||
549 | /* Note there is an implicit fifth argument if (clone_flags & CLONE_SETTLS). */ | ||
542 | SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, | 550 | SYSCALL_DEFINE5(clone, unsigned long, clone_flags, unsigned long, newsp, |
543 | void __user *, parent_tidptr, void __user *, child_tidptr, | 551 | void __user *, parent_tidptr, void __user *, child_tidptr, |
544 | struct pt_regs *, regs) | 552 | struct pt_regs *, regs) |
diff --git a/arch/tile/kernel/signal.c b/arch/tile/kernel/signal.c index 757407e36696..1260321155f1 100644 --- a/arch/tile/kernel/signal.c +++ b/arch/tile/kernel/signal.c | |||
@@ -52,7 +52,7 @@ SYSCALL_DEFINE3(sigaltstack, const stack_t __user *, uss, | |||
52 | */ | 52 | */ |
53 | 53 | ||
54 | int restore_sigcontext(struct pt_regs *regs, | 54 | int restore_sigcontext(struct pt_regs *regs, |
55 | struct sigcontext __user *sc, long *pr0) | 55 | struct sigcontext __user *sc) |
56 | { | 56 | { |
57 | int err = 0; | 57 | int err = 0; |
58 | int i; | 58 | int i; |
@@ -75,17 +75,15 @@ int restore_sigcontext(struct pt_regs *regs, | |||
75 | 75 | ||
76 | regs->faultnum = INT_SWINT_1_SIGRETURN; | 76 | regs->faultnum = INT_SWINT_1_SIGRETURN; |
77 | 77 | ||
78 | err |= __get_user(*pr0, &sc->gregs[0]); | ||
79 | return err; | 78 | return err; |
80 | } | 79 | } |
81 | 80 | ||
82 | /* sigreturn() returns long since it restores r0 in the interrupted code. */ | 81 | /* The assembly shim for this function arranges to ignore the return value. */ |
83 | SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs) | 82 | SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs) |
84 | { | 83 | { |
85 | struct rt_sigframe __user *frame = | 84 | struct rt_sigframe __user *frame = |
86 | (struct rt_sigframe __user *)(regs->sp); | 85 | (struct rt_sigframe __user *)(regs->sp); |
87 | sigset_t set; | 86 | sigset_t set; |
88 | long r0; | ||
89 | 87 | ||
90 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | 88 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) |
91 | goto badframe; | 89 | goto badframe; |
@@ -98,13 +96,13 @@ SYSCALL_DEFINE1(rt_sigreturn, struct pt_regs *, regs) | |||
98 | recalc_sigpending(); | 96 | recalc_sigpending(); |
99 | spin_unlock_irq(¤t->sighand->siglock); | 97 | spin_unlock_irq(¤t->sighand->siglock); |
100 | 98 | ||
101 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0)) | 99 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) |
102 | goto badframe; | 100 | goto badframe; |
103 | 101 | ||
104 | if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT) | 102 | if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->sp) == -EFAULT) |
105 | goto badframe; | 103 | goto badframe; |
106 | 104 | ||
107 | return r0; | 105 | return 0; |
108 | 106 | ||
109 | badframe: | 107 | badframe: |
110 | force_sig(SIGSEGV, current); | 108 | force_sig(SIGSEGV, current); |
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index 23f315c9f215..325c05294fc4 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c | |||
@@ -355,7 +355,7 @@ asmlinkage void decompress_kernel(void *rmode, memptr heap, | |||
355 | if (heap > 0x3fffffffffffUL) | 355 | if (heap > 0x3fffffffffffUL) |
356 | error("Destination address too large"); | 356 | error("Destination address too large"); |
357 | #else | 357 | #else |
358 | if (heap > ((-__PAGE_OFFSET-(512<<20)-1) & 0x7fffffff)) | 358 | if (heap > ((-__PAGE_OFFSET-(128<<20)-1) & 0x7fffffff)) |
359 | error("Destination address too large"); | 359 | error("Destination address too large"); |
360 | #endif | 360 | #endif |
361 | #ifndef CONFIG_RELOCATABLE | 361 | #ifndef CONFIG_RELOCATABLE |
diff --git a/arch/x86/crypto/ghash-clmulni-intel_glue.c b/arch/x86/crypto/ghash-clmulni-intel_glue.c index cbcc8d8ea93a..7a6e68e4f748 100644 --- a/arch/x86/crypto/ghash-clmulni-intel_glue.c +++ b/arch/x86/crypto/ghash-clmulni-intel_glue.c | |||
@@ -10,6 +10,7 @@ | |||
10 | * by the Free Software Foundation. | 10 | * by the Free Software Foundation. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/err.h> | ||
13 | #include <linux/module.h> | 14 | #include <linux/module.h> |
14 | #include <linux/init.h> | 15 | #include <linux/init.h> |
15 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
diff --git a/arch/x86/include/asm/e820.h b/arch/x86/include/asm/e820.h index 5be1542fbfaf..e99d55d74df5 100644 --- a/arch/x86/include/asm/e820.h +++ b/arch/x86/include/asm/e820.h | |||
@@ -72,6 +72,9 @@ struct e820map { | |||
72 | #define BIOS_BEGIN 0x000a0000 | 72 | #define BIOS_BEGIN 0x000a0000 |
73 | #define BIOS_END 0x00100000 | 73 | #define BIOS_END 0x00100000 |
74 | 74 | ||
75 | #define BIOS_ROM_BASE 0xffe00000 | ||
76 | #define BIOS_ROM_END 0xffffffff | ||
77 | |||
75 | #ifdef __KERNEL__ | 78 | #ifdef __KERNEL__ |
76 | /* see comment in arch/x86/kernel/e820.c */ | 79 | /* see comment in arch/x86/kernel/e820.c */ |
77 | extern struct e820map e820; | 80 | extern struct e820map e820; |
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 9e6fe391094e..f702f82aa1eb 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -79,7 +79,7 @@ | |||
79 | #define KVM_NUM_MMU_PAGES (1 << KVM_MMU_HASH_SHIFT) | 79 | #define KVM_NUM_MMU_PAGES (1 << KVM_MMU_HASH_SHIFT) |
80 | #define KVM_MIN_FREE_MMU_PAGES 5 | 80 | #define KVM_MIN_FREE_MMU_PAGES 5 |
81 | #define KVM_REFILL_PAGES 25 | 81 | #define KVM_REFILL_PAGES 25 |
82 | #define KVM_MAX_CPUID_ENTRIES 40 | 82 | #define KVM_MAX_CPUID_ENTRIES 80 |
83 | #define KVM_NR_FIXED_MTRR_REGION 88 | 83 | #define KVM_NR_FIXED_MTRR_REGION 88 |
84 | #define KVM_NR_VAR_MTRR 8 | 84 | #define KVM_NR_VAR_MTRR 8 |
85 | 85 | ||
diff --git a/arch/x86/include/asm/pvclock.h b/arch/x86/include/asm/pvclock.h index 7f7e577a0e39..31d84acc1512 100644 --- a/arch/x86/include/asm/pvclock.h +++ b/arch/x86/include/asm/pvclock.h | |||
@@ -11,6 +11,7 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src); | |||
11 | void pvclock_read_wallclock(struct pvclock_wall_clock *wall, | 11 | void pvclock_read_wallclock(struct pvclock_wall_clock *wall, |
12 | struct pvclock_vcpu_time_info *vcpu, | 12 | struct pvclock_vcpu_time_info *vcpu, |
13 | struct timespec *ts); | 13 | struct timespec *ts); |
14 | void pvclock_resume(void); | ||
14 | 15 | ||
15 | /* | 16 | /* |
16 | * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction, | 17 | * Scale a 64-bit delta by scaling and multiplying by a 32-bit fraction, |
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 9e13763b6092..1e994754d323 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
@@ -45,6 +45,7 @@ obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o | |||
45 | obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o | 45 | obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o |
46 | obj-y += tsc.o io_delay.o rtc.o | 46 | obj-y += tsc.o io_delay.o rtc.o |
47 | obj-y += pci-iommu_table.o | 47 | obj-y += pci-iommu_table.o |
48 | obj-y += resource.o | ||
48 | 49 | ||
49 | obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o | 50 | obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o |
50 | obj-y += process.o | 51 | obj-y += process.o |
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index 3f838d537392..78218135b48e 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c | |||
@@ -1389,6 +1389,14 @@ void __cpuinit end_local_APIC_setup(void) | |||
1389 | 1389 | ||
1390 | setup_apic_nmi_watchdog(NULL); | 1390 | setup_apic_nmi_watchdog(NULL); |
1391 | apic_pm_activate(); | 1391 | apic_pm_activate(); |
1392 | |||
1393 | /* | ||
1394 | * Now that local APIC setup is completed for BP, configure the fault | ||
1395 | * handling for interrupt remapping. | ||
1396 | */ | ||
1397 | if (!smp_processor_id() && intr_remapping_enabled) | ||
1398 | enable_drhd_fault_handling(); | ||
1399 | |||
1392 | } | 1400 | } |
1393 | 1401 | ||
1394 | #ifdef CONFIG_X86_X2APIC | 1402 | #ifdef CONFIG_X86_X2APIC |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 7cc0a721f628..fadcd743a74f 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -2430,13 +2430,12 @@ static void ack_apic_level(struct irq_data *data) | |||
2430 | { | 2430 | { |
2431 | struct irq_cfg *cfg = data->chip_data; | 2431 | struct irq_cfg *cfg = data->chip_data; |
2432 | int i, do_unmask_irq = 0, irq = data->irq; | 2432 | int i, do_unmask_irq = 0, irq = data->irq; |
2433 | struct irq_desc *desc = irq_to_desc(irq); | ||
2434 | unsigned long v; | 2433 | unsigned long v; |
2435 | 2434 | ||
2436 | irq_complete_move(cfg); | 2435 | irq_complete_move(cfg); |
2437 | #ifdef CONFIG_GENERIC_PENDING_IRQ | 2436 | #ifdef CONFIG_GENERIC_PENDING_IRQ |
2438 | /* If we are moving the irq we need to mask it */ | 2437 | /* If we are moving the irq we need to mask it */ |
2439 | if (unlikely(desc->status & IRQ_MOVE_PENDING)) { | 2438 | if (unlikely(irq_to_desc(irq)->status & IRQ_MOVE_PENDING)) { |
2440 | do_unmask_irq = 1; | 2439 | do_unmask_irq = 1; |
2441 | mask_ioapic(cfg); | 2440 | mask_ioapic(cfg); |
2442 | } | 2441 | } |
@@ -3413,6 +3412,7 @@ dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask, | |||
3413 | msg.data |= MSI_DATA_VECTOR(cfg->vector); | 3412 | msg.data |= MSI_DATA_VECTOR(cfg->vector); |
3414 | msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK; | 3413 | msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK; |
3415 | msg.address_lo |= MSI_ADDR_DEST_ID(dest); | 3414 | msg.address_lo |= MSI_ADDR_DEST_ID(dest); |
3415 | msg.address_hi = MSI_ADDR_BASE_HI | MSI_ADDR_EXT_DEST_ID(dest); | ||
3416 | 3416 | ||
3417 | dmar_msi_write(irq, &msg); | 3417 | dmar_msi_write(irq, &msg); |
3418 | 3418 | ||
diff --git a/arch/x86/kernel/apic/probe_64.c b/arch/x86/kernel/apic/probe_64.c index f9e4e6a54073..d8c4a6feb286 100644 --- a/arch/x86/kernel/apic/probe_64.c +++ b/arch/x86/kernel/apic/probe_64.c | |||
@@ -79,13 +79,6 @@ void __init default_setup_apic_routing(void) | |||
79 | /* need to update phys_pkg_id */ | 79 | /* need to update phys_pkg_id */ |
80 | apic->phys_pkg_id = apicid_phys_pkg_id; | 80 | apic->phys_pkg_id = apicid_phys_pkg_id; |
81 | } | 81 | } |
82 | |||
83 | /* | ||
84 | * Now that apic routing model is selected, configure the | ||
85 | * fault handling for intr remapping. | ||
86 | */ | ||
87 | if (intr_remapping_enabled) | ||
88 | enable_drhd_fault_handling(); | ||
89 | } | 82 | } |
90 | 83 | ||
91 | /* Same for both flat and physical. */ | 84 | /* Same for both flat and physical. */ |
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c index 0c2b7ef7a34d..294f26da0c0c 100644 --- a/arch/x86/kernel/e820.c +++ b/arch/x86/kernel/e820.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/bootmem.h> | 14 | #include <linux/bootmem.h> |
15 | #include <linux/pfn.h> | 15 | #include <linux/pfn.h> |
16 | #include <linux/suspend.h> | 16 | #include <linux/suspend.h> |
17 | #include <linux/acpi.h> | ||
17 | #include <linux/firmware-map.h> | 18 | #include <linux/firmware-map.h> |
18 | #include <linux/memblock.h> | 19 | #include <linux/memblock.h> |
19 | 20 | ||
diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index bcece91dd311..c0dbd9ac24f0 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S | |||
@@ -60,16 +60,18 @@ | |||
60 | #define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD) | 60 | #define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD) |
61 | #endif | 61 | #endif |
62 | 62 | ||
63 | /* Number of possible pages in the lowmem region */ | ||
64 | LOWMEM_PAGES = (((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) | ||
65 | |||
63 | /* Enough space to fit pagetables for the low memory linear map */ | 66 | /* Enough space to fit pagetables for the low memory linear map */ |
64 | MAPPING_BEYOND_END = \ | 67 | MAPPING_BEYOND_END = PAGE_TABLE_SIZE(LOWMEM_PAGES) << PAGE_SHIFT |
65 | PAGE_TABLE_SIZE(((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) << PAGE_SHIFT | ||
66 | 68 | ||
67 | /* | 69 | /* |
68 | * Worst-case size of the kernel mapping we need to make: | 70 | * Worst-case size of the kernel mapping we need to make: |
69 | * the worst-case size of the kernel itself, plus the extra we need | 71 | * a relocatable kernel can live anywhere in lowmem, so we need to be able |
70 | * to map for the linear map. | 72 | * to map all of lowmem. |
71 | */ | 73 | */ |
72 | KERNEL_PAGES = (KERNEL_IMAGE_SIZE + MAPPING_BEYOND_END)>>PAGE_SHIFT | 74 | KERNEL_PAGES = LOWMEM_PAGES |
73 | 75 | ||
74 | INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_PAGES) * PAGE_SIZE_asm | 76 | INIT_MAP_SIZE = PAGE_TABLE_SIZE(KERNEL_PAGES) * PAGE_SIZE_asm |
75 | RESERVE_BRK(pagetables, INIT_MAP_SIZE) | 77 | RESERVE_BRK(pagetables, INIT_MAP_SIZE) |
@@ -620,13 +622,13 @@ ENTRY(initial_code) | |||
620 | __PAGE_ALIGNED_BSS | 622 | __PAGE_ALIGNED_BSS |
621 | .align PAGE_SIZE_asm | 623 | .align PAGE_SIZE_asm |
622 | #ifdef CONFIG_X86_PAE | 624 | #ifdef CONFIG_X86_PAE |
623 | initial_pg_pmd: | 625 | ENTRY(initial_pg_pmd) |
624 | .fill 1024*KPMDS,4,0 | 626 | .fill 1024*KPMDS,4,0 |
625 | #else | 627 | #else |
626 | ENTRY(initial_page_table) | 628 | ENTRY(initial_page_table) |
627 | .fill 1024,4,0 | 629 | .fill 1024,4,0 |
628 | #endif | 630 | #endif |
629 | initial_pg_fixmap: | 631 | ENTRY(initial_pg_fixmap) |
630 | .fill 1024,4,0 | 632 | .fill 1024,4,0 |
631 | ENTRY(empty_zero_page) | 633 | ENTRY(empty_zero_page) |
632 | .fill 4096,1,0 | 634 | .fill 4096,1,0 |
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index ae03cab4352e..4ff5968f12d2 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c | |||
@@ -27,6 +27,9 @@ | |||
27 | #define HPET_DEV_FSB_CAP 0x1000 | 27 | #define HPET_DEV_FSB_CAP 0x1000 |
28 | #define HPET_DEV_PERI_CAP 0x2000 | 28 | #define HPET_DEV_PERI_CAP 0x2000 |
29 | 29 | ||
30 | #define HPET_MIN_CYCLES 128 | ||
31 | #define HPET_MIN_PROG_DELTA (HPET_MIN_CYCLES + (HPET_MIN_CYCLES >> 1)) | ||
32 | |||
30 | #define EVT_TO_HPET_DEV(evt) container_of(evt, struct hpet_dev, evt) | 33 | #define EVT_TO_HPET_DEV(evt) container_of(evt, struct hpet_dev, evt) |
31 | 34 | ||
32 | /* | 35 | /* |
@@ -299,8 +302,9 @@ static void hpet_legacy_clockevent_register(void) | |||
299 | /* Calculate the min / max delta */ | 302 | /* Calculate the min / max delta */ |
300 | hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, | 303 | hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF, |
301 | &hpet_clockevent); | 304 | &hpet_clockevent); |
302 | /* 5 usec minimum reprogramming delta. */ | 305 | /* Setup minimum reprogramming delta. */ |
303 | hpet_clockevent.min_delta_ns = 5000; | 306 | hpet_clockevent.min_delta_ns = clockevent_delta2ns(HPET_MIN_PROG_DELTA, |
307 | &hpet_clockevent); | ||
304 | 308 | ||
305 | /* | 309 | /* |
306 | * Start hpet with the boot cpu mask and make it | 310 | * Start hpet with the boot cpu mask and make it |
@@ -393,22 +397,24 @@ static int hpet_next_event(unsigned long delta, | |||
393 | * the wraparound into account) nor a simple count down event | 397 | * the wraparound into account) nor a simple count down event |
394 | * mode. Further the write to the comparator register is | 398 | * mode. Further the write to the comparator register is |
395 | * delayed internally up to two HPET clock cycles in certain | 399 | * delayed internally up to two HPET clock cycles in certain |
396 | * chipsets (ATI, ICH9,10). We worked around that by reading | 400 | * chipsets (ATI, ICH9,10). Some newer AMD chipsets have even |
397 | * back the compare register, but that required another | 401 | * longer delays. We worked around that by reading back the |
398 | * workaround for ICH9,10 chips where the first readout after | 402 | * compare register, but that required another workaround for |
399 | * write can return the old stale value. We already have a | 403 | * ICH9,10 chips where the first readout after write can |
400 | * minimum delta of 5us enforced, but a NMI or SMI hitting | 404 | * return the old stale value. We already had a minimum |
405 | * programming delta of 5us enforced, but a NMI or SMI hitting | ||
401 | * between the counter readout and the comparator write can | 406 | * between the counter readout and the comparator write can |
402 | * move us behind that point easily. Now instead of reading | 407 | * move us behind that point easily. Now instead of reading |
403 | * the compare register back several times, we make the ETIME | 408 | * the compare register back several times, we make the ETIME |
404 | * decision based on the following: Return ETIME if the | 409 | * decision based on the following: Return ETIME if the |
405 | * counter value after the write is less than 8 HPET cycles | 410 | * counter value after the write is less than HPET_MIN_CYCLES |
406 | * away from the event or if the counter is already ahead of | 411 | * away from the event or if the counter is already ahead of |
407 | * the event. | 412 | * the event. The minimum programming delta for the generic |
413 | * clockevents code is set to 1.5 * HPET_MIN_CYCLES. | ||
408 | */ | 414 | */ |
409 | res = (s32)(cnt - hpet_readl(HPET_COUNTER)); | 415 | res = (s32)(cnt - hpet_readl(HPET_COUNTER)); |
410 | 416 | ||
411 | return res < 8 ? -ETIME : 0; | 417 | return res < HPET_MIN_CYCLES ? -ETIME : 0; |
412 | } | 418 | } |
413 | 419 | ||
414 | static void hpet_legacy_set_mode(enum clock_event_mode mode, | 420 | static void hpet_legacy_set_mode(enum clock_event_mode mode, |
diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c index dcb65cc0a053..1a1b606d3e92 100644 --- a/arch/x86/kernel/microcode_intel.c +++ b/arch/x86/kernel/microcode_intel.c | |||
@@ -364,8 +364,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, | |||
364 | 364 | ||
365 | /* For performance reasons, reuse mc area when possible */ | 365 | /* For performance reasons, reuse mc area when possible */ |
366 | if (!mc || mc_size > curr_mc_size) { | 366 | if (!mc || mc_size > curr_mc_size) { |
367 | if (mc) | 367 | vfree(mc); |
368 | vfree(mc); | ||
369 | mc = vmalloc(mc_size); | 368 | mc = vmalloc(mc_size); |
370 | if (!mc) | 369 | if (!mc) |
371 | break; | 370 | break; |
@@ -374,13 +373,11 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, | |||
374 | 373 | ||
375 | if (get_ucode_data(mc, ucode_ptr, mc_size) || | 374 | if (get_ucode_data(mc, ucode_ptr, mc_size) || |
376 | microcode_sanity_check(mc) < 0) { | 375 | microcode_sanity_check(mc) < 0) { |
377 | vfree(mc); | ||
378 | break; | 376 | break; |
379 | } | 377 | } |
380 | 378 | ||
381 | if (get_matching_microcode(&uci->cpu_sig, mc, new_rev)) { | 379 | if (get_matching_microcode(&uci->cpu_sig, mc, new_rev)) { |
382 | if (new_mc) | 380 | vfree(new_mc); |
383 | vfree(new_mc); | ||
384 | new_rev = mc_header.rev; | 381 | new_rev = mc_header.rev; |
385 | new_mc = mc; | 382 | new_mc = mc; |
386 | mc = NULL; /* trigger new vmalloc */ | 383 | mc = NULL; /* trigger new vmalloc */ |
@@ -390,12 +387,10 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, | |||
390 | leftover -= mc_size; | 387 | leftover -= mc_size; |
391 | } | 388 | } |
392 | 389 | ||
393 | if (mc) | 390 | vfree(mc); |
394 | vfree(mc); | ||
395 | 391 | ||
396 | if (leftover) { | 392 | if (leftover) { |
397 | if (new_mc) | 393 | vfree(new_mc); |
398 | vfree(new_mc); | ||
399 | state = UCODE_ERROR; | 394 | state = UCODE_ERROR; |
400 | goto out; | 395 | goto out; |
401 | } | 396 | } |
@@ -405,8 +400,7 @@ static enum ucode_state generic_load_microcode(int cpu, void *data, size_t size, | |||
405 | goto out; | 400 | goto out; |
406 | } | 401 | } |
407 | 402 | ||
408 | if (uci->mc) | 403 | vfree(uci->mc); |
409 | vfree(uci->mc); | ||
410 | uci->mc = (struct microcode_intel *)new_mc; | 404 | uci->mc = (struct microcode_intel *)new_mc; |
411 | 405 | ||
412 | pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n", | 406 | pr_debug("CPU%d found a matching microcode update with version 0x%x (current=0x%x)\n", |
diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c index 008b91eefa18..42eb3300dfc6 100644 --- a/arch/x86/kernel/pvclock.c +++ b/arch/x86/kernel/pvclock.c | |||
@@ -83,6 +83,11 @@ unsigned long pvclock_tsc_khz(struct pvclock_vcpu_time_info *src) | |||
83 | 83 | ||
84 | static atomic64_t last_value = ATOMIC64_INIT(0); | 84 | static atomic64_t last_value = ATOMIC64_INIT(0); |
85 | 85 | ||
86 | void pvclock_resume(void) | ||
87 | { | ||
88 | atomic64_set(&last_value, 0); | ||
89 | } | ||
90 | |||
86 | cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src) | 91 | cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src) |
87 | { | 92 | { |
88 | struct pvclock_shadow_time shadow; | 93 | struct pvclock_shadow_time shadow; |
diff --git a/arch/x86/kernel/resource.c b/arch/x86/kernel/resource.c new file mode 100644 index 000000000000..2a26819bb6a8 --- /dev/null +++ b/arch/x86/kernel/resource.c | |||
@@ -0,0 +1,48 @@ | |||
1 | #include <linux/ioport.h> | ||
2 | #include <asm/e820.h> | ||
3 | |||
4 | static void resource_clip(struct resource *res, resource_size_t start, | ||
5 | resource_size_t end) | ||
6 | { | ||
7 | resource_size_t low = 0, high = 0; | ||
8 | |||
9 | if (res->end < start || res->start > end) | ||
10 | return; /* no conflict */ | ||
11 | |||
12 | if (res->start < start) | ||
13 | low = start - res->start; | ||
14 | |||
15 | if (res->end > end) | ||
16 | high = res->end - end; | ||
17 | |||
18 | /* Keep the area above or below the conflict, whichever is larger */ | ||
19 | if (low > high) | ||
20 | res->end = start - 1; | ||
21 | else | ||
22 | res->start = end + 1; | ||
23 | } | ||
24 | |||
25 | static void remove_e820_regions(struct resource *avail) | ||
26 | { | ||
27 | int i; | ||
28 | struct e820entry *entry; | ||
29 | |||
30 | for (i = 0; i < e820.nr_map; i++) { | ||
31 | entry = &e820.map[i]; | ||
32 | |||
33 | resource_clip(avail, entry->addr, | ||
34 | entry->addr + entry->size - 1); | ||
35 | } | ||
36 | } | ||
37 | |||
38 | void arch_remove_reservations(struct resource *avail) | ||
39 | { | ||
40 | /* Trim out BIOS areas (low 1MB and high 2MB) and E820 regions */ | ||
41 | if (avail->flags & IORESOURCE_MEM) { | ||
42 | if (avail->start < BIOS_END) | ||
43 | avail->start = BIOS_END; | ||
44 | resource_clip(avail, BIOS_ROM_BASE, BIOS_ROM_END); | ||
45 | |||
46 | remove_e820_regions(avail); | ||
47 | } | ||
48 | } | ||
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 21c6746338af..a0f52af256a0 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -501,7 +501,18 @@ static inline unsigned long long get_total_mem(void) | |||
501 | return total << PAGE_SHIFT; | 501 | return total << PAGE_SHIFT; |
502 | } | 502 | } |
503 | 503 | ||
504 | #define DEFAULT_BZIMAGE_ADDR_MAX 0x37FFFFFF | 504 | /* |
505 | * Keep the crash kernel below this limit. On 32 bits earlier kernels | ||
506 | * would limit the kernel to the low 512 MiB due to mapping restrictions. | ||
507 | * On 64 bits, kexec-tools currently limits us to 896 MiB; increase this | ||
508 | * limit once kexec-tools are fixed. | ||
509 | */ | ||
510 | #ifdef CONFIG_X86_32 | ||
511 | # define CRASH_KERNEL_ADDR_MAX (512 << 20) | ||
512 | #else | ||
513 | # define CRASH_KERNEL_ADDR_MAX (896 << 20) | ||
514 | #endif | ||
515 | |||
505 | static void __init reserve_crashkernel(void) | 516 | static void __init reserve_crashkernel(void) |
506 | { | 517 | { |
507 | unsigned long long total_mem; | 518 | unsigned long long total_mem; |
@@ -520,10 +531,10 @@ static void __init reserve_crashkernel(void) | |||
520 | const unsigned long long alignment = 16<<20; /* 16M */ | 531 | const unsigned long long alignment = 16<<20; /* 16M */ |
521 | 532 | ||
522 | /* | 533 | /* |
523 | * kexec want bzImage is below DEFAULT_BZIMAGE_ADDR_MAX | 534 | * kexec want bzImage is below CRASH_KERNEL_ADDR_MAX |
524 | */ | 535 | */ |
525 | crash_base = memblock_find_in_range(alignment, | 536 | crash_base = memblock_find_in_range(alignment, |
526 | DEFAULT_BZIMAGE_ADDR_MAX, crash_size, alignment); | 537 | CRASH_KERNEL_ADDR_MAX, crash_size, alignment); |
527 | 538 | ||
528 | if (crash_base == MEMBLOCK_ERROR) { | 539 | if (crash_base == MEMBLOCK_ERROR) { |
529 | pr_info("crashkernel reservation failed - No suitable area found.\n"); | 540 | pr_info("crashkernel reservation failed - No suitable area found.\n"); |
@@ -769,7 +780,6 @@ void __init setup_arch(char **cmdline_p) | |||
769 | 780 | ||
770 | x86_init.oem.arch_setup(); | 781 | x86_init.oem.arch_setup(); |
771 | 782 | ||
772 | resource_alloc_from_bottom = 0; | ||
773 | iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1; | 783 | iomem_resource.end = (1ULL << boot_cpu_data.x86_phys_bits) - 1; |
774 | setup_memory_map(); | 784 | setup_memory_map(); |
775 | parse_setup_data(); | 785 | parse_setup_data(); |
diff --git a/arch/x86/kernel/xsave.c b/arch/x86/kernel/xsave.c index 9c253bd65e24..547128546cc3 100644 --- a/arch/x86/kernel/xsave.c +++ b/arch/x86/kernel/xsave.c | |||
@@ -394,7 +394,8 @@ static void __init setup_xstate_init(void) | |||
394 | * Setup init_xstate_buf to represent the init state of | 394 | * Setup init_xstate_buf to represent the init state of |
395 | * all the features managed by the xsave | 395 | * all the features managed by the xsave |
396 | */ | 396 | */ |
397 | init_xstate_buf = alloc_bootmem(xstate_size); | 397 | init_xstate_buf = alloc_bootmem_align(xstate_size, |
398 | __alignof__(struct xsave_struct)); | ||
398 | init_xstate_buf->i387.mxcsr = MXCSR_DEFAULT; | 399 | init_xstate_buf->i387.mxcsr = MXCSR_DEFAULT; |
399 | 400 | ||
400 | clts(); | 401 | clts(); |
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c index f628234fbeca..3cece05e4ac4 100644 --- a/arch/x86/kvm/i8259.c +++ b/arch/x86/kvm/i8259.c | |||
@@ -575,6 +575,8 @@ struct kvm_pic *kvm_create_pic(struct kvm *kvm) | |||
575 | s->pics[1].elcr_mask = 0xde; | 575 | s->pics[1].elcr_mask = 0xde; |
576 | s->pics[0].pics_state = s; | 576 | s->pics[0].pics_state = s; |
577 | s->pics[1].pics_state = s; | 577 | s->pics[1].pics_state = s; |
578 | s->pics[0].isr_ack = 0xff; | ||
579 | s->pics[1].isr_ack = 0xff; | ||
578 | 580 | ||
579 | /* | 581 | /* |
580 | * Initialize PIO device | 582 | * Initialize PIO device |
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index fb8b376bf28c..fbb04aee8301 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -2394,7 +2394,8 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu) | |||
2394 | ASSERT(!VALID_PAGE(root)); | 2394 | ASSERT(!VALID_PAGE(root)); |
2395 | spin_lock(&vcpu->kvm->mmu_lock); | 2395 | spin_lock(&vcpu->kvm->mmu_lock); |
2396 | kvm_mmu_free_some_pages(vcpu); | 2396 | kvm_mmu_free_some_pages(vcpu); |
2397 | sp = kvm_mmu_get_page(vcpu, i << 30, i << 30, | 2397 | sp = kvm_mmu_get_page(vcpu, i << (30 - PAGE_SHIFT), |
2398 | i << 30, | ||
2398 | PT32_ROOT_LEVEL, 1, ACC_ALL, | 2399 | PT32_ROOT_LEVEL, 1, ACC_ALL, |
2399 | NULL); | 2400 | NULL); |
2400 | root = __pa(sp->spt); | 2401 | root = __pa(sp->spt); |
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 1ca12298ffc7..b81a9b7c2ca4 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -3494,6 +3494,10 @@ static void svm_cpuid_update(struct kvm_vcpu *vcpu) | |||
3494 | static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry) | 3494 | static void svm_set_supported_cpuid(u32 func, struct kvm_cpuid_entry2 *entry) |
3495 | { | 3495 | { |
3496 | switch (func) { | 3496 | switch (func) { |
3497 | case 0x00000001: | ||
3498 | /* Mask out xsave bit as long as it is not supported by SVM */ | ||
3499 | entry->ecx &= ~(bit(X86_FEATURE_XSAVE)); | ||
3500 | break; | ||
3497 | case 0x80000001: | 3501 | case 0x80000001: |
3498 | if (nested) | 3502 | if (nested) |
3499 | entry->ecx |= (1 << 2); /* Set SVM bit */ | 3503 | entry->ecx |= (1 << 2); /* Set SVM bit */ |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index ff21fdda0c53..81fcbe9515c5 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -4227,11 +4227,6 @@ static int vmx_get_lpage_level(void) | |||
4227 | return PT_PDPE_LEVEL; | 4227 | return PT_PDPE_LEVEL; |
4228 | } | 4228 | } |
4229 | 4229 | ||
4230 | static inline u32 bit(int bitno) | ||
4231 | { | ||
4232 | return 1 << (bitno & 31); | ||
4233 | } | ||
4234 | |||
4235 | static void vmx_cpuid_update(struct kvm_vcpu *vcpu) | 4230 | static void vmx_cpuid_update(struct kvm_vcpu *vcpu) |
4236 | { | 4231 | { |
4237 | struct kvm_cpuid_entry2 *best; | 4232 | struct kvm_cpuid_entry2 *best; |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index cdac9e592aa5..b989e1f1e5d3 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -155,11 +155,6 @@ struct kvm_stats_debugfs_item debugfs_entries[] = { | |||
155 | 155 | ||
156 | u64 __read_mostly host_xcr0; | 156 | u64 __read_mostly host_xcr0; |
157 | 157 | ||
158 | static inline u32 bit(int bitno) | ||
159 | { | ||
160 | return 1 << (bitno & 31); | ||
161 | } | ||
162 | |||
163 | static void kvm_on_user_return(struct user_return_notifier *urn) | 158 | static void kvm_on_user_return(struct user_return_notifier *urn) |
164 | { | 159 | { |
165 | unsigned slot; | 160 | unsigned slot; |
@@ -4569,9 +4564,11 @@ static void kvm_timer_init(void) | |||
4569 | #ifdef CONFIG_CPU_FREQ | 4564 | #ifdef CONFIG_CPU_FREQ |
4570 | struct cpufreq_policy policy; | 4565 | struct cpufreq_policy policy; |
4571 | memset(&policy, 0, sizeof(policy)); | 4566 | memset(&policy, 0, sizeof(policy)); |
4572 | cpufreq_get_policy(&policy, get_cpu()); | 4567 | cpu = get_cpu(); |
4568 | cpufreq_get_policy(&policy, cpu); | ||
4573 | if (policy.cpuinfo.max_freq) | 4569 | if (policy.cpuinfo.max_freq) |
4574 | max_tsc_khz = policy.cpuinfo.max_freq; | 4570 | max_tsc_khz = policy.cpuinfo.max_freq; |
4571 | put_cpu(); | ||
4575 | #endif | 4572 | #endif |
4576 | cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block, | 4573 | cpufreq_register_notifier(&kvmclock_cpufreq_notifier_block, |
4577 | CPUFREQ_TRANSITION_NOTIFIER); | 4574 | CPUFREQ_TRANSITION_NOTIFIER); |
@@ -5522,6 +5519,8 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, | |||
5522 | 5519 | ||
5523 | mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4; | 5520 | mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4; |
5524 | kvm_x86_ops->set_cr4(vcpu, sregs->cr4); | 5521 | kvm_x86_ops->set_cr4(vcpu, sregs->cr4); |
5522 | if (sregs->cr4 & X86_CR4_OSXSAVE) | ||
5523 | update_cpuid(vcpu); | ||
5525 | if (!is_long_mode(vcpu) && is_pae(vcpu)) { | 5524 | if (!is_long_mode(vcpu) && is_pae(vcpu)) { |
5526 | load_pdptrs(vcpu, vcpu->arch.walk_mmu, vcpu->arch.cr3); | 5525 | load_pdptrs(vcpu, vcpu->arch.walk_mmu, vcpu->arch.cr3); |
5527 | mmu_reset_needed = 1; | 5526 | mmu_reset_needed = 1; |
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h index 2cea414489f3..c600da830ce0 100644 --- a/arch/x86/kvm/x86.h +++ b/arch/x86/kvm/x86.h | |||
@@ -70,6 +70,11 @@ static inline int is_paging(struct kvm_vcpu *vcpu) | |||
70 | return kvm_read_cr0_bits(vcpu, X86_CR0_PG); | 70 | return kvm_read_cr0_bits(vcpu, X86_CR0_PG); |
71 | } | 71 | } |
72 | 72 | ||
73 | static inline u32 bit(int bitno) | ||
74 | { | ||
75 | return 1 << (bitno & 31); | ||
76 | } | ||
77 | |||
73 | void kvm_before_handle_nmi(struct kvm_vcpu *vcpu); | 78 | void kvm_before_handle_nmi(struct kvm_vcpu *vcpu); |
74 | void kvm_after_handle_nmi(struct kvm_vcpu *vcpu); | 79 | void kvm_after_handle_nmi(struct kvm_vcpu *vcpu); |
75 | int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq); | 80 | int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq); |
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 73b1e1a1f489..4996cf5f73a0 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -531,7 +531,10 @@ static void lguest_write_cr3(unsigned long cr3) | |||
531 | { | 531 | { |
532 | lguest_data.pgdir = cr3; | 532 | lguest_data.pgdir = cr3; |
533 | lazy_hcall1(LHCALL_NEW_PGTABLE, cr3); | 533 | lazy_hcall1(LHCALL_NEW_PGTABLE, cr3); |
534 | cr3_changed = true; | 534 | |
535 | /* These two page tables are simple, linear, and used during boot */ | ||
536 | if (cr3 != __pa(swapper_pg_dir) && cr3 != __pa(initial_page_table)) | ||
537 | cr3_changed = true; | ||
535 | } | 538 | } |
536 | 539 | ||
537 | static unsigned long lguest_read_cr3(void) | 540 | static unsigned long lguest_read_cr3(void) |
@@ -703,9 +706,9 @@ static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval) | |||
703 | * to forget all of them. Fortunately, this is very rare. | 706 | * to forget all of them. Fortunately, this is very rare. |
704 | * | 707 | * |
705 | * ... except in early boot when the kernel sets up the initial pagetables, | 708 | * ... except in early boot when the kernel sets up the initial pagetables, |
706 | * which makes booting astonishingly slow: 1.83 seconds! So we don't even tell | 709 | * which makes booting astonishingly slow: 48 seconds! So we don't even tell |
707 | * the Host anything changed until we've done the first page table switch, | 710 | * the Host anything changed until we've done the first real page table switch, |
708 | * which brings boot back to 0.25 seconds. | 711 | * which brings boot back to 4.3 seconds. |
709 | */ | 712 | */ |
710 | static void lguest_set_pte(pte_t *ptep, pte_t pteval) | 713 | static void lguest_set_pte(pte_t *ptep, pte_t pteval) |
711 | { | 714 | { |
@@ -1002,7 +1005,7 @@ static void lguest_time_init(void) | |||
1002 | clockevents_register_device(&lguest_clockevent); | 1005 | clockevents_register_device(&lguest_clockevent); |
1003 | 1006 | ||
1004 | /* Finally, we unblock the timer interrupt. */ | 1007 | /* Finally, we unblock the timer interrupt. */ |
1005 | enable_lguest_irq(0); | 1008 | clear_bit(0, lguest_data.blocked_interrupts); |
1006 | } | 1009 | } |
1007 | 1010 | ||
1008 | /* | 1011 | /* |
@@ -1349,9 +1352,6 @@ __init void lguest_init(void) | |||
1349 | */ | 1352 | */ |
1350 | switch_to_new_gdt(0); | 1353 | switch_to_new_gdt(0); |
1351 | 1354 | ||
1352 | /* We actually boot with all memory mapped, but let's say 128MB. */ | ||
1353 | max_pfn_mapped = (128*1024*1024) >> PAGE_SHIFT; | ||
1354 | |||
1355 | /* | 1355 | /* |
1356 | * The Host<->Guest Switcher lives at the top of our address space, and | 1356 | * The Host<->Guest Switcher lives at the top of our address space, and |
1357 | * the Host told us how big it is when we made LGUEST_INIT hypercall: | 1357 | * the Host told us how big it is when we made LGUEST_INIT hypercall: |
diff --git a/arch/x86/lguest/i386_head.S b/arch/x86/lguest/i386_head.S index 4f420c2f2d55..e7d5382ef263 100644 --- a/arch/x86/lguest/i386_head.S +++ b/arch/x86/lguest/i386_head.S | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <asm/asm-offsets.h> | 4 | #include <asm/asm-offsets.h> |
5 | #include <asm/thread_info.h> | 5 | #include <asm/thread_info.h> |
6 | #include <asm/processor-flags.h> | 6 | #include <asm/processor-flags.h> |
7 | #include <asm/pgtable.h> | ||
7 | 8 | ||
8 | /*G:020 | 9 | /*G:020 |
9 | * Our story starts with the kernel booting into startup_32 in | 10 | * Our story starts with the kernel booting into startup_32 in |
@@ -37,9 +38,113 @@ ENTRY(lguest_entry) | |||
37 | /* Set up the initial stack so we can run C code. */ | 38 | /* Set up the initial stack so we can run C code. */ |
38 | movl $(init_thread_union+THREAD_SIZE),%esp | 39 | movl $(init_thread_union+THREAD_SIZE),%esp |
39 | 40 | ||
41 | call init_pagetables | ||
42 | |||
40 | /* Jumps are relative: we're running __PAGE_OFFSET too low. */ | 43 | /* Jumps are relative: we're running __PAGE_OFFSET too low. */ |
41 | jmp lguest_init+__PAGE_OFFSET | 44 | jmp lguest_init+__PAGE_OFFSET |
42 | 45 | ||
46 | /* | ||
47 | * Initialize page tables. This creates a PDE and a set of page | ||
48 | * tables, which are located immediately beyond __brk_base. The variable | ||
49 | * _brk_end is set up to point to the first "safe" location. | ||
50 | * Mappings are created both at virtual address 0 (identity mapping) | ||
51 | * and PAGE_OFFSET for up to _end. | ||
52 | * | ||
53 | * FIXME: This code is taken verbatim from arch/x86/kernel/head_32.S: they | ||
54 | * don't have a stack at this point, so we can't just use call and ret. | ||
55 | */ | ||
56 | init_pagetables: | ||
57 | #if PTRS_PER_PMD > 1 | ||
58 | #define PAGE_TABLE_SIZE(pages) (((pages) / PTRS_PER_PMD) + PTRS_PER_PGD) | ||
59 | #else | ||
60 | #define PAGE_TABLE_SIZE(pages) ((pages) / PTRS_PER_PGD) | ||
61 | #endif | ||
62 | #define pa(X) ((X) - __PAGE_OFFSET) | ||
63 | |||
64 | /* Enough space to fit pagetables for the low memory linear map */ | ||
65 | MAPPING_BEYOND_END = \ | ||
66 | PAGE_TABLE_SIZE(((1<<32) - __PAGE_OFFSET) >> PAGE_SHIFT) << PAGE_SHIFT | ||
67 | #ifdef CONFIG_X86_PAE | ||
68 | |||
69 | /* | ||
70 | * In PAE mode initial_page_table is statically defined to contain | ||
71 | * enough entries to cover the VMSPLIT option (that is the top 1, 2 or 3 | ||
72 | * entries). The identity mapping is handled by pointing two PGD entries | ||
73 | * to the first kernel PMD. | ||
74 | * | ||
75 | * Note the upper half of each PMD or PTE are always zero at this stage. | ||
76 | */ | ||
77 | |||
78 | #define KPMDS (((-__PAGE_OFFSET) >> 30) & 3) /* Number of kernel PMDs */ | ||
79 | |||
80 | xorl %ebx,%ebx /* %ebx is kept at zero */ | ||
81 | |||
82 | movl $pa(__brk_base), %edi | ||
83 | movl $pa(initial_pg_pmd), %edx | ||
84 | movl $PTE_IDENT_ATTR, %eax | ||
85 | 10: | ||
86 | leal PDE_IDENT_ATTR(%edi),%ecx /* Create PMD entry */ | ||
87 | movl %ecx,(%edx) /* Store PMD entry */ | ||
88 | /* Upper half already zero */ | ||
89 | addl $8,%edx | ||
90 | movl $512,%ecx | ||
91 | 11: | ||
92 | stosl | ||
93 | xchgl %eax,%ebx | ||
94 | stosl | ||
95 | xchgl %eax,%ebx | ||
96 | addl $0x1000,%eax | ||
97 | loop 11b | ||
98 | |||
99 | /* | ||
100 | * End condition: we must map up to the end + MAPPING_BEYOND_END. | ||
101 | */ | ||
102 | movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp | ||
103 | cmpl %ebp,%eax | ||
104 | jb 10b | ||
105 | 1: | ||
106 | addl $__PAGE_OFFSET, %edi | ||
107 | movl %edi, pa(_brk_end) | ||
108 | shrl $12, %eax | ||
109 | movl %eax, pa(max_pfn_mapped) | ||
110 | |||
111 | /* Do early initialization of the fixmap area */ | ||
112 | movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax | ||
113 | movl %eax,pa(initial_pg_pmd+0x1000*KPMDS-8) | ||
114 | #else /* Not PAE */ | ||
115 | |||
116 | page_pde_offset = (__PAGE_OFFSET >> 20); | ||
117 | |||
118 | movl $pa(__brk_base), %edi | ||
119 | movl $pa(initial_page_table), %edx | ||
120 | movl $PTE_IDENT_ATTR, %eax | ||
121 | 10: | ||
122 | leal PDE_IDENT_ATTR(%edi),%ecx /* Create PDE entry */ | ||
123 | movl %ecx,(%edx) /* Store identity PDE entry */ | ||
124 | movl %ecx,page_pde_offset(%edx) /* Store kernel PDE entry */ | ||
125 | addl $4,%edx | ||
126 | movl $1024, %ecx | ||
127 | 11: | ||
128 | stosl | ||
129 | addl $0x1000,%eax | ||
130 | loop 11b | ||
131 | /* | ||
132 | * End condition: we must map up to the end + MAPPING_BEYOND_END. | ||
133 | */ | ||
134 | movl $pa(_end) + MAPPING_BEYOND_END + PTE_IDENT_ATTR, %ebp | ||
135 | cmpl %ebp,%eax | ||
136 | jb 10b | ||
137 | addl $__PAGE_OFFSET, %edi | ||
138 | movl %edi, pa(_brk_end) | ||
139 | shrl $12, %eax | ||
140 | movl %eax, pa(max_pfn_mapped) | ||
141 | |||
142 | /* Do early initialization of the fixmap area */ | ||
143 | movl $pa(initial_pg_fixmap)+PDE_IDENT_ATTR,%eax | ||
144 | movl %eax,pa(initial_page_table+0xffc) | ||
145 | #endif | ||
146 | ret | ||
147 | |||
43 | /*G:055 | 148 | /*G:055 |
44 | * We create a macro which puts the assembler code between lgstart_ and lgend_ | 149 | * We create a macro which puts the assembler code between lgstart_ and lgend_ |
45 | * markers. These templates are put in the .text section: they can't be | 150 | * markers. These templates are put in the .text section: they can't be |
diff --git a/arch/x86/oprofile/op_model_amd.c b/arch/x86/oprofile/op_model_amd.c index a011bcc0f943..7d90d47655ba 100644 --- a/arch/x86/oprofile/op_model_amd.c +++ b/arch/x86/oprofile/op_model_amd.c | |||
@@ -630,21 +630,29 @@ static int __init_ibs_nmi(void) | |||
630 | return 0; | 630 | return 0; |
631 | } | 631 | } |
632 | 632 | ||
633 | /* initialize the APIC for the IBS interrupts if available */ | 633 | /* |
634 | * check and reserve APIC extended interrupt LVT offset for IBS if | ||
635 | * available | ||
636 | * | ||
637 | * init_ibs() preforms implicitly cpu-local operations, so pin this | ||
638 | * thread to its current CPU | ||
639 | */ | ||
640 | |||
634 | static void init_ibs(void) | 641 | static void init_ibs(void) |
635 | { | 642 | { |
636 | ibs_caps = get_ibs_caps(); | 643 | preempt_disable(); |
637 | 644 | ||
645 | ibs_caps = get_ibs_caps(); | ||
638 | if (!ibs_caps) | 646 | if (!ibs_caps) |
639 | return; | 647 | goto out; |
640 | 648 | ||
641 | if (__init_ibs_nmi()) { | 649 | if (__init_ibs_nmi() < 0) |
642 | ibs_caps = 0; | 650 | ibs_caps = 0; |
643 | return; | 651 | else |
644 | } | 652 | printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", ibs_caps); |
645 | 653 | ||
646 | printk(KERN_INFO "oprofile: AMD IBS detected (0x%08x)\n", | 654 | out: |
647 | (unsigned)ibs_caps); | 655 | preempt_enable(); |
648 | } | 656 | } |
649 | 657 | ||
650 | static int (*create_arch_files)(struct super_block *sb, struct dentry *root); | 658 | static int (*create_arch_files)(struct super_block *sb, struct dentry *root); |
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c index c4bb261c106e..b1805b78842f 100644 --- a/arch/x86/pci/i386.c +++ b/arch/x86/pci/i386.c | |||
@@ -65,21 +65,13 @@ pcibios_align_resource(void *data, const struct resource *res, | |||
65 | resource_size_t size, resource_size_t align) | 65 | resource_size_t size, resource_size_t align) |
66 | { | 66 | { |
67 | struct pci_dev *dev = data; | 67 | struct pci_dev *dev = data; |
68 | resource_size_t start = round_down(res->end - size + 1, align); | 68 | resource_size_t start = res->start; |
69 | 69 | ||
70 | if (res->flags & IORESOURCE_IO) { | 70 | if (res->flags & IORESOURCE_IO) { |
71 | 71 | if (skip_isa_ioresource_align(dev)) | |
72 | /* | 72 | return start; |
73 | * If we're avoiding ISA aliases, the largest contiguous I/O | 73 | if (start & 0x300) |
74 | * port space is 256 bytes. Clearing bits 9 and 10 preserves | 74 | start = (start + 0x3ff) & ~0x3ff; |
75 | * all 256-byte and smaller alignments, so the result will | ||
76 | * still be correctly aligned. | ||
77 | */ | ||
78 | if (!skip_isa_ioresource_align(dev)) | ||
79 | start &= ~0x300; | ||
80 | } else if (res->flags & IORESOURCE_MEM) { | ||
81 | if (start < BIOS_END) | ||
82 | start = res->end; /* fail; no space */ | ||
83 | } | 75 | } |
84 | return start; | 76 | return start; |
85 | } | 77 | } |
diff --git a/arch/x86/vdso/Makefile b/arch/x86/vdso/Makefile index 4a2afa1bac51..b6552b189bcd 100644 --- a/arch/x86/vdso/Makefile +++ b/arch/x86/vdso/Makefile | |||
@@ -25,7 +25,7 @@ targets += vdso.so vdso.so.dbg vdso.lds $(vobjs-y) | |||
25 | 25 | ||
26 | export CPPFLAGS_vdso.lds += -P -C | 26 | export CPPFLAGS_vdso.lds += -P -C |
27 | 27 | ||
28 | VDSO_LDFLAGS_vdso.lds = -m elf_x86_64 -Wl,-soname=linux-vdso.so.1 \ | 28 | VDSO_LDFLAGS_vdso.lds = -m64 -Wl,-soname=linux-vdso.so.1 \ |
29 | -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 | 29 | -Wl,-z,max-page-size=4096 -Wl,-z,common-page-size=4096 |
30 | 30 | ||
31 | $(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so | 31 | $(obj)/vdso.o: $(src)/vdso.S $(obj)/vdso.so |
@@ -69,7 +69,7 @@ vdso32.so-$(VDSO32-y) += sysenter | |||
69 | vdso32-images = $(vdso32.so-y:%=vdso32-%.so) | 69 | vdso32-images = $(vdso32.so-y:%=vdso32-%.so) |
70 | 70 | ||
71 | CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds) | 71 | CPPFLAGS_vdso32.lds = $(CPPFLAGS_vdso.lds) |
72 | VDSO_LDFLAGS_vdso32.lds = -m elf_i386 -Wl,-soname=linux-gate.so.1 | 72 | VDSO_LDFLAGS_vdso32.lds = -m32 -Wl,-soname=linux-gate.so.1 |
73 | 73 | ||
74 | # This makes sure the $(obj) subdirectory exists even though vdso32/ | 74 | # This makes sure the $(obj) subdirectory exists even though vdso32/ |
75 | # is not a kbuild sub-make subdirectory. | 75 | # is not a kbuild sub-make subdirectory. |
diff --git a/arch/x86/xen/time.c b/arch/x86/xen/time.c index b2bb5aa3b054..5da5e53fb94c 100644 --- a/arch/x86/xen/time.c +++ b/arch/x86/xen/time.c | |||
@@ -426,6 +426,8 @@ void xen_timer_resume(void) | |||
426 | { | 426 | { |
427 | int cpu; | 427 | int cpu; |
428 | 428 | ||
429 | pvclock_resume(); | ||
430 | |||
429 | if (xen_clockevent != &xen_vcpuop_clockevent) | 431 | if (xen_clockevent != &xen_vcpuop_clockevent) |
430 | return; | 432 | return; |
431 | 433 | ||
diff --git a/block/blk-map.c b/block/blk-map.c index 5d5dbe47c228..e663ac2d8e68 100644 --- a/block/blk-map.c +++ b/block/blk-map.c | |||
@@ -201,12 +201,13 @@ int blk_rq_map_user_iov(struct request_queue *q, struct request *rq, | |||
201 | for (i = 0; i < iov_count; i++) { | 201 | for (i = 0; i < iov_count; i++) { |
202 | unsigned long uaddr = (unsigned long)iov[i].iov_base; | 202 | unsigned long uaddr = (unsigned long)iov[i].iov_base; |
203 | 203 | ||
204 | if (!iov[i].iov_len) | ||
205 | return -EINVAL; | ||
206 | |||
204 | if (uaddr & queue_dma_alignment(q)) { | 207 | if (uaddr & queue_dma_alignment(q)) { |
205 | unaligned = 1; | 208 | unaligned = 1; |
206 | break; | 209 | break; |
207 | } | 210 | } |
208 | if (!iov[i].iov_len) | ||
209 | return -EINVAL; | ||
210 | } | 211 | } |
211 | 212 | ||
212 | if (unaligned || (q->dma_pad_mask & len) || map_data) | 213 | if (unaligned || (q->dma_pad_mask & len) || map_data) |
diff --git a/block/blk-merge.c b/block/blk-merge.c index 77b7c26df6b5..74bc4a768f32 100644 --- a/block/blk-merge.c +++ b/block/blk-merge.c | |||
@@ -21,7 +21,7 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q, | |||
21 | return 0; | 21 | return 0; |
22 | 22 | ||
23 | fbio = bio; | 23 | fbio = bio; |
24 | cluster = test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); | 24 | cluster = blk_queue_cluster(q); |
25 | seg_size = 0; | 25 | seg_size = 0; |
26 | nr_phys_segs = 0; | 26 | nr_phys_segs = 0; |
27 | for_each_bio(bio) { | 27 | for_each_bio(bio) { |
@@ -87,7 +87,7 @@ EXPORT_SYMBOL(blk_recount_segments); | |||
87 | static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio, | 87 | static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio, |
88 | struct bio *nxt) | 88 | struct bio *nxt) |
89 | { | 89 | { |
90 | if (!test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags)) | 90 | if (!blk_queue_cluster(q)) |
91 | return 0; | 91 | return 0; |
92 | 92 | ||
93 | if (bio->bi_seg_back_size + nxt->bi_seg_front_size > | 93 | if (bio->bi_seg_back_size + nxt->bi_seg_front_size > |
@@ -123,7 +123,7 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq, | |||
123 | int nsegs, cluster; | 123 | int nsegs, cluster; |
124 | 124 | ||
125 | nsegs = 0; | 125 | nsegs = 0; |
126 | cluster = test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags); | 126 | cluster = blk_queue_cluster(q); |
127 | 127 | ||
128 | /* | 128 | /* |
129 | * for each bio in rq | 129 | * for each bio in rq |
diff --git a/block/blk-settings.c b/block/blk-settings.c index 701859fb9647..36c8c1f2af18 100644 --- a/block/blk-settings.c +++ b/block/blk-settings.c | |||
@@ -126,7 +126,7 @@ void blk_set_default_limits(struct queue_limits *lim) | |||
126 | lim->alignment_offset = 0; | 126 | lim->alignment_offset = 0; |
127 | lim->io_opt = 0; | 127 | lim->io_opt = 0; |
128 | lim->misaligned = 0; | 128 | lim->misaligned = 0; |
129 | lim->no_cluster = 0; | 129 | lim->cluster = 1; |
130 | } | 130 | } |
131 | EXPORT_SYMBOL(blk_set_default_limits); | 131 | EXPORT_SYMBOL(blk_set_default_limits); |
132 | 132 | ||
@@ -229,8 +229,8 @@ void blk_queue_bounce_limit(struct request_queue *q, u64 dma_mask) | |||
229 | EXPORT_SYMBOL(blk_queue_bounce_limit); | 229 | EXPORT_SYMBOL(blk_queue_bounce_limit); |
230 | 230 | ||
231 | /** | 231 | /** |
232 | * blk_queue_max_hw_sectors - set max sectors for a request for this queue | 232 | * blk_limits_max_hw_sectors - set hard and soft limit of max sectors for request |
233 | * @q: the request queue for the device | 233 | * @limits: the queue limits |
234 | * @max_hw_sectors: max hardware sectors in the usual 512b unit | 234 | * @max_hw_sectors: max hardware sectors in the usual 512b unit |
235 | * | 235 | * |
236 | * Description: | 236 | * Description: |
@@ -244,7 +244,7 @@ EXPORT_SYMBOL(blk_queue_bounce_limit); | |||
244 | * per-device basis in /sys/block/<device>/queue/max_sectors_kb. | 244 | * per-device basis in /sys/block/<device>/queue/max_sectors_kb. |
245 | * The soft limit can not exceed max_hw_sectors. | 245 | * The soft limit can not exceed max_hw_sectors. |
246 | **/ | 246 | **/ |
247 | void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_sectors) | 247 | void blk_limits_max_hw_sectors(struct queue_limits *limits, unsigned int max_hw_sectors) |
248 | { | 248 | { |
249 | if ((max_hw_sectors << 9) < PAGE_CACHE_SIZE) { | 249 | if ((max_hw_sectors << 9) < PAGE_CACHE_SIZE) { |
250 | max_hw_sectors = 1 << (PAGE_CACHE_SHIFT - 9); | 250 | max_hw_sectors = 1 << (PAGE_CACHE_SHIFT - 9); |
@@ -252,9 +252,23 @@ void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_secto | |||
252 | __func__, max_hw_sectors); | 252 | __func__, max_hw_sectors); |
253 | } | 253 | } |
254 | 254 | ||
255 | q->limits.max_hw_sectors = max_hw_sectors; | 255 | limits->max_hw_sectors = max_hw_sectors; |
256 | q->limits.max_sectors = min_t(unsigned int, max_hw_sectors, | 256 | limits->max_sectors = min_t(unsigned int, max_hw_sectors, |
257 | BLK_DEF_MAX_SECTORS); | 257 | BLK_DEF_MAX_SECTORS); |
258 | } | ||
259 | EXPORT_SYMBOL(blk_limits_max_hw_sectors); | ||
260 | |||
261 | /** | ||
262 | * blk_queue_max_hw_sectors - set max sectors for a request for this queue | ||
263 | * @q: the request queue for the device | ||
264 | * @max_hw_sectors: max hardware sectors in the usual 512b unit | ||
265 | * | ||
266 | * Description: | ||
267 | * See description for blk_limits_max_hw_sectors(). | ||
268 | **/ | ||
269 | void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_hw_sectors) | ||
270 | { | ||
271 | blk_limits_max_hw_sectors(&q->limits, max_hw_sectors); | ||
258 | } | 272 | } |
259 | EXPORT_SYMBOL(blk_queue_max_hw_sectors); | 273 | EXPORT_SYMBOL(blk_queue_max_hw_sectors); |
260 | 274 | ||
@@ -464,15 +478,6 @@ EXPORT_SYMBOL(blk_queue_io_opt); | |||
464 | void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b) | 478 | void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b) |
465 | { | 479 | { |
466 | blk_stack_limits(&t->limits, &b->limits, 0); | 480 | blk_stack_limits(&t->limits, &b->limits, 0); |
467 | |||
468 | if (!t->queue_lock) | ||
469 | WARN_ON_ONCE(1); | ||
470 | else if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) { | ||
471 | unsigned long flags; | ||
472 | spin_lock_irqsave(t->queue_lock, flags); | ||
473 | queue_flag_clear(QUEUE_FLAG_CLUSTER, t); | ||
474 | spin_unlock_irqrestore(t->queue_lock, flags); | ||
475 | } | ||
476 | } | 481 | } |
477 | EXPORT_SYMBOL(blk_queue_stack_limits); | 482 | EXPORT_SYMBOL(blk_queue_stack_limits); |
478 | 483 | ||
@@ -545,7 +550,7 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b, | |||
545 | t->io_min = max(t->io_min, b->io_min); | 550 | t->io_min = max(t->io_min, b->io_min); |
546 | t->io_opt = lcm(t->io_opt, b->io_opt); | 551 | t->io_opt = lcm(t->io_opt, b->io_opt); |
547 | 552 | ||
548 | t->no_cluster |= b->no_cluster; | 553 | t->cluster &= b->cluster; |
549 | t->discard_zeroes_data &= b->discard_zeroes_data; | 554 | t->discard_zeroes_data &= b->discard_zeroes_data; |
550 | 555 | ||
551 | /* Physical block size a multiple of the logical block size? */ | 556 | /* Physical block size a multiple of the logical block size? */ |
@@ -641,7 +646,6 @@ void disk_stack_limits(struct gendisk *disk, struct block_device *bdev, | |||
641 | sector_t offset) | 646 | sector_t offset) |
642 | { | 647 | { |
643 | struct request_queue *t = disk->queue; | 648 | struct request_queue *t = disk->queue; |
644 | struct request_queue *b = bdev_get_queue(bdev); | ||
645 | 649 | ||
646 | if (bdev_stack_limits(&t->limits, bdev, offset >> 9) < 0) { | 650 | if (bdev_stack_limits(&t->limits, bdev, offset >> 9) < 0) { |
647 | char top[BDEVNAME_SIZE], bottom[BDEVNAME_SIZE]; | 651 | char top[BDEVNAME_SIZE], bottom[BDEVNAME_SIZE]; |
@@ -652,17 +656,6 @@ void disk_stack_limits(struct gendisk *disk, struct block_device *bdev, | |||
652 | printk(KERN_NOTICE "%s: Warning: Device %s is misaligned\n", | 656 | printk(KERN_NOTICE "%s: Warning: Device %s is misaligned\n", |
653 | top, bottom); | 657 | top, bottom); |
654 | } | 658 | } |
655 | |||
656 | if (!t->queue_lock) | ||
657 | WARN_ON_ONCE(1); | ||
658 | else if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) { | ||
659 | unsigned long flags; | ||
660 | |||
661 | spin_lock_irqsave(t->queue_lock, flags); | ||
662 | if (!test_bit(QUEUE_FLAG_CLUSTER, &b->queue_flags)) | ||
663 | queue_flag_clear(QUEUE_FLAG_CLUSTER, t); | ||
664 | spin_unlock_irqrestore(t->queue_lock, flags); | ||
665 | } | ||
666 | } | 659 | } |
667 | EXPORT_SYMBOL(disk_stack_limits); | 660 | EXPORT_SYMBOL(disk_stack_limits); |
668 | 661 | ||
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c index 013457f47fdc..41fb69150b4d 100644 --- a/block/blk-sysfs.c +++ b/block/blk-sysfs.c | |||
@@ -119,7 +119,7 @@ static ssize_t queue_max_integrity_segments_show(struct request_queue *q, char * | |||
119 | 119 | ||
120 | static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page) | 120 | static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page) |
121 | { | 121 | { |
122 | if (test_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags)) | 122 | if (blk_queue_cluster(q)) |
123 | return queue_var_show(queue_max_segment_size(q), (page)); | 123 | return queue_var_show(queue_max_segment_size(q), (page)); |
124 | 124 | ||
125 | return queue_var_show(PAGE_CACHE_SIZE, (page)); | 125 | return queue_var_show(PAGE_CACHE_SIZE, (page)); |
diff --git a/block/blk-throttle.c b/block/blk-throttle.c index 004be80fd894..381b09bb562b 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c | |||
@@ -355,6 +355,12 @@ throtl_start_new_slice(struct throtl_data *td, struct throtl_grp *tg, bool rw) | |||
355 | tg->slice_end[rw], jiffies); | 355 | tg->slice_end[rw], jiffies); |
356 | } | 356 | } |
357 | 357 | ||
358 | static inline void throtl_set_slice_end(struct throtl_data *td, | ||
359 | struct throtl_grp *tg, bool rw, unsigned long jiffy_end) | ||
360 | { | ||
361 | tg->slice_end[rw] = roundup(jiffy_end, throtl_slice); | ||
362 | } | ||
363 | |||
358 | static inline void throtl_extend_slice(struct throtl_data *td, | 364 | static inline void throtl_extend_slice(struct throtl_data *td, |
359 | struct throtl_grp *tg, bool rw, unsigned long jiffy_end) | 365 | struct throtl_grp *tg, bool rw, unsigned long jiffy_end) |
360 | { | 366 | { |
@@ -391,6 +397,16 @@ throtl_trim_slice(struct throtl_data *td, struct throtl_grp *tg, bool rw) | |||
391 | if (throtl_slice_used(td, tg, rw)) | 397 | if (throtl_slice_used(td, tg, rw)) |
392 | return; | 398 | return; |
393 | 399 | ||
400 | /* | ||
401 | * A bio has been dispatched. Also adjust slice_end. It might happen | ||
402 | * that initially cgroup limit was very low resulting in high | ||
403 | * slice_end, but later limit was bumped up and bio was dispached | ||
404 | * sooner, then we need to reduce slice_end. A high bogus slice_end | ||
405 | * is bad because it does not allow new slice to start. | ||
406 | */ | ||
407 | |||
408 | throtl_set_slice_end(td, tg, rw, jiffies + throtl_slice); | ||
409 | |||
394 | time_elapsed = jiffies - tg->slice_start[rw]; | 410 | time_elapsed = jiffies - tg->slice_start[rw]; |
395 | 411 | ||
396 | nr_slices = time_elapsed / throtl_slice; | 412 | nr_slices = time_elapsed / throtl_slice; |
@@ -709,26 +725,21 @@ static void throtl_process_limit_change(struct throtl_data *td) | |||
709 | struct throtl_grp *tg; | 725 | struct throtl_grp *tg; |
710 | struct hlist_node *pos, *n; | 726 | struct hlist_node *pos, *n; |
711 | 727 | ||
712 | /* | ||
713 | * Make sure atomic_inc() effects from | ||
714 | * throtl_update_blkio_group_read_bps(), group of functions are | ||
715 | * visible. | ||
716 | * Is this required or smp_mb__after_atomic_inc() was suffcient | ||
717 | * after the atomic_inc(). | ||
718 | */ | ||
719 | smp_rmb(); | ||
720 | if (!atomic_read(&td->limits_changed)) | 728 | if (!atomic_read(&td->limits_changed)) |
721 | return; | 729 | return; |
722 | 730 | ||
723 | throtl_log(td, "limit changed =%d", atomic_read(&td->limits_changed)); | 731 | throtl_log(td, "limit changed =%d", atomic_read(&td->limits_changed)); |
724 | 732 | ||
725 | hlist_for_each_entry_safe(tg, pos, n, &td->tg_list, tg_node) { | 733 | /* |
726 | /* | 734 | * Make sure updates from throtl_update_blkio_group_read_bps() group |
727 | * Do I need an smp_rmb() here to make sure tg->limits_changed | 735 | * of functions to tg->limits_changed are visible. We do not |
728 | * update is visible. I am relying on smp_rmb() at the | 736 | * want update td->limits_changed to be visible but update to |
729 | * beginning of function and not putting a new one here. | 737 | * tg->limits_changed not being visible yet on this cpu. Hence |
730 | */ | 738 | * the read barrier. |
739 | */ | ||
740 | smp_rmb(); | ||
731 | 741 | ||
742 | hlist_for_each_entry_safe(tg, pos, n, &td->tg_list, tg_node) { | ||
732 | if (throtl_tg_on_rr(tg) && tg->limits_changed) { | 743 | if (throtl_tg_on_rr(tg) && tg->limits_changed) { |
733 | throtl_log_tg(td, tg, "limit change rbps=%llu wbps=%llu" | 744 | throtl_log_tg(td, tg, "limit change rbps=%llu wbps=%llu" |
734 | " riops=%u wiops=%u", tg->bps[READ], | 745 | " riops=%u wiops=%u", tg->bps[READ], |
diff --git a/block/bsg.c b/block/bsg.c index f20d6a789d48..0c8b64a16484 100644 --- a/block/bsg.c +++ b/block/bsg.c | |||
@@ -250,6 +250,14 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm, | |||
250 | int ret, rw; | 250 | int ret, rw; |
251 | unsigned int dxfer_len; | 251 | unsigned int dxfer_len; |
252 | void *dxferp = NULL; | 252 | void *dxferp = NULL; |
253 | struct bsg_class_device *bcd = &q->bsg_dev; | ||
254 | |||
255 | /* if the LLD has been removed then the bsg_unregister_queue will | ||
256 | * eventually be called and the class_dev was freed, so we can no | ||
257 | * longer use this request_queue. Return no such address. | ||
258 | */ | ||
259 | if (!bcd->class_dev) | ||
260 | return ERR_PTR(-ENXIO); | ||
253 | 261 | ||
254 | dprintk("map hdr %llx/%u %llx/%u\n", (unsigned long long) hdr->dout_xferp, | 262 | dprintk("map hdr %llx/%u %llx/%u\n", (unsigned long long) hdr->dout_xferp, |
255 | hdr->dout_xfer_len, (unsigned long long) hdr->din_xferp, | 263 | hdr->dout_xfer_len, (unsigned long long) hdr->din_xferp, |
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 3d031d02e54b..9cc9f2c4da79 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile | |||
@@ -24,7 +24,7 @@ acpi-y += atomicio.o | |||
24 | # sleep related files | 24 | # sleep related files |
25 | acpi-y += wakeup.o | 25 | acpi-y += wakeup.o |
26 | acpi-y += sleep.o | 26 | acpi-y += sleep.o |
27 | acpi-$(CONFIG_ACPI_SLEEP) += proc.o | 27 | acpi-$(CONFIG_ACPI_SLEEP) += proc.o nvs.o |
28 | 28 | ||
29 | 29 | ||
30 | # | 30 | # |
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index f441e92481f6..58c3f74bd84c 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -100,24 +100,7 @@ static const struct file_operations acpi_ac_fops = { | |||
100 | .release = single_release, | 100 | .release = single_release, |
101 | }; | 101 | }; |
102 | #endif | 102 | #endif |
103 | static int get_ac_property(struct power_supply *psy, | ||
104 | enum power_supply_property psp, | ||
105 | union power_supply_propval *val) | ||
106 | { | ||
107 | struct acpi_ac *ac = to_acpi_ac(psy); | ||
108 | switch (psp) { | ||
109 | case POWER_SUPPLY_PROP_ONLINE: | ||
110 | val->intval = ac->state; | ||
111 | break; | ||
112 | default: | ||
113 | return -EINVAL; | ||
114 | } | ||
115 | return 0; | ||
116 | } | ||
117 | 103 | ||
118 | static enum power_supply_property ac_props[] = { | ||
119 | POWER_SUPPLY_PROP_ONLINE, | ||
120 | }; | ||
121 | /* -------------------------------------------------------------------------- | 104 | /* -------------------------------------------------------------------------- |
122 | AC Adapter Management | 105 | AC Adapter Management |
123 | -------------------------------------------------------------------------- */ | 106 | -------------------------------------------------------------------------- */ |
@@ -140,6 +123,35 @@ static int acpi_ac_get_state(struct acpi_ac *ac) | |||
140 | return 0; | 123 | return 0; |
141 | } | 124 | } |
142 | 125 | ||
126 | /* -------------------------------------------------------------------------- | ||
127 | sysfs I/F | ||
128 | -------------------------------------------------------------------------- */ | ||
129 | static int get_ac_property(struct power_supply *psy, | ||
130 | enum power_supply_property psp, | ||
131 | union power_supply_propval *val) | ||
132 | { | ||
133 | struct acpi_ac *ac = to_acpi_ac(psy); | ||
134 | |||
135 | if (!ac) | ||
136 | return -ENODEV; | ||
137 | |||
138 | if (acpi_ac_get_state(ac)) | ||
139 | return -ENODEV; | ||
140 | |||
141 | switch (psp) { | ||
142 | case POWER_SUPPLY_PROP_ONLINE: | ||
143 | val->intval = ac->state; | ||
144 | break; | ||
145 | default: | ||
146 | return -EINVAL; | ||
147 | } | ||
148 | return 0; | ||
149 | } | ||
150 | |||
151 | static enum power_supply_property ac_props[] = { | ||
152 | POWER_SUPPLY_PROP_ONLINE, | ||
153 | }; | ||
154 | |||
143 | #ifdef CONFIG_ACPI_PROCFS_POWER | 155 | #ifdef CONFIG_ACPI_PROCFS_POWER |
144 | /* -------------------------------------------------------------------------- | 156 | /* -------------------------------------------------------------------------- |
145 | FS Interface (/proc) | 157 | FS Interface (/proc) |
diff --git a/drivers/acpi/acpica/Makefile b/drivers/acpi/acpica/Makefile index a7e1d1aa4107..eec2eadd2431 100644 --- a/drivers/acpi/acpica/Makefile +++ b/drivers/acpi/acpica/Makefile | |||
@@ -14,7 +14,7 @@ acpi-y := dsfield.o dsmthdat.o dsopcode.o dswexec.o dswscope.o \ | |||
14 | 14 | ||
15 | acpi-y += evevent.o evregion.o evsci.o evxfevnt.o \ | 15 | acpi-y += evevent.o evregion.o evsci.o evxfevnt.o \ |
16 | evmisc.o evrgnini.o evxface.o evxfregn.o \ | 16 | evmisc.o evrgnini.o evxface.o evxfregn.o \ |
17 | evgpe.o evgpeblk.o evgpeinit.o evgpeutil.o | 17 | evgpe.o evgpeblk.o evgpeinit.o evgpeutil.o evxfgpe.o |
18 | 18 | ||
19 | acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ | 19 | acpi-y += exconfig.o exfield.o exnames.o exoparg6.o exresolv.o exstorob.o\ |
20 | exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\ | 20 | exconvrt.o exfldio.o exoparg1.o exprep.o exresop.o exsystem.o\ |
diff --git a/drivers/acpi/acpica/acevents.h b/drivers/acpi/acpica/acevents.h index a6f99cc37a19..70e0b28801aa 100644 --- a/drivers/acpi/acpica/acevents.h +++ b/drivers/acpi/acpica/acevents.h | |||
@@ -51,8 +51,6 @@ acpi_status acpi_ev_initialize_events(void); | |||
51 | 51 | ||
52 | acpi_status acpi_ev_install_xrupt_handlers(void); | 52 | acpi_status acpi_ev_install_xrupt_handlers(void); |
53 | 53 | ||
54 | acpi_status acpi_ev_install_fadt_gpes(void); | ||
55 | |||
56 | u32 acpi_ev_fixed_event_detect(void); | 54 | u32 acpi_ev_fixed_event_detect(void); |
57 | 55 | ||
58 | /* | 56 | /* |
@@ -82,9 +80,9 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info); | |||
82 | 80 | ||
83 | acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); | 81 | acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); |
84 | 82 | ||
85 | acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); | 83 | acpi_status acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info); |
86 | 84 | ||
87 | acpi_status acpi_raw_disable_gpe(struct acpi_gpe_event_info *gpe_event_info); | 85 | acpi_status acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info); |
88 | 86 | ||
89 | struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, | 87 | struct acpi_gpe_event_info *acpi_ev_get_gpe_event_info(acpi_handle gpe_device, |
90 | u32 gpe_number); | 88 | u32 gpe_number); |
@@ -93,6 +91,8 @@ struct acpi_gpe_event_info *acpi_ev_low_get_gpe_info(u32 gpe_number, | |||
93 | struct acpi_gpe_block_info | 91 | struct acpi_gpe_block_info |
94 | *gpe_block); | 92 | *gpe_block); |
95 | 93 | ||
94 | acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info); | ||
95 | |||
96 | /* | 96 | /* |
97 | * evgpeblk - Upper-level GPE block support | 97 | * evgpeblk - Upper-level GPE block support |
98 | */ | 98 | */ |
@@ -107,12 +107,13 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
107 | acpi_status | 107 | acpi_status |
108 | acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | 108 | acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
109 | struct acpi_gpe_block_info *gpe_block, | 109 | struct acpi_gpe_block_info *gpe_block, |
110 | void *ignored); | 110 | void *context); |
111 | 111 | ||
112 | acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block); | 112 | acpi_status acpi_ev_delete_gpe_block(struct acpi_gpe_block_info *gpe_block); |
113 | 113 | ||
114 | u32 | 114 | u32 |
115 | acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, | 115 | acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, |
116 | struct acpi_gpe_event_info *gpe_event_info, | ||
116 | u32 gpe_number); | 117 | u32 gpe_number); |
117 | 118 | ||
118 | /* | 119 | /* |
@@ -126,10 +127,6 @@ acpi_status | |||
126 | acpi_ev_match_gpe_method(acpi_handle obj_handle, | 127 | acpi_ev_match_gpe_method(acpi_handle obj_handle, |
127 | u32 level, void *context, void **return_value); | 128 | u32 level, void *context, void **return_value); |
128 | 129 | ||
129 | acpi_status | ||
130 | acpi_ev_match_prw_and_gpe(acpi_handle obj_handle, | ||
131 | u32 level, void *context, void **return_value); | ||
132 | |||
133 | /* | 130 | /* |
134 | * evgpeutil - GPE utilities | 131 | * evgpeutil - GPE utilities |
135 | */ | 132 | */ |
@@ -138,6 +135,10 @@ acpi_ev_walk_gpe_list(acpi_gpe_callback gpe_walk_callback, void *context); | |||
138 | 135 | ||
139 | u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info); | 136 | u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info); |
140 | 137 | ||
138 | acpi_status | ||
139 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | ||
140 | struct acpi_gpe_block_info *gpe_block, void *context); | ||
141 | |||
141 | struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 interrupt_number); | 142 | struct acpi_gpe_xrupt_info *acpi_ev_get_gpe_xrupt_block(u32 interrupt_number); |
142 | 143 | ||
143 | acpi_status acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt); | 144 | acpi_status acpi_ev_delete_gpe_xrupt(struct acpi_gpe_xrupt_info *gpe_xrupt); |
diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h index ad88fcae4eb9..9bb69c59bb12 100644 --- a/drivers/acpi/acpica/acglobal.h +++ b/drivers/acpi/acpica/acglobal.h | |||
@@ -146,6 +146,9 @@ u8 acpi_gbl_system_awake_and_running; | |||
146 | 146 | ||
147 | extern u32 acpi_gbl_nesting_level; | 147 | extern u32 acpi_gbl_nesting_level; |
148 | 148 | ||
149 | ACPI_EXTERN u32 acpi_gpe_count; | ||
150 | ACPI_EXTERN u32 acpi_fixed_event_count[ACPI_NUM_FIXED_EVENTS]; | ||
151 | |||
149 | /* Support for dynamic control method tracing mechanism */ | 152 | /* Support for dynamic control method tracing mechanism */ |
150 | 153 | ||
151 | ACPI_EXTERN u32 acpi_gbl_original_dbg_level; | 154 | ACPI_EXTERN u32 acpi_gbl_original_dbg_level; |
@@ -370,7 +373,9 @@ ACPI_EXTERN struct acpi_fixed_event_handler | |||
370 | ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; | 373 | ACPI_EXTERN struct acpi_gpe_xrupt_info *acpi_gbl_gpe_xrupt_list_head; |
371 | ACPI_EXTERN struct acpi_gpe_block_info | 374 | ACPI_EXTERN struct acpi_gpe_block_info |
372 | *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; | 375 | *acpi_gbl_gpe_fadt_blocks[ACPI_MAX_GPE_BLOCKS]; |
373 | ACPI_EXTERN u8 acpi_all_gpes_initialized; | 376 | ACPI_EXTERN u8 acpi_gbl_all_gpes_initialized; |
377 | ACPI_EXTERN ACPI_GBL_EVENT_HANDLER acpi_gbl_global_event_handler; | ||
378 | ACPI_EXTERN void *acpi_gbl_global_event_handler_context; | ||
374 | 379 | ||
375 | /***************************************************************************** | 380 | /***************************************************************************** |
376 | * | 381 | * |
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index 167470ad2d21..258d628793ea 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h | |||
@@ -94,7 +94,7 @@ u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info, | |||
94 | struct acpi_gpe_register_info *gpe_register_info); | 94 | struct acpi_gpe_register_info *gpe_register_info); |
95 | 95 | ||
96 | acpi_status | 96 | acpi_status |
97 | acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action); | 97 | acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action); |
98 | 98 | ||
99 | acpi_status | 99 | acpi_status |
100 | acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | 100 | acpi_hw_disable_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, |
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 2ceb0c05b2d7..74000f5b7dab 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
@@ -408,17 +408,18 @@ struct acpi_predefined_data { | |||
408 | 408 | ||
409 | /* Dispatch info for each GPE -- either a method or handler, cannot be both */ | 409 | /* Dispatch info for each GPE -- either a method or handler, cannot be both */ |
410 | 410 | ||
411 | struct acpi_handler_info { | 411 | struct acpi_gpe_handler_info { |
412 | acpi_event_handler address; /* Address of handler, if any */ | 412 | acpi_gpe_handler address; /* Address of handler, if any */ |
413 | void *context; /* Context to be passed to handler */ | 413 | void *context; /* Context to be passed to handler */ |
414 | struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */ | 414 | struct acpi_namespace_node *method_node; /* Method node for this GPE level (saved) */ |
415 | u8 orig_flags; /* Original misc info about this GPE */ | 415 | u8 original_flags; /* Original (pre-handler) GPE info */ |
416 | u8 orig_enabled; /* Set if the GPE was originally enabled */ | 416 | u8 originally_enabled; /* True if GPE was originally enabled */ |
417 | }; | 417 | }; |
418 | 418 | ||
419 | union acpi_gpe_dispatch_info { | 419 | union acpi_gpe_dispatch_info { |
420 | struct acpi_namespace_node *method_node; /* Method node for this GPE level */ | 420 | struct acpi_namespace_node *method_node; /* Method node for this GPE level */ |
421 | struct acpi_handler_info *handler; | 421 | struct acpi_gpe_handler_info *handler; /* Installed GPE handler */ |
422 | struct acpi_namespace_node *device_node; /* Parent _PRW device for implicit notify */ | ||
422 | }; | 423 | }; |
423 | 424 | ||
424 | /* | 425 | /* |
@@ -458,7 +459,7 @@ struct acpi_gpe_block_info { | |||
458 | u32 register_count; /* Number of register pairs in block */ | 459 | u32 register_count; /* Number of register pairs in block */ |
459 | u16 gpe_count; /* Number of individual GPEs in block */ | 460 | u16 gpe_count; /* Number of individual GPEs in block */ |
460 | u8 block_base_number; /* Base GPE number for this block */ | 461 | u8 block_base_number; /* Base GPE number for this block */ |
461 | u8 initialized; /* If set, the GPE block has been initialized */ | 462 | u8 initialized; /* TRUE if this block is initialized */ |
462 | }; | 463 | }; |
463 | 464 | ||
464 | /* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */ | 465 | /* Information about GPE interrupt handlers, one per each interrupt level used for GPEs */ |
diff --git a/drivers/acpi/acpica/evevent.c b/drivers/acpi/acpica/evevent.c index c61c3039c31a..e5e313c663a5 100644 --- a/drivers/acpi/acpica/evevent.c +++ b/drivers/acpi/acpica/evevent.c | |||
@@ -217,9 +217,17 @@ u32 acpi_ev_fixed_event_detect(void) | |||
217 | status_bit_mask) | 217 | status_bit_mask) |
218 | && (fixed_enable & acpi_gbl_fixed_event_info[i]. | 218 | && (fixed_enable & acpi_gbl_fixed_event_info[i]. |
219 | enable_bit_mask)) { | 219 | enable_bit_mask)) { |
220 | /* | ||
221 | * Found an active (signalled) event. Invoke global event | ||
222 | * handler if present. | ||
223 | */ | ||
224 | acpi_fixed_event_count[i]++; | ||
225 | if (acpi_gbl_global_event_handler) { | ||
226 | acpi_gbl_global_event_handler | ||
227 | (ACPI_EVENT_TYPE_FIXED, NULL, i, | ||
228 | acpi_gbl_global_event_handler_context); | ||
229 | } | ||
220 | 230 | ||
221 | /* Found an active (signalled) event */ | ||
222 | acpi_os_fixed_event_count(i); | ||
223 | int_status |= acpi_ev_fixed_event_dispatch(i); | 231 | int_status |= acpi_ev_fixed_event_dispatch(i); |
224 | } | 232 | } |
225 | } | 233 | } |
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index f226eac314db..7c339d34ab42 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c | |||
@@ -52,6 +52,8 @@ ACPI_MODULE_NAME("evgpe") | |||
52 | /* Local prototypes */ | 52 | /* Local prototypes */ |
53 | static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context); | 53 | static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context); |
54 | 54 | ||
55 | static void ACPI_SYSTEM_XFACE acpi_ev_asynch_enable_gpe(void *context); | ||
56 | |||
55 | /******************************************************************************* | 57 | /******************************************************************************* |
56 | * | 58 | * |
57 | * FUNCTION: acpi_ev_update_gpe_enable_mask | 59 | * FUNCTION: acpi_ev_update_gpe_enable_mask |
@@ -102,7 +104,7 @@ acpi_ev_update_gpe_enable_mask(struct acpi_gpe_event_info *gpe_event_info) | |||
102 | * | 104 | * |
103 | * RETURN: Status | 105 | * RETURN: Status |
104 | * | 106 | * |
105 | * DESCRIPTION: Clear the given GPE from stale events and enable it. | 107 | * DESCRIPTION: Clear a GPE of stale events and enable it. |
106 | * | 108 | * |
107 | ******************************************************************************/ | 109 | ******************************************************************************/ |
108 | acpi_status | 110 | acpi_status |
@@ -113,12 +115,13 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
113 | ACPI_FUNCTION_TRACE(ev_enable_gpe); | 115 | ACPI_FUNCTION_TRACE(ev_enable_gpe); |
114 | 116 | ||
115 | /* | 117 | /* |
116 | * We will only allow a GPE to be enabled if it has either an | 118 | * We will only allow a GPE to be enabled if it has either an associated |
117 | * associated method (_Lxx/_Exx) or a handler. Otherwise, the | 119 | * method (_Lxx/_Exx) or a handler, or is using the implicit notify |
118 | * GPE will be immediately disabled by acpi_ev_gpe_dispatch the | 120 | * feature. Otherwise, the GPE will be immediately disabled by |
119 | * first time it fires. | 121 | * acpi_ev_gpe_dispatch the first time it fires. |
120 | */ | 122 | */ |
121 | if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)) { | 123 | if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == |
124 | ACPI_GPE_DISPATCH_NONE) { | ||
122 | return_ACPI_STATUS(AE_NO_HANDLER); | 125 | return_ACPI_STATUS(AE_NO_HANDLER); |
123 | } | 126 | } |
124 | 127 | ||
@@ -137,9 +140,9 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
137 | 140 | ||
138 | /******************************************************************************* | 141 | /******************************************************************************* |
139 | * | 142 | * |
140 | * FUNCTION: acpi_raw_enable_gpe | 143 | * FUNCTION: acpi_ev_add_gpe_reference |
141 | * | 144 | * |
142 | * PARAMETERS: gpe_event_info - GPE to enable | 145 | * PARAMETERS: gpe_event_info - Add a reference to this GPE |
143 | * | 146 | * |
144 | * RETURN: Status | 147 | * RETURN: Status |
145 | * | 148 | * |
@@ -148,16 +151,21 @@ acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
148 | * | 151 | * |
149 | ******************************************************************************/ | 152 | ******************************************************************************/ |
150 | 153 | ||
151 | acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) | 154 | acpi_status acpi_ev_add_gpe_reference(struct acpi_gpe_event_info *gpe_event_info) |
152 | { | 155 | { |
153 | acpi_status status = AE_OK; | 156 | acpi_status status = AE_OK; |
154 | 157 | ||
158 | ACPI_FUNCTION_TRACE(ev_add_gpe_reference); | ||
159 | |||
155 | if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) { | 160 | if (gpe_event_info->runtime_count == ACPI_UINT8_MAX) { |
156 | return_ACPI_STATUS(AE_LIMIT); | 161 | return_ACPI_STATUS(AE_LIMIT); |
157 | } | 162 | } |
158 | 163 | ||
159 | gpe_event_info->runtime_count++; | 164 | gpe_event_info->runtime_count++; |
160 | if (gpe_event_info->runtime_count == 1) { | 165 | if (gpe_event_info->runtime_count == 1) { |
166 | |||
167 | /* Enable on first reference */ | ||
168 | |||
161 | status = acpi_ev_update_gpe_enable_mask(gpe_event_info); | 169 | status = acpi_ev_update_gpe_enable_mask(gpe_event_info); |
162 | if (ACPI_SUCCESS(status)) { | 170 | if (ACPI_SUCCESS(status)) { |
163 | status = acpi_ev_enable_gpe(gpe_event_info); | 171 | status = acpi_ev_enable_gpe(gpe_event_info); |
@@ -173,9 +181,9 @@ acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
173 | 181 | ||
174 | /******************************************************************************* | 182 | /******************************************************************************* |
175 | * | 183 | * |
176 | * FUNCTION: acpi_raw_disable_gpe | 184 | * FUNCTION: acpi_ev_remove_gpe_reference |
177 | * | 185 | * |
178 | * PARAMETERS: gpe_event_info - GPE to disable | 186 | * PARAMETERS: gpe_event_info - Remove a reference to this GPE |
179 | * | 187 | * |
180 | * RETURN: Status | 188 | * RETURN: Status |
181 | * | 189 | * |
@@ -184,16 +192,21 @@ acpi_status acpi_raw_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) | |||
184 | * | 192 | * |
185 | ******************************************************************************/ | 193 | ******************************************************************************/ |
186 | 194 | ||
187 | acpi_status acpi_raw_disable_gpe(struct acpi_gpe_event_info *gpe_event_info) | 195 | acpi_status acpi_ev_remove_gpe_reference(struct acpi_gpe_event_info *gpe_event_info) |
188 | { | 196 | { |
189 | acpi_status status = AE_OK; | 197 | acpi_status status = AE_OK; |
190 | 198 | ||
199 | ACPI_FUNCTION_TRACE(ev_remove_gpe_reference); | ||
200 | |||
191 | if (!gpe_event_info->runtime_count) { | 201 | if (!gpe_event_info->runtime_count) { |
192 | return_ACPI_STATUS(AE_LIMIT); | 202 | return_ACPI_STATUS(AE_LIMIT); |
193 | } | 203 | } |
194 | 204 | ||
195 | gpe_event_info->runtime_count--; | 205 | gpe_event_info->runtime_count--; |
196 | if (!gpe_event_info->runtime_count) { | 206 | if (!gpe_event_info->runtime_count) { |
207 | |||
208 | /* Disable on last reference */ | ||
209 | |||
197 | status = acpi_ev_update_gpe_enable_mask(gpe_event_info); | 210 | status = acpi_ev_update_gpe_enable_mask(gpe_event_info); |
198 | if (ACPI_SUCCESS(status)) { | 211 | if (ACPI_SUCCESS(status)) { |
199 | status = acpi_hw_low_set_gpe(gpe_event_info, | 212 | status = acpi_hw_low_set_gpe(gpe_event_info, |
@@ -379,7 +392,7 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) | |||
379 | } | 392 | } |
380 | 393 | ||
381 | ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, | 394 | ACPI_DEBUG_PRINT((ACPI_DB_INTERRUPTS, |
382 | "Read GPE Register at GPE%X: Status=%02X, Enable=%02X\n", | 395 | "Read GPE Register at GPE%02X: Status=%02X, Enable=%02X\n", |
383 | gpe_register_info->base_gpe_number, | 396 | gpe_register_info->base_gpe_number, |
384 | status_reg, enable_reg)); | 397 | status_reg, enable_reg)); |
385 | 398 | ||
@@ -405,7 +418,9 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) | |||
405 | * or method. | 418 | * or method. |
406 | */ | 419 | */ |
407 | int_status |= | 420 | int_status |= |
408 | acpi_ev_gpe_dispatch(&gpe_block-> | 421 | acpi_ev_gpe_dispatch(gpe_block-> |
422 | node, | ||
423 | &gpe_block-> | ||
409 | event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number); | 424 | event_info[((acpi_size) i * ACPI_GPE_REGISTER_WIDTH) + j], j + gpe_register_info->base_gpe_number); |
410 | } | 425 | } |
411 | } | 426 | } |
@@ -435,17 +450,25 @@ u32 acpi_ev_gpe_detect(struct acpi_gpe_xrupt_info * gpe_xrupt_list) | |||
435 | * an interrupt handler. | 450 | * an interrupt handler. |
436 | * | 451 | * |
437 | ******************************************************************************/ | 452 | ******************************************************************************/ |
438 | static void acpi_ev_asynch_enable_gpe(void *context); | ||
439 | 453 | ||
440 | static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | 454 | static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) |
441 | { | 455 | { |
442 | struct acpi_gpe_event_info *gpe_event_info = (void *)context; | 456 | struct acpi_gpe_event_info *gpe_event_info = context; |
443 | acpi_status status; | 457 | acpi_status status; |
444 | struct acpi_gpe_event_info local_gpe_event_info; | 458 | struct acpi_gpe_event_info *local_gpe_event_info; |
445 | struct acpi_evaluate_info *info; | 459 | struct acpi_evaluate_info *info; |
446 | 460 | ||
447 | ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method); | 461 | ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method); |
448 | 462 | ||
463 | /* Allocate a local GPE block */ | ||
464 | |||
465 | local_gpe_event_info = | ||
466 | ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_event_info)); | ||
467 | if (!local_gpe_event_info) { | ||
468 | ACPI_EXCEPTION((AE_INFO, AE_NO_MEMORY, "while handling a GPE")); | ||
469 | return_VOID; | ||
470 | } | ||
471 | |||
449 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | 472 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); |
450 | if (ACPI_FAILURE(status)) { | 473 | if (ACPI_FAILURE(status)) { |
451 | return_VOID; | 474 | return_VOID; |
@@ -462,7 +485,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | |||
462 | * Take a snapshot of the GPE info for this level - we copy the info to | 485 | * Take a snapshot of the GPE info for this level - we copy the info to |
463 | * prevent a race condition with remove_handler/remove_block. | 486 | * prevent a race condition with remove_handler/remove_block. |
464 | */ | 487 | */ |
465 | ACPI_MEMCPY(&local_gpe_event_info, gpe_event_info, | 488 | ACPI_MEMCPY(local_gpe_event_info, gpe_event_info, |
466 | sizeof(struct acpi_gpe_event_info)); | 489 | sizeof(struct acpi_gpe_event_info)); |
467 | 490 | ||
468 | status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); | 491 | status = acpi_ut_release_mutex(ACPI_MTX_EVENTS); |
@@ -470,12 +493,26 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | |||
470 | return_VOID; | 493 | return_VOID; |
471 | } | 494 | } |
472 | 495 | ||
473 | /* | 496 | /* Do the correct dispatch - normal method or implicit notify */ |
474 | * Must check for control method type dispatch one more time to avoid a | 497 | |
475 | * race with ev_gpe_install_handler | 498 | switch (local_gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { |
476 | */ | 499 | case ACPI_GPE_DISPATCH_NOTIFY: |
477 | if ((local_gpe_event_info.flags & ACPI_GPE_DISPATCH_MASK) == | 500 | |
478 | ACPI_GPE_DISPATCH_METHOD) { | 501 | /* |
502 | * Implicit notify. | ||
503 | * Dispatch a DEVICE_WAKE notify to the appropriate handler. | ||
504 | * NOTE: the request is queued for execution after this method | ||
505 | * completes. The notify handlers are NOT invoked synchronously | ||
506 | * from this thread -- because handlers may in turn run other | ||
507 | * control methods. | ||
508 | */ | ||
509 | status = | ||
510 | acpi_ev_queue_notify_request(local_gpe_event_info->dispatch. | ||
511 | device_node, | ||
512 | ACPI_NOTIFY_DEVICE_WAKE); | ||
513 | break; | ||
514 | |||
515 | case ACPI_GPE_DISPATCH_METHOD: | ||
479 | 516 | ||
480 | /* Allocate the evaluation information block */ | 517 | /* Allocate the evaluation information block */ |
481 | 518 | ||
@@ -488,7 +525,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | |||
488 | * control method that corresponds to this GPE | 525 | * control method that corresponds to this GPE |
489 | */ | 526 | */ |
490 | info->prefix_node = | 527 | info->prefix_node = |
491 | local_gpe_event_info.dispatch.method_node; | 528 | local_gpe_event_info->dispatch.method_node; |
492 | info->flags = ACPI_IGNORE_RETURN_VALUE; | 529 | info->flags = ACPI_IGNORE_RETURN_VALUE; |
493 | 530 | ||
494 | status = acpi_ns_evaluate(info); | 531 | status = acpi_ns_evaluate(info); |
@@ -499,46 +536,98 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | |||
499 | ACPI_EXCEPTION((AE_INFO, status, | 536 | ACPI_EXCEPTION((AE_INFO, status, |
500 | "while evaluating GPE method [%4.4s]", | 537 | "while evaluating GPE method [%4.4s]", |
501 | acpi_ut_get_node_name | 538 | acpi_ut_get_node_name |
502 | (local_gpe_event_info.dispatch. | 539 | (local_gpe_event_info->dispatch. |
503 | method_node))); | 540 | method_node))); |
504 | } | 541 | } |
542 | |||
543 | break; | ||
544 | |||
545 | default: | ||
546 | return_VOID; /* Should never happen */ | ||
505 | } | 547 | } |
548 | |||
506 | /* Defer enabling of GPE until all notify handlers are done */ | 549 | /* Defer enabling of GPE until all notify handlers are done */ |
507 | acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_asynch_enable_gpe, | 550 | |
508 | gpe_event_info); | 551 | status = acpi_os_execute(OSL_NOTIFY_HANDLER, |
552 | acpi_ev_asynch_enable_gpe, | ||
553 | local_gpe_event_info); | ||
554 | if (ACPI_FAILURE(status)) { | ||
555 | ACPI_FREE(local_gpe_event_info); | ||
556 | } | ||
509 | return_VOID; | 557 | return_VOID; |
510 | } | 558 | } |
511 | 559 | ||
512 | static void acpi_ev_asynch_enable_gpe(void *context) | 560 | |
561 | /******************************************************************************* | ||
562 | * | ||
563 | * FUNCTION: acpi_ev_asynch_enable_gpe | ||
564 | * | ||
565 | * PARAMETERS: Context (gpe_event_info) - Info for this GPE | ||
566 | * Callback from acpi_os_execute | ||
567 | * | ||
568 | * RETURN: None | ||
569 | * | ||
570 | * DESCRIPTION: Asynchronous clear/enable for GPE. This allows the GPE to | ||
571 | * complete (i.e., finish execution of Notify) | ||
572 | * | ||
573 | ******************************************************************************/ | ||
574 | |||
575 | static void ACPI_SYSTEM_XFACE acpi_ev_asynch_enable_gpe(void *context) | ||
513 | { | 576 | { |
514 | struct acpi_gpe_event_info *gpe_event_info = context; | 577 | struct acpi_gpe_event_info *gpe_event_info = context; |
578 | |||
579 | (void)acpi_ev_finish_gpe(gpe_event_info); | ||
580 | |||
581 | ACPI_FREE(gpe_event_info); | ||
582 | return; | ||
583 | } | ||
584 | |||
585 | |||
586 | /******************************************************************************* | ||
587 | * | ||
588 | * FUNCTION: acpi_ev_finish_gpe | ||
589 | * | ||
590 | * PARAMETERS: gpe_event_info - Info for this GPE | ||
591 | * | ||
592 | * RETURN: Status | ||
593 | * | ||
594 | * DESCRIPTION: Clear/Enable a GPE. Common code that is used after execution | ||
595 | * of a GPE method or a synchronous or asynchronous GPE handler. | ||
596 | * | ||
597 | ******************************************************************************/ | ||
598 | |||
599 | acpi_status acpi_ev_finish_gpe(struct acpi_gpe_event_info *gpe_event_info) | ||
600 | { | ||
515 | acpi_status status; | 601 | acpi_status status; |
602 | |||
516 | if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == | 603 | if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == |
517 | ACPI_GPE_LEVEL_TRIGGERED) { | 604 | ACPI_GPE_LEVEL_TRIGGERED) { |
518 | /* | 605 | /* |
519 | * GPE is level-triggered, we clear the GPE status bit after handling | 606 | * GPE is level-triggered, we clear the GPE status bit after |
520 | * the event. | 607 | * handling the event. |
521 | */ | 608 | */ |
522 | status = acpi_hw_clear_gpe(gpe_event_info); | 609 | status = acpi_hw_clear_gpe(gpe_event_info); |
523 | if (ACPI_FAILURE(status)) { | 610 | if (ACPI_FAILURE(status)) { |
524 | return_VOID; | 611 | return (status); |
525 | } | 612 | } |
526 | } | 613 | } |
527 | 614 | ||
528 | /* | 615 | /* |
529 | * Enable this GPE, conditionally. This means that the GPE will only be | 616 | * Enable this GPE, conditionally. This means that the GPE will |
530 | * physically enabled if the enable_for_run bit is set in the event_info | 617 | * only be physically enabled if the enable_for_run bit is set |
618 | * in the event_info. | ||
531 | */ | 619 | */ |
532 | (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_COND_ENABLE); | 620 | (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_CONDITIONAL_ENABLE); |
533 | 621 | return (AE_OK); | |
534 | return_VOID; | ||
535 | } | 622 | } |
536 | 623 | ||
624 | |||
537 | /******************************************************************************* | 625 | /******************************************************************************* |
538 | * | 626 | * |
539 | * FUNCTION: acpi_ev_gpe_dispatch | 627 | * FUNCTION: acpi_ev_gpe_dispatch |
540 | * | 628 | * |
541 | * PARAMETERS: gpe_event_info - Info for this GPE | 629 | * PARAMETERS: gpe_device - Device node. NULL for GPE0/GPE1 |
630 | * gpe_event_info - Info for this GPE | ||
542 | * gpe_number - Number relative to the parent GPE block | 631 | * gpe_number - Number relative to the parent GPE block |
543 | * | 632 | * |
544 | * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED | 633 | * RETURN: INTERRUPT_HANDLED or INTERRUPT_NOT_HANDLED |
@@ -551,13 +640,22 @@ static void acpi_ev_asynch_enable_gpe(void *context) | |||
551 | ******************************************************************************/ | 640 | ******************************************************************************/ |
552 | 641 | ||
553 | u32 | 642 | u32 |
554 | acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) | 643 | acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device, |
644 | struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) | ||
555 | { | 645 | { |
556 | acpi_status status; | 646 | acpi_status status; |
647 | u32 return_value; | ||
557 | 648 | ||
558 | ACPI_FUNCTION_TRACE(ev_gpe_dispatch); | 649 | ACPI_FUNCTION_TRACE(ev_gpe_dispatch); |
559 | 650 | ||
560 | acpi_os_gpe_count(gpe_number); | 651 | /* Invoke global event handler if present */ |
652 | |||
653 | acpi_gpe_count++; | ||
654 | if (acpi_gbl_global_event_handler) { | ||
655 | acpi_gbl_global_event_handler(ACPI_EVENT_TYPE_GPE, gpe_device, | ||
656 | gpe_number, | ||
657 | acpi_gbl_global_event_handler_context); | ||
658 | } | ||
561 | 659 | ||
562 | /* | 660 | /* |
563 | * If edge-triggered, clear the GPE status bit now. Note that | 661 | * If edge-triggered, clear the GPE status bit now. Note that |
@@ -568,59 +666,55 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) | |||
568 | status = acpi_hw_clear_gpe(gpe_event_info); | 666 | status = acpi_hw_clear_gpe(gpe_event_info); |
569 | if (ACPI_FAILURE(status)) { | 667 | if (ACPI_FAILURE(status)) { |
570 | ACPI_EXCEPTION((AE_INFO, status, | 668 | ACPI_EXCEPTION((AE_INFO, status, |
571 | "Unable to clear GPE[0x%2X]", | 669 | "Unable to clear GPE%02X", gpe_number)); |
572 | gpe_number)); | ||
573 | return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); | 670 | return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); |
574 | } | 671 | } |
575 | } | 672 | } |
576 | 673 | ||
577 | /* | 674 | /* |
578 | * Dispatch the GPE to either an installed handler, or the control method | 675 | * Always disable the GPE so that it does not keep firing before |
579 | * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke | 676 | * any asynchronous activity completes (either from the execution |
580 | * it and do not attempt to run the method. If there is neither a handler | 677 | * of a GPE method or an asynchronous GPE handler.) |
581 | * nor a method, we disable this GPE to prevent further such pointless | 678 | * |
582 | * events from firing. | 679 | * If there is no handler or method to run, just disable the |
680 | * GPE and leave it disabled permanently to prevent further such | ||
681 | * pointless events from firing. | ||
682 | */ | ||
683 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); | ||
684 | if (ACPI_FAILURE(status)) { | ||
685 | ACPI_EXCEPTION((AE_INFO, status, | ||
686 | "Unable to disable GPE%02X", gpe_number)); | ||
687 | return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); | ||
688 | } | ||
689 | |||
690 | /* | ||
691 | * Dispatch the GPE to either an installed handler or the control | ||
692 | * method associated with this GPE (_Lxx or _Exx). If a handler | ||
693 | * exists, we invoke it and do not attempt to run the method. | ||
694 | * If there is neither a handler nor a method, leave the GPE | ||
695 | * disabled. | ||
583 | */ | 696 | */ |
584 | switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { | 697 | switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) { |
585 | case ACPI_GPE_DISPATCH_HANDLER: | 698 | case ACPI_GPE_DISPATCH_HANDLER: |
586 | 699 | ||
587 | /* | 700 | /* Invoke the installed handler (at interrupt level) */ |
588 | * Invoke the installed handler (at interrupt level) | ||
589 | * Ignore return status for now. | ||
590 | * TBD: leave GPE disabled on error? | ||
591 | */ | ||
592 | (void)gpe_event_info->dispatch.handler->address(gpe_event_info-> | ||
593 | dispatch. | ||
594 | handler-> | ||
595 | context); | ||
596 | 701 | ||
597 | /* It is now safe to clear level-triggered events. */ | 702 | return_value = |
703 | gpe_event_info->dispatch.handler->address(gpe_device, | ||
704 | gpe_number, | ||
705 | gpe_event_info-> | ||
706 | dispatch.handler-> | ||
707 | context); | ||
598 | 708 | ||
599 | if ((gpe_event_info->flags & ACPI_GPE_XRUPT_TYPE_MASK) == | 709 | /* If requested, clear (if level-triggered) and reenable the GPE */ |
600 | ACPI_GPE_LEVEL_TRIGGERED) { | 710 | |
601 | status = acpi_hw_clear_gpe(gpe_event_info); | 711 | if (return_value & ACPI_REENABLE_GPE) { |
602 | if (ACPI_FAILURE(status)) { | 712 | (void)acpi_ev_finish_gpe(gpe_event_info); |
603 | ACPI_EXCEPTION((AE_INFO, status, | ||
604 | "Unable to clear GPE[0x%2X]", | ||
605 | gpe_number)); | ||
606 | return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); | ||
607 | } | ||
608 | } | 713 | } |
609 | break; | 714 | break; |
610 | 715 | ||
611 | case ACPI_GPE_DISPATCH_METHOD: | 716 | case ACPI_GPE_DISPATCH_METHOD: |
612 | 717 | case ACPI_GPE_DISPATCH_NOTIFY: | |
613 | /* | ||
614 | * Disable the GPE, so it doesn't keep firing before the method has a | ||
615 | * chance to run (it runs asynchronously with interrupts enabled). | ||
616 | */ | ||
617 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); | ||
618 | if (ACPI_FAILURE(status)) { | ||
619 | ACPI_EXCEPTION((AE_INFO, status, | ||
620 | "Unable to disable GPE[0x%2X]", | ||
621 | gpe_number)); | ||
622 | return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); | ||
623 | } | ||
624 | 718 | ||
625 | /* | 719 | /* |
626 | * Execute the method associated with the GPE | 720 | * Execute the method associated with the GPE |
@@ -631,7 +725,7 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) | |||
631 | gpe_event_info); | 725 | gpe_event_info); |
632 | if (ACPI_FAILURE(status)) { | 726 | if (ACPI_FAILURE(status)) { |
633 | ACPI_EXCEPTION((AE_INFO, status, | 727 | ACPI_EXCEPTION((AE_INFO, status, |
634 | "Unable to queue handler for GPE[0x%2X] - event disabled", | 728 | "Unable to queue handler for GPE%2X - event disabled", |
635 | gpe_number)); | 729 | gpe_number)); |
636 | } | 730 | } |
637 | break; | 731 | break; |
@@ -644,20 +738,9 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number) | |||
644 | * a GPE to be enabled if it has no handler or method. | 738 | * a GPE to be enabled if it has no handler or method. |
645 | */ | 739 | */ |
646 | ACPI_ERROR((AE_INFO, | 740 | ACPI_ERROR((AE_INFO, |
647 | "No handler or method for GPE[0x%2X], disabling event", | 741 | "No handler or method for GPE%02X, disabling event", |
648 | gpe_number)); | 742 | gpe_number)); |
649 | 743 | ||
650 | /* | ||
651 | * Disable the GPE. The GPE will remain disabled a handler | ||
652 | * is installed or ACPICA is restarted. | ||
653 | */ | ||
654 | status = acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); | ||
655 | if (ACPI_FAILURE(status)) { | ||
656 | ACPI_EXCEPTION((AE_INFO, status, | ||
657 | "Unable to disable GPE[0x%2X]", | ||
658 | gpe_number)); | ||
659 | return_UINT32(ACPI_INTERRUPT_NOT_HANDLED); | ||
660 | } | ||
661 | break; | 744 | break; |
662 | } | 745 | } |
663 | 746 | ||
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c index 020add3eee1c..9acb86958c09 100644 --- a/drivers/acpi/acpica/evgpeblk.c +++ b/drivers/acpi/acpica/evgpeblk.c | |||
@@ -361,9 +361,9 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
361 | 361 | ||
362 | gpe_block->node = gpe_device; | 362 | gpe_block->node = gpe_device; |
363 | gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH); | 363 | gpe_block->gpe_count = (u16)(register_count * ACPI_GPE_REGISTER_WIDTH); |
364 | gpe_block->initialized = FALSE; | ||
364 | gpe_block->register_count = register_count; | 365 | gpe_block->register_count = register_count; |
365 | gpe_block->block_base_number = gpe_block_base_number; | 366 | gpe_block->block_base_number = gpe_block_base_number; |
366 | gpe_block->initialized = FALSE; | ||
367 | 367 | ||
368 | ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address, | 368 | ACPI_MEMCPY(&gpe_block->block_address, gpe_block_address, |
369 | sizeof(struct acpi_generic_address)); | 369 | sizeof(struct acpi_generic_address)); |
@@ -386,7 +386,7 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
386 | return_ACPI_STATUS(status); | 386 | return_ACPI_STATUS(status); |
387 | } | 387 | } |
388 | 388 | ||
389 | acpi_all_gpes_initialized = FALSE; | 389 | acpi_gbl_all_gpes_initialized = FALSE; |
390 | 390 | ||
391 | /* Find all GPE methods (_Lxx or_Exx) for this block */ | 391 | /* Find all GPE methods (_Lxx or_Exx) for this block */ |
392 | 392 | ||
@@ -423,14 +423,12 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device, | |||
423 | * | 423 | * |
424 | * FUNCTION: acpi_ev_initialize_gpe_block | 424 | * FUNCTION: acpi_ev_initialize_gpe_block |
425 | * | 425 | * |
426 | * PARAMETERS: gpe_device - Handle to the parent GPE block | 426 | * PARAMETERS: acpi_gpe_callback |
427 | * gpe_block - Gpe Block info | ||
428 | * | 427 | * |
429 | * RETURN: Status | 428 | * RETURN: Status |
430 | * | 429 | * |
431 | * DESCRIPTION: Initialize and enable a GPE block. First find and run any | 430 | * DESCRIPTION: Initialize and enable a GPE block. Enable GPEs that have |
432 | * _PRT methods associated with the block, then enable the | 431 | * associated methods. |
433 | * appropriate GPEs. | ||
434 | * Note: Assumes namespace is locked. | 432 | * Note: Assumes namespace is locked. |
435 | * | 433 | * |
436 | ******************************************************************************/ | 434 | ******************************************************************************/ |
@@ -450,8 +448,8 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
450 | ACPI_FUNCTION_TRACE(ev_initialize_gpe_block); | 448 | ACPI_FUNCTION_TRACE(ev_initialize_gpe_block); |
451 | 449 | ||
452 | /* | 450 | /* |
453 | * Ignore a null GPE block (e.g., if no GPE block 1 exists) and | 451 | * Ignore a null GPE block (e.g., if no GPE block 1 exists), and |
454 | * GPE blocks that have been initialized already. | 452 | * any GPE blocks that have been initialized already. |
455 | */ | 453 | */ |
456 | if (!gpe_block || gpe_block->initialized) { | 454 | if (!gpe_block || gpe_block->initialized) { |
457 | return_ACPI_STATUS(AE_OK); | 455 | return_ACPI_STATUS(AE_OK); |
@@ -459,8 +457,8 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
459 | 457 | ||
460 | /* | 458 | /* |
461 | * Enable all GPEs that have a corresponding method and have the | 459 | * Enable all GPEs that have a corresponding method and have the |
462 | * ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block must | 460 | * ACPI_GPE_CAN_WAKE flag unset. Any other GPEs within this block |
463 | * be enabled via the acpi_enable_gpe() interface. | 461 | * must be enabled via the acpi_enable_gpe() interface. |
464 | */ | 462 | */ |
465 | gpe_enabled_count = 0; | 463 | gpe_enabled_count = 0; |
466 | 464 | ||
@@ -472,14 +470,19 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
472 | gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j; | 470 | gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j; |
473 | gpe_event_info = &gpe_block->event_info[gpe_index]; | 471 | gpe_event_info = &gpe_block->event_info[gpe_index]; |
474 | 472 | ||
475 | /* Ignore GPEs that have no corresponding _Lxx/_Exx method */ | 473 | /* |
476 | 474 | * Ignore GPEs that have no corresponding _Lxx/_Exx method | |
477 | if (!(gpe_event_info->flags & ACPI_GPE_DISPATCH_METHOD) | 475 | * and GPEs that are used to wake the system |
476 | */ | ||
477 | if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == | ||
478 | ACPI_GPE_DISPATCH_NONE) | ||
479 | || ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) | ||
480 | == ACPI_GPE_DISPATCH_HANDLER) | ||
478 | || (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { | 481 | || (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { |
479 | continue; | 482 | continue; |
480 | } | 483 | } |
481 | 484 | ||
482 | status = acpi_raw_enable_gpe(gpe_event_info); | 485 | status = acpi_ev_add_gpe_reference(gpe_event_info); |
483 | if (ACPI_FAILURE(status)) { | 486 | if (ACPI_FAILURE(status)) { |
484 | ACPI_EXCEPTION((AE_INFO, status, | 487 | ACPI_EXCEPTION((AE_INFO, status, |
485 | "Could not enable GPE 0x%02X", | 488 | "Could not enable GPE 0x%02X", |
diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c index 2c7def95f721..c59dc2340593 100644 --- a/drivers/acpi/acpica/evgpeinit.c +++ b/drivers/acpi/acpica/evgpeinit.c | |||
@@ -45,11 +45,27 @@ | |||
45 | #include "accommon.h" | 45 | #include "accommon.h" |
46 | #include "acevents.h" | 46 | #include "acevents.h" |
47 | #include "acnamesp.h" | 47 | #include "acnamesp.h" |
48 | #include "acinterp.h" | ||
49 | 48 | ||
50 | #define _COMPONENT ACPI_EVENTS | 49 | #define _COMPONENT ACPI_EVENTS |
51 | ACPI_MODULE_NAME("evgpeinit") | 50 | ACPI_MODULE_NAME("evgpeinit") |
52 | 51 | ||
52 | /* | ||
53 | * Note: History of _PRW support in ACPICA | ||
54 | * | ||
55 | * Originally (2000 - 2010), the GPE initialization code performed a walk of | ||
56 | * the entire namespace to execute the _PRW methods and detect all GPEs | ||
57 | * capable of waking the system. | ||
58 | * | ||
59 | * As of 10/2010, the _PRW method execution has been removed since it is | ||
60 | * actually unnecessary. The host OS must in fact execute all _PRW methods | ||
61 | * in order to identify the device/power-resource dependencies. We now put | ||
62 | * the onus on the host OS to identify the wake GPEs as part of this process | ||
63 | * and to inform ACPICA of these GPEs via the acpi_setup_gpe_for_wake interface. This | ||
64 | * not only reduces the complexity of the ACPICA initialization code, but in | ||
65 | * some cases (on systems with very large namespaces) it should reduce the | ||
66 | * kernel boot time as well. | ||
67 | */ | ||
68 | |||
53 | /******************************************************************************* | 69 | /******************************************************************************* |
54 | * | 70 | * |
55 | * FUNCTION: acpi_ev_gpe_initialize | 71 | * FUNCTION: acpi_ev_gpe_initialize |
@@ -222,7 +238,7 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id) | |||
222 | acpi_status status = AE_OK; | 238 | acpi_status status = AE_OK; |
223 | 239 | ||
224 | /* | 240 | /* |
225 | * 2) Find any _Lxx/_Exx GPE methods that have just been loaded. | 241 | * Find any _Lxx/_Exx GPE methods that have just been loaded. |
226 | * | 242 | * |
227 | * Any GPEs that correspond to new _Lxx/_Exx methods are immediately | 243 | * Any GPEs that correspond to new _Lxx/_Exx methods are immediately |
228 | * enabled. | 244 | * enabled. |
@@ -235,9 +251,9 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id) | |||
235 | return; | 251 | return; |
236 | } | 252 | } |
237 | 253 | ||
254 | walk_info.count = 0; | ||
238 | walk_info.owner_id = table_owner_id; | 255 | walk_info.owner_id = table_owner_id; |
239 | walk_info.execute_by_owner_id = TRUE; | 256 | walk_info.execute_by_owner_id = TRUE; |
240 | walk_info.count = 0; | ||
241 | 257 | ||
242 | /* Walk the interrupt level descriptor list */ | 258 | /* Walk the interrupt level descriptor list */ |
243 | 259 | ||
@@ -298,7 +314,7 @@ void acpi_ev_update_gpes(acpi_owner_id table_owner_id) | |||
298 | * xx - is the GPE number [in HEX] | 314 | * xx - is the GPE number [in HEX] |
299 | * | 315 | * |
300 | * If walk_info->execute_by_owner_id is TRUE, we only execute examine GPE methods | 316 | * If walk_info->execute_by_owner_id is TRUE, we only execute examine GPE methods |
301 | * with that owner. | 317 | * with that owner. |
302 | * | 318 | * |
303 | ******************************************************************************/ | 319 | ******************************************************************************/ |
304 | 320 | ||
@@ -408,10 +424,14 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle, | |||
408 | return_ACPI_STATUS(AE_OK); | 424 | return_ACPI_STATUS(AE_OK); |
409 | } | 425 | } |
410 | 426 | ||
427 | /* Disable the GPE in case it's been enabled already. */ | ||
428 | (void)acpi_hw_low_set_gpe(gpe_event_info, ACPI_GPE_DISABLE); | ||
429 | |||
411 | /* | 430 | /* |
412 | * Add the GPE information from above to the gpe_event_info block for | 431 | * Add the GPE information from above to the gpe_event_info block for |
413 | * use during dispatch of this GPE. | 432 | * use during dispatch of this GPE. |
414 | */ | 433 | */ |
434 | gpe_event_info->flags &= ~(ACPI_GPE_DISPATCH_MASK); | ||
415 | gpe_event_info->flags |= (u8)(type | ACPI_GPE_DISPATCH_METHOD); | 435 | gpe_event_info->flags |= (u8)(type | ACPI_GPE_DISPATCH_METHOD); |
416 | gpe_event_info->dispatch.method_node = method_node; | 436 | gpe_event_info->dispatch.method_node = method_node; |
417 | 437 | ||
diff --git a/drivers/acpi/acpica/evgpeutil.c b/drivers/acpi/acpica/evgpeutil.c index 19a0e513ea48..10e477494dcf 100644 --- a/drivers/acpi/acpica/evgpeutil.c +++ b/drivers/acpi/acpica/evgpeutil.c | |||
@@ -154,6 +154,45 @@ u8 acpi_ev_valid_gpe_event(struct acpi_gpe_event_info *gpe_event_info) | |||
154 | 154 | ||
155 | /******************************************************************************* | 155 | /******************************************************************************* |
156 | * | 156 | * |
157 | * FUNCTION: acpi_ev_get_gpe_device | ||
158 | * | ||
159 | * PARAMETERS: GPE_WALK_CALLBACK | ||
160 | * | ||
161 | * RETURN: Status | ||
162 | * | ||
163 | * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE | ||
164 | * block device. NULL if the GPE is one of the FADT-defined GPEs. | ||
165 | * | ||
166 | ******************************************************************************/ | ||
167 | |||
168 | acpi_status | ||
169 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | ||
170 | struct acpi_gpe_block_info *gpe_block, void *context) | ||
171 | { | ||
172 | struct acpi_gpe_device_info *info = context; | ||
173 | |||
174 | /* Increment Index by the number of GPEs in this block */ | ||
175 | |||
176 | info->next_block_base_index += gpe_block->gpe_count; | ||
177 | |||
178 | if (info->index < info->next_block_base_index) { | ||
179 | /* | ||
180 | * The GPE index is within this block, get the node. Leave the node | ||
181 | * NULL for the FADT-defined GPEs | ||
182 | */ | ||
183 | if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) { | ||
184 | info->gpe_device = gpe_block->node; | ||
185 | } | ||
186 | |||
187 | info->status = AE_OK; | ||
188 | return (AE_CTRL_END); | ||
189 | } | ||
190 | |||
191 | return (AE_OK); | ||
192 | } | ||
193 | |||
194 | /******************************************************************************* | ||
195 | * | ||
157 | * FUNCTION: acpi_ev_get_gpe_xrupt_block | 196 | * FUNCTION: acpi_ev_get_gpe_xrupt_block |
158 | * | 197 | * |
159 | * PARAMETERS: interrupt_number - Interrupt for a GPE block | 198 | * PARAMETERS: interrupt_number - Interrupt for a GPE block |
diff --git a/drivers/acpi/acpica/evmisc.c b/drivers/acpi/acpica/evmisc.c index fcaed9fb44ff..8e31bb5a973a 100644 --- a/drivers/acpi/acpica/evmisc.c +++ b/drivers/acpi/acpica/evmisc.c | |||
@@ -284,41 +284,41 @@ static void ACPI_SYSTEM_XFACE acpi_ev_notify_dispatch(void *context) | |||
284 | * RETURN: ACPI_INTERRUPT_HANDLED | 284 | * RETURN: ACPI_INTERRUPT_HANDLED |
285 | * | 285 | * |
286 | * DESCRIPTION: Invoked directly from the SCI handler when a global lock | 286 | * DESCRIPTION: Invoked directly from the SCI handler when a global lock |
287 | * release interrupt occurs. Attempt to acquire the global lock, | 287 | * release interrupt occurs. If there's a thread waiting for |
288 | * if successful, signal the thread waiting for the lock. | 288 | * the global lock, signal it. |
289 | * | 289 | * |
290 | * NOTE: Assumes that the semaphore can be signaled from interrupt level. If | 290 | * NOTE: Assumes that the semaphore can be signaled from interrupt level. If |
291 | * this is not possible for some reason, a separate thread will have to be | 291 | * this is not possible for some reason, a separate thread will have to be |
292 | * scheduled to do this. | 292 | * scheduled to do this. |
293 | * | 293 | * |
294 | ******************************************************************************/ | 294 | ******************************************************************************/ |
295 | static u8 acpi_ev_global_lock_pending; | ||
296 | static spinlock_t _acpi_ev_global_lock_pending_lock; | ||
297 | #define acpi_ev_global_lock_pending_lock &_acpi_ev_global_lock_pending_lock | ||
295 | 298 | ||
296 | static u32 acpi_ev_global_lock_handler(void *context) | 299 | static u32 acpi_ev_global_lock_handler(void *context) |
297 | { | 300 | { |
298 | u8 acquired = FALSE; | 301 | acpi_status status; |
302 | acpi_cpu_flags flags; | ||
299 | 303 | ||
300 | /* | 304 | flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); |
301 | * Attempt to get the lock. | ||
302 | * | ||
303 | * If we don't get it now, it will be marked pending and we will | ||
304 | * take another interrupt when it becomes free. | ||
305 | */ | ||
306 | ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); | ||
307 | if (acquired) { | ||
308 | 305 | ||
309 | /* Got the lock, now wake all threads waiting for it */ | 306 | if (!acpi_ev_global_lock_pending) { |
307 | goto out; | ||
308 | } | ||
310 | 309 | ||
311 | acpi_gbl_global_lock_acquired = TRUE; | 310 | /* Send a unit to the semaphore */ |
312 | /* Send a unit to the semaphore */ | ||
313 | 311 | ||
314 | if (ACPI_FAILURE | 312 | status = acpi_os_signal_semaphore(acpi_gbl_global_lock_semaphore, 1); |
315 | (acpi_os_signal_semaphore | 313 | if (ACPI_FAILURE(status)) { |
316 | (acpi_gbl_global_lock_semaphore, 1))) { | 314 | ACPI_ERROR((AE_INFO, "Could not signal Global Lock semaphore")); |
317 | ACPI_ERROR((AE_INFO, | ||
318 | "Could not signal Global Lock semaphore")); | ||
319 | } | ||
320 | } | 315 | } |
321 | 316 | ||
317 | acpi_ev_global_lock_pending = FALSE; | ||
318 | |||
319 | out: | ||
320 | acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); | ||
321 | |||
322 | return (ACPI_INTERRUPT_HANDLED); | 322 | return (ACPI_INTERRUPT_HANDLED); |
323 | } | 323 | } |
324 | 324 | ||
@@ -415,6 +415,7 @@ static int acpi_ev_global_lock_acquired; | |||
415 | 415 | ||
416 | acpi_status acpi_ev_acquire_global_lock(u16 timeout) | 416 | acpi_status acpi_ev_acquire_global_lock(u16 timeout) |
417 | { | 417 | { |
418 | acpi_cpu_flags flags; | ||
418 | acpi_status status = AE_OK; | 419 | acpi_status status = AE_OK; |
419 | u8 acquired = FALSE; | 420 | u8 acquired = FALSE; |
420 | 421 | ||
@@ -467,32 +468,47 @@ acpi_status acpi_ev_acquire_global_lock(u16 timeout) | |||
467 | return_ACPI_STATUS(AE_OK); | 468 | return_ACPI_STATUS(AE_OK); |
468 | } | 469 | } |
469 | 470 | ||
470 | /* Attempt to acquire the actual hardware lock */ | 471 | flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); |
472 | |||
473 | do { | ||
474 | |||
475 | /* Attempt to acquire the actual hardware lock */ | ||
476 | |||
477 | ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); | ||
478 | if (acquired) { | ||
479 | acpi_gbl_global_lock_acquired = TRUE; | ||
480 | |||
481 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | ||
482 | "Acquired hardware Global Lock\n")); | ||
483 | break; | ||
484 | } | ||
471 | 485 | ||
472 | ACPI_ACQUIRE_GLOBAL_LOCK(acpi_gbl_FACS, acquired); | 486 | acpi_ev_global_lock_pending = TRUE; |
473 | if (acquired) { | ||
474 | 487 | ||
475 | /* We got the lock */ | 488 | acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); |
476 | 489 | ||
490 | /* | ||
491 | * Did not get the lock. The pending bit was set above, and we | ||
492 | * must wait until we get the global lock released interrupt. | ||
493 | */ | ||
477 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, | 494 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, |
478 | "Acquired hardware Global Lock\n")); | 495 | "Waiting for hardware Global Lock\n")); |
479 | 496 | ||
480 | acpi_gbl_global_lock_acquired = TRUE; | 497 | /* |
481 | return_ACPI_STATUS(AE_OK); | 498 | * Wait for handshake with the global lock interrupt handler. |
482 | } | 499 | * This interface releases the interpreter if we must wait. |
500 | */ | ||
501 | status = acpi_ex_system_wait_semaphore( | ||
502 | acpi_gbl_global_lock_semaphore, | ||
503 | ACPI_WAIT_FOREVER); | ||
483 | 504 | ||
484 | /* | 505 | flags = acpi_os_acquire_lock(acpi_ev_global_lock_pending_lock); |
485 | * Did not get the lock. The pending bit was set above, and we must now | ||
486 | * wait until we get the global lock released interrupt. | ||
487 | */ | ||
488 | ACPI_DEBUG_PRINT((ACPI_DB_EXEC, "Waiting for hardware Global Lock\n")); | ||
489 | 506 | ||
490 | /* | 507 | } while (ACPI_SUCCESS(status)); |
491 | * Wait for handshake with the global lock interrupt handler. | 508 | |
492 | * This interface releases the interpreter if we must wait. | 509 | acpi_ev_global_lock_pending = FALSE; |
493 | */ | 510 | |
494 | status = acpi_ex_system_wait_semaphore(acpi_gbl_global_lock_semaphore, | 511 | acpi_os_release_lock(acpi_ev_global_lock_pending_lock, flags); |
495 | ACPI_WAIT_FOREVER); | ||
496 | 512 | ||
497 | return_ACPI_STATUS(status); | 513 | return_ACPI_STATUS(status); |
498 | } | 514 | } |
diff --git a/drivers/acpi/acpica/evxface.c b/drivers/acpi/acpica/evxface.c index 36af222cac65..1226689bdb1b 100644 --- a/drivers/acpi/acpica/evxface.c +++ b/drivers/acpi/acpica/evxface.c | |||
@@ -92,6 +92,57 @@ acpi_status acpi_install_exception_handler(acpi_exception_handler handler) | |||
92 | 92 | ||
93 | ACPI_EXPORT_SYMBOL(acpi_install_exception_handler) | 93 | ACPI_EXPORT_SYMBOL(acpi_install_exception_handler) |
94 | #endif /* ACPI_FUTURE_USAGE */ | 94 | #endif /* ACPI_FUTURE_USAGE */ |
95 | |||
96 | /******************************************************************************* | ||
97 | * | ||
98 | * FUNCTION: acpi_install_global_event_handler | ||
99 | * | ||
100 | * PARAMETERS: Handler - Pointer to the global event handler function | ||
101 | * Context - Value passed to the handler on each event | ||
102 | * | ||
103 | * RETURN: Status | ||
104 | * | ||
105 | * DESCRIPTION: Saves the pointer to the handler function. The global handler | ||
106 | * is invoked upon each incoming GPE and Fixed Event. It is | ||
107 | * invoked at interrupt level at the time of the event dispatch. | ||
108 | * Can be used to update event counters, etc. | ||
109 | * | ||
110 | ******************************************************************************/ | ||
111 | acpi_status | ||
112 | acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler, void *context) | ||
113 | { | ||
114 | acpi_status status; | ||
115 | |||
116 | ACPI_FUNCTION_TRACE(acpi_install_global_event_handler); | ||
117 | |||
118 | /* Parameter validation */ | ||
119 | |||
120 | if (!handler) { | ||
121 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
122 | } | ||
123 | |||
124 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
125 | if (ACPI_FAILURE(status)) { | ||
126 | return_ACPI_STATUS(status); | ||
127 | } | ||
128 | |||
129 | /* Don't allow two handlers. */ | ||
130 | |||
131 | if (acpi_gbl_global_event_handler) { | ||
132 | status = AE_ALREADY_EXISTS; | ||
133 | goto cleanup; | ||
134 | } | ||
135 | |||
136 | acpi_gbl_global_event_handler = handler; | ||
137 | acpi_gbl_global_event_handler_context = context; | ||
138 | |||
139 | cleanup: | ||
140 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
141 | return_ACPI_STATUS(status); | ||
142 | } | ||
143 | |||
144 | ACPI_EXPORT_SYMBOL(acpi_install_global_event_handler) | ||
145 | |||
95 | /******************************************************************************* | 146 | /******************************************************************************* |
96 | * | 147 | * |
97 | * FUNCTION: acpi_install_fixed_event_handler | 148 | * FUNCTION: acpi_install_fixed_event_handler |
@@ -671,10 +722,10 @@ ACPI_EXPORT_SYMBOL(acpi_remove_notify_handler) | |||
671 | acpi_status | 722 | acpi_status |
672 | acpi_install_gpe_handler(acpi_handle gpe_device, | 723 | acpi_install_gpe_handler(acpi_handle gpe_device, |
673 | u32 gpe_number, | 724 | u32 gpe_number, |
674 | u32 type, acpi_event_handler address, void *context) | 725 | u32 type, acpi_gpe_handler address, void *context) |
675 | { | 726 | { |
676 | struct acpi_gpe_event_info *gpe_event_info; | 727 | struct acpi_gpe_event_info *gpe_event_info; |
677 | struct acpi_handler_info *handler; | 728 | struct acpi_gpe_handler_info *handler; |
678 | acpi_status status; | 729 | acpi_status status; |
679 | acpi_cpu_flags flags; | 730 | acpi_cpu_flags flags; |
680 | 731 | ||
@@ -693,7 +744,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device, | |||
693 | 744 | ||
694 | /* Allocate memory for the handler object */ | 745 | /* Allocate memory for the handler object */ |
695 | 746 | ||
696 | handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_handler_info)); | 747 | handler = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_handler_info)); |
697 | if (!handler) { | 748 | if (!handler) { |
698 | status = AE_NO_MEMORY; | 749 | status = AE_NO_MEMORY; |
699 | goto unlock_and_exit; | 750 | goto unlock_and_exit; |
@@ -722,7 +773,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device, | |||
722 | handler->address = address; | 773 | handler->address = address; |
723 | handler->context = context; | 774 | handler->context = context; |
724 | handler->method_node = gpe_event_info->dispatch.method_node; | 775 | handler->method_node = gpe_event_info->dispatch.method_node; |
725 | handler->orig_flags = gpe_event_info->flags & | 776 | handler->original_flags = gpe_event_info->flags & |
726 | (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); | 777 | (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); |
727 | 778 | ||
728 | /* | 779 | /* |
@@ -731,10 +782,10 @@ acpi_install_gpe_handler(acpi_handle gpe_device, | |||
731 | * disabled now to avoid spurious execution of the handler. | 782 | * disabled now to avoid spurious execution of the handler. |
732 | */ | 783 | */ |
733 | 784 | ||
734 | if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) | 785 | if ((handler->original_flags & ACPI_GPE_DISPATCH_METHOD) |
735 | && gpe_event_info->runtime_count) { | 786 | && gpe_event_info->runtime_count) { |
736 | handler->orig_enabled = 1; | 787 | handler->originally_enabled = 1; |
737 | (void)acpi_raw_disable_gpe(gpe_event_info); | 788 | (void)acpi_ev_remove_gpe_reference(gpe_event_info); |
738 | } | 789 | } |
739 | 790 | ||
740 | /* Install the handler */ | 791 | /* Install the handler */ |
@@ -777,10 +828,10 @@ ACPI_EXPORT_SYMBOL(acpi_install_gpe_handler) | |||
777 | ******************************************************************************/ | 828 | ******************************************************************************/ |
778 | acpi_status | 829 | acpi_status |
779 | acpi_remove_gpe_handler(acpi_handle gpe_device, | 830 | acpi_remove_gpe_handler(acpi_handle gpe_device, |
780 | u32 gpe_number, acpi_event_handler address) | 831 | u32 gpe_number, acpi_gpe_handler address) |
781 | { | 832 | { |
782 | struct acpi_gpe_event_info *gpe_event_info; | 833 | struct acpi_gpe_event_info *gpe_event_info; |
783 | struct acpi_handler_info *handler; | 834 | struct acpi_gpe_handler_info *handler; |
784 | acpi_status status; | 835 | acpi_status status; |
785 | acpi_cpu_flags flags; | 836 | acpi_cpu_flags flags; |
786 | 837 | ||
@@ -835,7 +886,7 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, | |||
835 | gpe_event_info->dispatch.method_node = handler->method_node; | 886 | gpe_event_info->dispatch.method_node = handler->method_node; |
836 | gpe_event_info->flags &= | 887 | gpe_event_info->flags &= |
837 | ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); | 888 | ~(ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK); |
838 | gpe_event_info->flags |= handler->orig_flags; | 889 | gpe_event_info->flags |= handler->original_flags; |
839 | 890 | ||
840 | /* | 891 | /* |
841 | * If the GPE was previously associated with a method and it was | 892 | * If the GPE was previously associated with a method and it was |
@@ -843,9 +894,9 @@ acpi_remove_gpe_handler(acpi_handle gpe_device, | |||
843 | * post-initialization configuration. | 894 | * post-initialization configuration. |
844 | */ | 895 | */ |
845 | 896 | ||
846 | if ((handler->orig_flags & ACPI_GPE_DISPATCH_METHOD) | 897 | if ((handler->original_flags & ACPI_GPE_DISPATCH_METHOD) |
847 | && handler->orig_enabled) | 898 | && handler->originally_enabled) |
848 | (void)acpi_raw_enable_gpe(gpe_event_info); | 899 | (void)acpi_ev_add_gpe_reference(gpe_event_info); |
849 | 900 | ||
850 | /* Now we can free the handler object */ | 901 | /* Now we can free the handler object */ |
851 | 902 | ||
diff --git a/drivers/acpi/acpica/evxfevnt.c b/drivers/acpi/acpica/evxfevnt.c index a1dabe3fd8ae..90488c1e0f3d 100644 --- a/drivers/acpi/acpica/evxfevnt.c +++ b/drivers/acpi/acpica/evxfevnt.c | |||
@@ -43,18 +43,11 @@ | |||
43 | 43 | ||
44 | #include <acpi/acpi.h> | 44 | #include <acpi/acpi.h> |
45 | #include "accommon.h" | 45 | #include "accommon.h" |
46 | #include "acevents.h" | ||
47 | #include "acnamesp.h" | ||
48 | #include "actables.h" | 46 | #include "actables.h" |
49 | 47 | ||
50 | #define _COMPONENT ACPI_EVENTS | 48 | #define _COMPONENT ACPI_EVENTS |
51 | ACPI_MODULE_NAME("evxfevnt") | 49 | ACPI_MODULE_NAME("evxfevnt") |
52 | 50 | ||
53 | /* Local prototypes */ | ||
54 | static acpi_status | ||
55 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | ||
56 | struct acpi_gpe_block_info *gpe_block, void *context); | ||
57 | |||
58 | /******************************************************************************* | 51 | /******************************************************************************* |
59 | * | 52 | * |
60 | * FUNCTION: acpi_enable | 53 | * FUNCTION: acpi_enable |
@@ -213,185 +206,6 @@ ACPI_EXPORT_SYMBOL(acpi_enable_event) | |||
213 | 206 | ||
214 | /******************************************************************************* | 207 | /******************************************************************************* |
215 | * | 208 | * |
216 | * FUNCTION: acpi_gpe_wakeup | ||
217 | * | ||
218 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
219 | * gpe_number - GPE level within the GPE block | ||
220 | * Action - Enable or Disable | ||
221 | * | ||
222 | * RETURN: Status | ||
223 | * | ||
224 | * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. | ||
225 | * | ||
226 | ******************************************************************************/ | ||
227 | acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action) | ||
228 | { | ||
229 | acpi_status status = AE_OK; | ||
230 | struct acpi_gpe_event_info *gpe_event_info; | ||
231 | struct acpi_gpe_register_info *gpe_register_info; | ||
232 | acpi_cpu_flags flags; | ||
233 | u32 register_bit; | ||
234 | |||
235 | ACPI_FUNCTION_TRACE(acpi_gpe_wakeup); | ||
236 | |||
237 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
238 | |||
239 | /* Ensure that we have a valid GPE number */ | ||
240 | |||
241 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
242 | if (!gpe_event_info || !(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { | ||
243 | status = AE_BAD_PARAMETER; | ||
244 | goto unlock_and_exit; | ||
245 | } | ||
246 | |||
247 | gpe_register_info = gpe_event_info->register_info; | ||
248 | if (!gpe_register_info) { | ||
249 | status = AE_NOT_EXIST; | ||
250 | goto unlock_and_exit; | ||
251 | } | ||
252 | |||
253 | register_bit = | ||
254 | acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info); | ||
255 | |||
256 | /* Perform the action */ | ||
257 | |||
258 | switch (action) { | ||
259 | case ACPI_GPE_ENABLE: | ||
260 | ACPI_SET_BIT(gpe_register_info->enable_for_wake, | ||
261 | (u8)register_bit); | ||
262 | break; | ||
263 | |||
264 | case ACPI_GPE_DISABLE: | ||
265 | ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, | ||
266 | (u8)register_bit); | ||
267 | break; | ||
268 | |||
269 | default: | ||
270 | ACPI_ERROR((AE_INFO, "%u, Invalid action", action)); | ||
271 | status = AE_BAD_PARAMETER; | ||
272 | break; | ||
273 | } | ||
274 | |||
275 | unlock_and_exit: | ||
276 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
277 | return_ACPI_STATUS(status); | ||
278 | } | ||
279 | |||
280 | ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup) | ||
281 | |||
282 | /******************************************************************************* | ||
283 | * | ||
284 | * FUNCTION: acpi_enable_gpe | ||
285 | * | ||
286 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
287 | * gpe_number - GPE level within the GPE block | ||
288 | * | ||
289 | * RETURN: Status | ||
290 | * | ||
291 | * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is | ||
292 | * hardware-enabled. | ||
293 | * | ||
294 | ******************************************************************************/ | ||
295 | acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) | ||
296 | { | ||
297 | acpi_status status = AE_BAD_PARAMETER; | ||
298 | struct acpi_gpe_event_info *gpe_event_info; | ||
299 | acpi_cpu_flags flags; | ||
300 | |||
301 | ACPI_FUNCTION_TRACE(acpi_enable_gpe); | ||
302 | |||
303 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
304 | |||
305 | /* Ensure that we have a valid GPE number */ | ||
306 | |||
307 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
308 | if (gpe_event_info) { | ||
309 | status = acpi_raw_enable_gpe(gpe_event_info); | ||
310 | } | ||
311 | |||
312 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
313 | return_ACPI_STATUS(status); | ||
314 | } | ||
315 | ACPI_EXPORT_SYMBOL(acpi_enable_gpe) | ||
316 | |||
317 | /******************************************************************************* | ||
318 | * | ||
319 | * FUNCTION: acpi_disable_gpe | ||
320 | * | ||
321 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
322 | * gpe_number - GPE level within the GPE block | ||
323 | * | ||
324 | * RETURN: Status | ||
325 | * | ||
326 | * DESCRIPTION: Remove a reference to a GPE. When the last reference is | ||
327 | * removed, only then is the GPE disabled (for runtime GPEs), or | ||
328 | * the GPE mask bit disabled (for wake GPEs) | ||
329 | * | ||
330 | ******************************************************************************/ | ||
331 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) | ||
332 | { | ||
333 | acpi_status status = AE_BAD_PARAMETER; | ||
334 | struct acpi_gpe_event_info *gpe_event_info; | ||
335 | acpi_cpu_flags flags; | ||
336 | |||
337 | ACPI_FUNCTION_TRACE(acpi_disable_gpe); | ||
338 | |||
339 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
340 | |||
341 | /* Ensure that we have a valid GPE number */ | ||
342 | |||
343 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
344 | if (gpe_event_info) { | ||
345 | status = acpi_raw_disable_gpe(gpe_event_info) ; | ||
346 | } | ||
347 | |||
348 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
349 | return_ACPI_STATUS(status); | ||
350 | } | ||
351 | ACPI_EXPORT_SYMBOL(acpi_disable_gpe) | ||
352 | |||
353 | /******************************************************************************* | ||
354 | * | ||
355 | * FUNCTION: acpi_gpe_can_wake | ||
356 | * | ||
357 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
358 | * gpe_number - GPE level within the GPE block | ||
359 | * | ||
360 | * RETURN: Status | ||
361 | * | ||
362 | * DESCRIPTION: Set the ACPI_GPE_CAN_WAKE flag for the given GPE. If the GPE | ||
363 | * has a corresponding method and is currently enabled, disable it | ||
364 | * (GPEs with corresponding methods are enabled unconditionally | ||
365 | * during initialization, but GPEs that can wake up are expected | ||
366 | * to be initially disabled). | ||
367 | * | ||
368 | ******************************************************************************/ | ||
369 | acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number) | ||
370 | { | ||
371 | acpi_status status = AE_OK; | ||
372 | struct acpi_gpe_event_info *gpe_event_info; | ||
373 | acpi_cpu_flags flags; | ||
374 | |||
375 | ACPI_FUNCTION_TRACE(acpi_gpe_can_wake); | ||
376 | |||
377 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
378 | |||
379 | /* Ensure that we have a valid GPE number */ | ||
380 | |||
381 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
382 | if (gpe_event_info) { | ||
383 | gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; | ||
384 | } else { | ||
385 | status = AE_BAD_PARAMETER; | ||
386 | } | ||
387 | |||
388 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
389 | return_ACPI_STATUS(status); | ||
390 | } | ||
391 | ACPI_EXPORT_SYMBOL(acpi_gpe_can_wake) | ||
392 | |||
393 | /******************************************************************************* | ||
394 | * | ||
395 | * FUNCTION: acpi_disable_event | 209 | * FUNCTION: acpi_disable_event |
396 | * | 210 | * |
397 | * PARAMETERS: Event - The fixed eventto be enabled | 211 | * PARAMETERS: Event - The fixed eventto be enabled |
@@ -483,44 +297,6 @@ ACPI_EXPORT_SYMBOL(acpi_clear_event) | |||
483 | 297 | ||
484 | /******************************************************************************* | 298 | /******************************************************************************* |
485 | * | 299 | * |
486 | * FUNCTION: acpi_clear_gpe | ||
487 | * | ||
488 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
489 | * gpe_number - GPE level within the GPE block | ||
490 | * | ||
491 | * RETURN: Status | ||
492 | * | ||
493 | * DESCRIPTION: Clear an ACPI event (general purpose) | ||
494 | * | ||
495 | ******************************************************************************/ | ||
496 | acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number) | ||
497 | { | ||
498 | acpi_status status = AE_OK; | ||
499 | struct acpi_gpe_event_info *gpe_event_info; | ||
500 | acpi_cpu_flags flags; | ||
501 | |||
502 | ACPI_FUNCTION_TRACE(acpi_clear_gpe); | ||
503 | |||
504 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
505 | |||
506 | /* Ensure that we have a valid GPE number */ | ||
507 | |||
508 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
509 | if (!gpe_event_info) { | ||
510 | status = AE_BAD_PARAMETER; | ||
511 | goto unlock_and_exit; | ||
512 | } | ||
513 | |||
514 | status = acpi_hw_clear_gpe(gpe_event_info); | ||
515 | |||
516 | unlock_and_exit: | ||
517 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
518 | return_ACPI_STATUS(status); | ||
519 | } | ||
520 | |||
521 | ACPI_EXPORT_SYMBOL(acpi_clear_gpe) | ||
522 | /******************************************************************************* | ||
523 | * | ||
524 | * FUNCTION: acpi_get_event_status | 300 | * FUNCTION: acpi_get_event_status |
525 | * | 301 | * |
526 | * PARAMETERS: Event - The fixed event | 302 | * PARAMETERS: Event - The fixed event |
@@ -575,379 +351,3 @@ acpi_status acpi_get_event_status(u32 event, acpi_event_status * event_status) | |||
575 | } | 351 | } |
576 | 352 | ||
577 | ACPI_EXPORT_SYMBOL(acpi_get_event_status) | 353 | ACPI_EXPORT_SYMBOL(acpi_get_event_status) |
578 | |||
579 | /******************************************************************************* | ||
580 | * | ||
581 | * FUNCTION: acpi_get_gpe_status | ||
582 | * | ||
583 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
584 | * gpe_number - GPE level within the GPE block | ||
585 | * event_status - Where the current status of the event will | ||
586 | * be returned | ||
587 | * | ||
588 | * RETURN: Status | ||
589 | * | ||
590 | * DESCRIPTION: Get status of an event (general purpose) | ||
591 | * | ||
592 | ******************************************************************************/ | ||
593 | acpi_status | ||
594 | acpi_get_gpe_status(acpi_handle gpe_device, | ||
595 | u32 gpe_number, acpi_event_status *event_status) | ||
596 | { | ||
597 | acpi_status status = AE_OK; | ||
598 | struct acpi_gpe_event_info *gpe_event_info; | ||
599 | acpi_cpu_flags flags; | ||
600 | |||
601 | ACPI_FUNCTION_TRACE(acpi_get_gpe_status); | ||
602 | |||
603 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
604 | |||
605 | /* Ensure that we have a valid GPE number */ | ||
606 | |||
607 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
608 | if (!gpe_event_info) { | ||
609 | status = AE_BAD_PARAMETER; | ||
610 | goto unlock_and_exit; | ||
611 | } | ||
612 | |||
613 | /* Obtain status on the requested GPE number */ | ||
614 | |||
615 | status = acpi_hw_get_gpe_status(gpe_event_info, event_status); | ||
616 | |||
617 | if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) | ||
618 | *event_status |= ACPI_EVENT_FLAG_HANDLE; | ||
619 | |||
620 | unlock_and_exit: | ||
621 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
622 | return_ACPI_STATUS(status); | ||
623 | } | ||
624 | |||
625 | ACPI_EXPORT_SYMBOL(acpi_get_gpe_status) | ||
626 | /******************************************************************************* | ||
627 | * | ||
628 | * FUNCTION: acpi_install_gpe_block | ||
629 | * | ||
630 | * PARAMETERS: gpe_device - Handle to the parent GPE Block Device | ||
631 | * gpe_block_address - Address and space_iD | ||
632 | * register_count - Number of GPE register pairs in the block | ||
633 | * interrupt_number - H/W interrupt for the block | ||
634 | * | ||
635 | * RETURN: Status | ||
636 | * | ||
637 | * DESCRIPTION: Create and Install a block of GPE registers | ||
638 | * | ||
639 | ******************************************************************************/ | ||
640 | acpi_status | ||
641 | acpi_install_gpe_block(acpi_handle gpe_device, | ||
642 | struct acpi_generic_address *gpe_block_address, | ||
643 | u32 register_count, u32 interrupt_number) | ||
644 | { | ||
645 | acpi_status status = AE_OK; | ||
646 | union acpi_operand_object *obj_desc; | ||
647 | struct acpi_namespace_node *node; | ||
648 | struct acpi_gpe_block_info *gpe_block; | ||
649 | |||
650 | ACPI_FUNCTION_TRACE(acpi_install_gpe_block); | ||
651 | |||
652 | if ((!gpe_device) || (!gpe_block_address) || (!register_count)) { | ||
653 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
654 | } | ||
655 | |||
656 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
657 | if (ACPI_FAILURE(status)) { | ||
658 | return (status); | ||
659 | } | ||
660 | |||
661 | node = acpi_ns_validate_handle(gpe_device); | ||
662 | if (!node) { | ||
663 | status = AE_BAD_PARAMETER; | ||
664 | goto unlock_and_exit; | ||
665 | } | ||
666 | |||
667 | /* | ||
668 | * For user-installed GPE Block Devices, the gpe_block_base_number | ||
669 | * is always zero | ||
670 | */ | ||
671 | status = | ||
672 | acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0, | ||
673 | interrupt_number, &gpe_block); | ||
674 | if (ACPI_FAILURE(status)) { | ||
675 | goto unlock_and_exit; | ||
676 | } | ||
677 | |||
678 | /* Install block in the device_object attached to the node */ | ||
679 | |||
680 | obj_desc = acpi_ns_get_attached_object(node); | ||
681 | if (!obj_desc) { | ||
682 | |||
683 | /* | ||
684 | * No object, create a new one (Device nodes do not always have | ||
685 | * an attached object) | ||
686 | */ | ||
687 | obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE); | ||
688 | if (!obj_desc) { | ||
689 | status = AE_NO_MEMORY; | ||
690 | goto unlock_and_exit; | ||
691 | } | ||
692 | |||
693 | status = | ||
694 | acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE); | ||
695 | |||
696 | /* Remove local reference to the object */ | ||
697 | |||
698 | acpi_ut_remove_reference(obj_desc); | ||
699 | |||
700 | if (ACPI_FAILURE(status)) { | ||
701 | goto unlock_and_exit; | ||
702 | } | ||
703 | } | ||
704 | |||
705 | /* Now install the GPE block in the device_object */ | ||
706 | |||
707 | obj_desc->device.gpe_block = gpe_block; | ||
708 | |||
709 | unlock_and_exit: | ||
710 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
711 | return_ACPI_STATUS(status); | ||
712 | } | ||
713 | |||
714 | ACPI_EXPORT_SYMBOL(acpi_install_gpe_block) | ||
715 | |||
716 | /******************************************************************************* | ||
717 | * | ||
718 | * FUNCTION: acpi_remove_gpe_block | ||
719 | * | ||
720 | * PARAMETERS: gpe_device - Handle to the parent GPE Block Device | ||
721 | * | ||
722 | * RETURN: Status | ||
723 | * | ||
724 | * DESCRIPTION: Remove a previously installed block of GPE registers | ||
725 | * | ||
726 | ******************************************************************************/ | ||
727 | acpi_status acpi_remove_gpe_block(acpi_handle gpe_device) | ||
728 | { | ||
729 | union acpi_operand_object *obj_desc; | ||
730 | acpi_status status; | ||
731 | struct acpi_namespace_node *node; | ||
732 | |||
733 | ACPI_FUNCTION_TRACE(acpi_remove_gpe_block); | ||
734 | |||
735 | if (!gpe_device) { | ||
736 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
737 | } | ||
738 | |||
739 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
740 | if (ACPI_FAILURE(status)) { | ||
741 | return (status); | ||
742 | } | ||
743 | |||
744 | node = acpi_ns_validate_handle(gpe_device); | ||
745 | if (!node) { | ||
746 | status = AE_BAD_PARAMETER; | ||
747 | goto unlock_and_exit; | ||
748 | } | ||
749 | |||
750 | /* Get the device_object attached to the node */ | ||
751 | |||
752 | obj_desc = acpi_ns_get_attached_object(node); | ||
753 | if (!obj_desc || !obj_desc->device.gpe_block) { | ||
754 | return_ACPI_STATUS(AE_NULL_OBJECT); | ||
755 | } | ||
756 | |||
757 | /* Delete the GPE block (but not the device_object) */ | ||
758 | |||
759 | status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block); | ||
760 | if (ACPI_SUCCESS(status)) { | ||
761 | obj_desc->device.gpe_block = NULL; | ||
762 | } | ||
763 | |||
764 | unlock_and_exit: | ||
765 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
766 | return_ACPI_STATUS(status); | ||
767 | } | ||
768 | |||
769 | ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block) | ||
770 | |||
771 | /******************************************************************************* | ||
772 | * | ||
773 | * FUNCTION: acpi_get_gpe_device | ||
774 | * | ||
775 | * PARAMETERS: Index - System GPE index (0-current_gpe_count) | ||
776 | * gpe_device - Where the parent GPE Device is returned | ||
777 | * | ||
778 | * RETURN: Status | ||
779 | * | ||
780 | * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL | ||
781 | * gpe device indicates that the gpe number is contained in one of | ||
782 | * the FADT-defined gpe blocks. Otherwise, the GPE block device. | ||
783 | * | ||
784 | ******************************************************************************/ | ||
785 | acpi_status | ||
786 | acpi_get_gpe_device(u32 index, acpi_handle *gpe_device) | ||
787 | { | ||
788 | struct acpi_gpe_device_info info; | ||
789 | acpi_status status; | ||
790 | |||
791 | ACPI_FUNCTION_TRACE(acpi_get_gpe_device); | ||
792 | |||
793 | if (!gpe_device) { | ||
794 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
795 | } | ||
796 | |||
797 | if (index >= acpi_current_gpe_count) { | ||
798 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
799 | } | ||
800 | |||
801 | /* Setup and walk the GPE list */ | ||
802 | |||
803 | info.index = index; | ||
804 | info.status = AE_NOT_EXIST; | ||
805 | info.gpe_device = NULL; | ||
806 | info.next_block_base_index = 0; | ||
807 | |||
808 | status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info); | ||
809 | if (ACPI_FAILURE(status)) { | ||
810 | return_ACPI_STATUS(status); | ||
811 | } | ||
812 | |||
813 | *gpe_device = info.gpe_device; | ||
814 | return_ACPI_STATUS(info.status); | ||
815 | } | ||
816 | |||
817 | ACPI_EXPORT_SYMBOL(acpi_get_gpe_device) | ||
818 | |||
819 | /******************************************************************************* | ||
820 | * | ||
821 | * FUNCTION: acpi_ev_get_gpe_device | ||
822 | * | ||
823 | * PARAMETERS: GPE_WALK_CALLBACK | ||
824 | * | ||
825 | * RETURN: Status | ||
826 | * | ||
827 | * DESCRIPTION: Matches the input GPE index (0-current_gpe_count) with a GPE | ||
828 | * block device. NULL if the GPE is one of the FADT-defined GPEs. | ||
829 | * | ||
830 | ******************************************************************************/ | ||
831 | static acpi_status | ||
832 | acpi_ev_get_gpe_device(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | ||
833 | struct acpi_gpe_block_info *gpe_block, void *context) | ||
834 | { | ||
835 | struct acpi_gpe_device_info *info = context; | ||
836 | |||
837 | /* Increment Index by the number of GPEs in this block */ | ||
838 | |||
839 | info->next_block_base_index += gpe_block->gpe_count; | ||
840 | |||
841 | if (info->index < info->next_block_base_index) { | ||
842 | /* | ||
843 | * The GPE index is within this block, get the node. Leave the node | ||
844 | * NULL for the FADT-defined GPEs | ||
845 | */ | ||
846 | if ((gpe_block->node)->type == ACPI_TYPE_DEVICE) { | ||
847 | info->gpe_device = gpe_block->node; | ||
848 | } | ||
849 | |||
850 | info->status = AE_OK; | ||
851 | return (AE_CTRL_END); | ||
852 | } | ||
853 | |||
854 | return (AE_OK); | ||
855 | } | ||
856 | |||
857 | /****************************************************************************** | ||
858 | * | ||
859 | * FUNCTION: acpi_disable_all_gpes | ||
860 | * | ||
861 | * PARAMETERS: None | ||
862 | * | ||
863 | * RETURN: Status | ||
864 | * | ||
865 | * DESCRIPTION: Disable and clear all GPEs in all GPE blocks | ||
866 | * | ||
867 | ******************************************************************************/ | ||
868 | |||
869 | acpi_status acpi_disable_all_gpes(void) | ||
870 | { | ||
871 | acpi_status status; | ||
872 | |||
873 | ACPI_FUNCTION_TRACE(acpi_disable_all_gpes); | ||
874 | |||
875 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
876 | if (ACPI_FAILURE(status)) { | ||
877 | return_ACPI_STATUS(status); | ||
878 | } | ||
879 | |||
880 | status = acpi_hw_disable_all_gpes(); | ||
881 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
882 | |||
883 | return_ACPI_STATUS(status); | ||
884 | } | ||
885 | |||
886 | /****************************************************************************** | ||
887 | * | ||
888 | * FUNCTION: acpi_enable_all_runtime_gpes | ||
889 | * | ||
890 | * PARAMETERS: None | ||
891 | * | ||
892 | * RETURN: Status | ||
893 | * | ||
894 | * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks | ||
895 | * | ||
896 | ******************************************************************************/ | ||
897 | |||
898 | acpi_status acpi_enable_all_runtime_gpes(void) | ||
899 | { | ||
900 | acpi_status status; | ||
901 | |||
902 | ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes); | ||
903 | |||
904 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
905 | if (ACPI_FAILURE(status)) { | ||
906 | return_ACPI_STATUS(status); | ||
907 | } | ||
908 | |||
909 | status = acpi_hw_enable_all_runtime_gpes(); | ||
910 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
911 | |||
912 | return_ACPI_STATUS(status); | ||
913 | } | ||
914 | |||
915 | /****************************************************************************** | ||
916 | * | ||
917 | * FUNCTION: acpi_update_gpes | ||
918 | * | ||
919 | * PARAMETERS: None | ||
920 | * | ||
921 | * RETURN: None | ||
922 | * | ||
923 | * DESCRIPTION: Enable all GPEs that have associated _Lxx or _Exx methods and | ||
924 | * are not pointed to by any device _PRW methods indicating that | ||
925 | * these GPEs are generally intended for system or device wakeup | ||
926 | * (such GPEs have to be enabled directly when the devices whose | ||
927 | * _PRW methods point to them are set up for wakeup signaling). | ||
928 | * | ||
929 | ******************************************************************************/ | ||
930 | |||
931 | acpi_status acpi_update_gpes(void) | ||
932 | { | ||
933 | acpi_status status; | ||
934 | |||
935 | ACPI_FUNCTION_TRACE(acpi_update_gpes); | ||
936 | |||
937 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
938 | if (ACPI_FAILURE(status)) { | ||
939 | return_ACPI_STATUS(status); | ||
940 | } else if (acpi_all_gpes_initialized) { | ||
941 | goto unlock; | ||
942 | } | ||
943 | |||
944 | status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL); | ||
945 | if (ACPI_SUCCESS(status)) { | ||
946 | acpi_all_gpes_initialized = TRUE; | ||
947 | } | ||
948 | |||
949 | unlock: | ||
950 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
951 | |||
952 | return_ACPI_STATUS(status); | ||
953 | } | ||
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c new file mode 100644 index 000000000000..416845bc9c1f --- /dev/null +++ b/drivers/acpi/acpica/evxfgpe.c | |||
@@ -0,0 +1,669 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Module Name: evxfgpe - External Interfaces for General Purpose Events (GPEs) | ||
4 | * | ||
5 | *****************************************************************************/ | ||
6 | |||
7 | /* | ||
8 | * Copyright (C) 2000 - 2010, Intel Corp. | ||
9 | * All rights reserved. | ||
10 | * | ||
11 | * Redistribution and use in source and binary forms, with or without | ||
12 | * modification, are permitted provided that the following conditions | ||
13 | * are met: | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions, and the following disclaimer, | ||
16 | * without modification. | ||
17 | * 2. Redistributions in binary form must reproduce at minimum a disclaimer | ||
18 | * substantially similar to the "NO WARRANTY" disclaimer below | ||
19 | * ("Disclaimer") and any redistribution must be conditioned upon | ||
20 | * including a substantially similar Disclaimer requirement for further | ||
21 | * binary redistribution. | ||
22 | * 3. Neither the names of the above-listed copyright holders nor the names | ||
23 | * of any contributors may be used to endorse or promote products derived | ||
24 | * from this software without specific prior written permission. | ||
25 | * | ||
26 | * Alternatively, this software may be distributed under the terms of the | ||
27 | * GNU General Public License ("GPL") version 2 as published by the Free | ||
28 | * Software Foundation. | ||
29 | * | ||
30 | * NO WARRANTY | ||
31 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
32 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
33 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR | ||
34 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
35 | * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
36 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
37 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
38 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | ||
39 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | ||
40 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
41 | * POSSIBILITY OF SUCH DAMAGES. | ||
42 | */ | ||
43 | |||
44 | #include <acpi/acpi.h> | ||
45 | #include "accommon.h" | ||
46 | #include "acevents.h" | ||
47 | #include "acnamesp.h" | ||
48 | |||
49 | #define _COMPONENT ACPI_EVENTS | ||
50 | ACPI_MODULE_NAME("evxfgpe") | ||
51 | |||
52 | /****************************************************************************** | ||
53 | * | ||
54 | * FUNCTION: acpi_update_all_gpes | ||
55 | * | ||
56 | * PARAMETERS: None | ||
57 | * | ||
58 | * RETURN: Status | ||
59 | * | ||
60 | * DESCRIPTION: Complete GPE initialization and enable all GPEs that have | ||
61 | * associated _Lxx or _Exx methods and are not pointed to by any | ||
62 | * device _PRW methods (this indicates that these GPEs are | ||
63 | * generally intended for system or device wakeup. Such GPEs | ||
64 | * have to be enabled directly when the devices whose _PRW | ||
65 | * methods point to them are set up for wakeup signaling.) | ||
66 | * | ||
67 | * NOTE: Should be called after any GPEs are added to the system. Primarily, | ||
68 | * after the system _PRW methods have been run, but also after a GPE Block | ||
69 | * Device has been added or if any new GPE methods have been added via a | ||
70 | * dynamic table load. | ||
71 | * | ||
72 | ******************************************************************************/ | ||
73 | |||
74 | acpi_status acpi_update_all_gpes(void) | ||
75 | { | ||
76 | acpi_status status; | ||
77 | |||
78 | ACPI_FUNCTION_TRACE(acpi_update_all_gpes); | ||
79 | |||
80 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
81 | if (ACPI_FAILURE(status)) { | ||
82 | return_ACPI_STATUS(status); | ||
83 | } | ||
84 | |||
85 | if (acpi_gbl_all_gpes_initialized) { | ||
86 | goto unlock_and_exit; | ||
87 | } | ||
88 | |||
89 | status = acpi_ev_walk_gpe_list(acpi_ev_initialize_gpe_block, NULL); | ||
90 | if (ACPI_SUCCESS(status)) { | ||
91 | acpi_gbl_all_gpes_initialized = TRUE; | ||
92 | } | ||
93 | |||
94 | unlock_and_exit: | ||
95 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
96 | |||
97 | return_ACPI_STATUS(status); | ||
98 | } | ||
99 | |||
100 | ACPI_EXPORT_SYMBOL(acpi_update_all_gpes) | ||
101 | |||
102 | /******************************************************************************* | ||
103 | * | ||
104 | * FUNCTION: acpi_enable_gpe | ||
105 | * | ||
106 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
107 | * gpe_number - GPE level within the GPE block | ||
108 | * | ||
109 | * RETURN: Status | ||
110 | * | ||
111 | * DESCRIPTION: Add a reference to a GPE. On the first reference, the GPE is | ||
112 | * hardware-enabled. | ||
113 | * | ||
114 | ******************************************************************************/ | ||
115 | |||
116 | acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number) | ||
117 | { | ||
118 | acpi_status status = AE_BAD_PARAMETER; | ||
119 | struct acpi_gpe_event_info *gpe_event_info; | ||
120 | acpi_cpu_flags flags; | ||
121 | |||
122 | ACPI_FUNCTION_TRACE(acpi_enable_gpe); | ||
123 | |||
124 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
125 | |||
126 | /* Ensure that we have a valid GPE number */ | ||
127 | |||
128 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
129 | if (gpe_event_info) { | ||
130 | status = acpi_ev_add_gpe_reference(gpe_event_info); | ||
131 | } | ||
132 | |||
133 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
134 | return_ACPI_STATUS(status); | ||
135 | } | ||
136 | ACPI_EXPORT_SYMBOL(acpi_enable_gpe) | ||
137 | |||
138 | /******************************************************************************* | ||
139 | * | ||
140 | * FUNCTION: acpi_disable_gpe | ||
141 | * | ||
142 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
143 | * gpe_number - GPE level within the GPE block | ||
144 | * | ||
145 | * RETURN: Status | ||
146 | * | ||
147 | * DESCRIPTION: Remove a reference to a GPE. When the last reference is | ||
148 | * removed, only then is the GPE disabled (for runtime GPEs), or | ||
149 | * the GPE mask bit disabled (for wake GPEs) | ||
150 | * | ||
151 | ******************************************************************************/ | ||
152 | |||
153 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number) | ||
154 | { | ||
155 | acpi_status status = AE_BAD_PARAMETER; | ||
156 | struct acpi_gpe_event_info *gpe_event_info; | ||
157 | acpi_cpu_flags flags; | ||
158 | |||
159 | ACPI_FUNCTION_TRACE(acpi_disable_gpe); | ||
160 | |||
161 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
162 | |||
163 | /* Ensure that we have a valid GPE number */ | ||
164 | |||
165 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
166 | if (gpe_event_info) { | ||
167 | status = acpi_ev_remove_gpe_reference(gpe_event_info) ; | ||
168 | } | ||
169 | |||
170 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
171 | return_ACPI_STATUS(status); | ||
172 | } | ||
173 | ACPI_EXPORT_SYMBOL(acpi_disable_gpe) | ||
174 | |||
175 | |||
176 | /******************************************************************************* | ||
177 | * | ||
178 | * FUNCTION: acpi_setup_gpe_for_wake | ||
179 | * | ||
180 | * PARAMETERS: wake_device - Device associated with the GPE (via _PRW) | ||
181 | * gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
182 | * gpe_number - GPE level within the GPE block | ||
183 | * | ||
184 | * RETURN: Status | ||
185 | * | ||
186 | * DESCRIPTION: Mark a GPE as having the ability to wake the system. This | ||
187 | * interface is intended to be used as the host executes the | ||
188 | * _PRW methods (Power Resources for Wake) in the system tables. | ||
189 | * Each _PRW appears under a Device Object (The wake_device), and | ||
190 | * contains the info for the wake GPE associated with the | ||
191 | * wake_device. | ||
192 | * | ||
193 | ******************************************************************************/ | ||
194 | acpi_status | ||
195 | acpi_setup_gpe_for_wake(acpi_handle wake_device, | ||
196 | acpi_handle gpe_device, u32 gpe_number) | ||
197 | { | ||
198 | acpi_status status = AE_BAD_PARAMETER; | ||
199 | struct acpi_gpe_event_info *gpe_event_info; | ||
200 | struct acpi_namespace_node *device_node; | ||
201 | acpi_cpu_flags flags; | ||
202 | |||
203 | ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake); | ||
204 | |||
205 | /* Parameter Validation */ | ||
206 | |||
207 | if (!wake_device) { | ||
208 | /* | ||
209 | * By forcing wake_device to be valid, we automatically enable the | ||
210 | * implicit notify feature on all hosts. | ||
211 | */ | ||
212 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
213 | } | ||
214 | |||
215 | /* Validate wake_device is of type Device */ | ||
216 | |||
217 | device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device); | ||
218 | if (device_node->type != ACPI_TYPE_DEVICE) { | ||
219 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
220 | } | ||
221 | |||
222 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
223 | |||
224 | /* Ensure that we have a valid GPE number */ | ||
225 | |||
226 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
227 | if (gpe_event_info) { | ||
228 | /* | ||
229 | * If there is no method or handler for this GPE, then the | ||
230 | * wake_device will be notified whenever this GPE fires (aka | ||
231 | * "implicit notify") Note: The GPE is assumed to be | ||
232 | * level-triggered (for windows compatibility). | ||
233 | */ | ||
234 | if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == | ||
235 | ACPI_GPE_DISPATCH_NONE) { | ||
236 | gpe_event_info->flags = | ||
237 | (ACPI_GPE_DISPATCH_NOTIFY | | ||
238 | ACPI_GPE_LEVEL_TRIGGERED); | ||
239 | gpe_event_info->dispatch.device_node = device_node; | ||
240 | } | ||
241 | |||
242 | gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; | ||
243 | status = AE_OK; | ||
244 | } | ||
245 | |||
246 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
247 | return_ACPI_STATUS(status); | ||
248 | } | ||
249 | ACPI_EXPORT_SYMBOL(acpi_setup_gpe_for_wake) | ||
250 | |||
251 | /******************************************************************************* | ||
252 | * | ||
253 | * FUNCTION: acpi_set_gpe_wake_mask | ||
254 | * | ||
255 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
256 | * gpe_number - GPE level within the GPE block | ||
257 | * Action - Enable or Disable | ||
258 | * | ||
259 | * RETURN: Status | ||
260 | * | ||
261 | * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. The GPE must | ||
262 | * already be marked as a WAKE GPE. | ||
263 | * | ||
264 | ******************************************************************************/ | ||
265 | |||
266 | acpi_status acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action) | ||
267 | { | ||
268 | acpi_status status = AE_OK; | ||
269 | struct acpi_gpe_event_info *gpe_event_info; | ||
270 | struct acpi_gpe_register_info *gpe_register_info; | ||
271 | acpi_cpu_flags flags; | ||
272 | u32 register_bit; | ||
273 | |||
274 | ACPI_FUNCTION_TRACE(acpi_set_gpe_wake_mask); | ||
275 | |||
276 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
277 | |||
278 | /* | ||
279 | * Ensure that we have a valid GPE number and that this GPE is in | ||
280 | * fact a wake GPE | ||
281 | */ | ||
282 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
283 | if (!gpe_event_info) { | ||
284 | status = AE_BAD_PARAMETER; | ||
285 | goto unlock_and_exit; | ||
286 | } | ||
287 | |||
288 | if (!(gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { | ||
289 | status = AE_TYPE; | ||
290 | goto unlock_and_exit; | ||
291 | } | ||
292 | |||
293 | gpe_register_info = gpe_event_info->register_info; | ||
294 | if (!gpe_register_info) { | ||
295 | status = AE_NOT_EXIST; | ||
296 | goto unlock_and_exit; | ||
297 | } | ||
298 | |||
299 | register_bit = | ||
300 | acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info); | ||
301 | |||
302 | /* Perform the action */ | ||
303 | |||
304 | switch (action) { | ||
305 | case ACPI_GPE_ENABLE: | ||
306 | ACPI_SET_BIT(gpe_register_info->enable_for_wake, | ||
307 | (u8)register_bit); | ||
308 | break; | ||
309 | |||
310 | case ACPI_GPE_DISABLE: | ||
311 | ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, | ||
312 | (u8)register_bit); | ||
313 | break; | ||
314 | |||
315 | default: | ||
316 | ACPI_ERROR((AE_INFO, "%u, Invalid action", action)); | ||
317 | status = AE_BAD_PARAMETER; | ||
318 | break; | ||
319 | } | ||
320 | |||
321 | unlock_and_exit: | ||
322 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
323 | return_ACPI_STATUS(status); | ||
324 | } | ||
325 | |||
326 | ACPI_EXPORT_SYMBOL(acpi_set_gpe_wake_mask) | ||
327 | |||
328 | /******************************************************************************* | ||
329 | * | ||
330 | * FUNCTION: acpi_clear_gpe | ||
331 | * | ||
332 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
333 | * gpe_number - GPE level within the GPE block | ||
334 | * | ||
335 | * RETURN: Status | ||
336 | * | ||
337 | * DESCRIPTION: Clear an ACPI event (general purpose) | ||
338 | * | ||
339 | ******************************************************************************/ | ||
340 | acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number) | ||
341 | { | ||
342 | acpi_status status = AE_OK; | ||
343 | struct acpi_gpe_event_info *gpe_event_info; | ||
344 | acpi_cpu_flags flags; | ||
345 | |||
346 | ACPI_FUNCTION_TRACE(acpi_clear_gpe); | ||
347 | |||
348 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
349 | |||
350 | /* Ensure that we have a valid GPE number */ | ||
351 | |||
352 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
353 | if (!gpe_event_info) { | ||
354 | status = AE_BAD_PARAMETER; | ||
355 | goto unlock_and_exit; | ||
356 | } | ||
357 | |||
358 | status = acpi_hw_clear_gpe(gpe_event_info); | ||
359 | |||
360 | unlock_and_exit: | ||
361 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
362 | return_ACPI_STATUS(status); | ||
363 | } | ||
364 | |||
365 | ACPI_EXPORT_SYMBOL(acpi_clear_gpe) | ||
366 | |||
367 | /******************************************************************************* | ||
368 | * | ||
369 | * FUNCTION: acpi_get_gpe_status | ||
370 | * | ||
371 | * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 | ||
372 | * gpe_number - GPE level within the GPE block | ||
373 | * event_status - Where the current status of the event will | ||
374 | * be returned | ||
375 | * | ||
376 | * RETURN: Status | ||
377 | * | ||
378 | * DESCRIPTION: Get the current status of a GPE (signalled/not_signalled) | ||
379 | * | ||
380 | ******************************************************************************/ | ||
381 | acpi_status | ||
382 | acpi_get_gpe_status(acpi_handle gpe_device, | ||
383 | u32 gpe_number, acpi_event_status *event_status) | ||
384 | { | ||
385 | acpi_status status = AE_OK; | ||
386 | struct acpi_gpe_event_info *gpe_event_info; | ||
387 | acpi_cpu_flags flags; | ||
388 | |||
389 | ACPI_FUNCTION_TRACE(acpi_get_gpe_status); | ||
390 | |||
391 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
392 | |||
393 | /* Ensure that we have a valid GPE number */ | ||
394 | |||
395 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
396 | if (!gpe_event_info) { | ||
397 | status = AE_BAD_PARAMETER; | ||
398 | goto unlock_and_exit; | ||
399 | } | ||
400 | |||
401 | /* Obtain status on the requested GPE number */ | ||
402 | |||
403 | status = acpi_hw_get_gpe_status(gpe_event_info, event_status); | ||
404 | |||
405 | if (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) | ||
406 | *event_status |= ACPI_EVENT_FLAG_HANDLE; | ||
407 | |||
408 | unlock_and_exit: | ||
409 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | ||
410 | return_ACPI_STATUS(status); | ||
411 | } | ||
412 | |||
413 | ACPI_EXPORT_SYMBOL(acpi_get_gpe_status) | ||
414 | |||
415 | /****************************************************************************** | ||
416 | * | ||
417 | * FUNCTION: acpi_disable_all_gpes | ||
418 | * | ||
419 | * PARAMETERS: None | ||
420 | * | ||
421 | * RETURN: Status | ||
422 | * | ||
423 | * DESCRIPTION: Disable and clear all GPEs in all GPE blocks | ||
424 | * | ||
425 | ******************************************************************************/ | ||
426 | |||
427 | acpi_status acpi_disable_all_gpes(void) | ||
428 | { | ||
429 | acpi_status status; | ||
430 | |||
431 | ACPI_FUNCTION_TRACE(acpi_disable_all_gpes); | ||
432 | |||
433 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
434 | if (ACPI_FAILURE(status)) { | ||
435 | return_ACPI_STATUS(status); | ||
436 | } | ||
437 | |||
438 | status = acpi_hw_disable_all_gpes(); | ||
439 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
440 | |||
441 | return_ACPI_STATUS(status); | ||
442 | } | ||
443 | |||
444 | ACPI_EXPORT_SYMBOL(acpi_disable_all_gpes) | ||
445 | |||
446 | /****************************************************************************** | ||
447 | * | ||
448 | * FUNCTION: acpi_enable_all_runtime_gpes | ||
449 | * | ||
450 | * PARAMETERS: None | ||
451 | * | ||
452 | * RETURN: Status | ||
453 | * | ||
454 | * DESCRIPTION: Enable all "runtime" GPEs, in all GPE blocks | ||
455 | * | ||
456 | ******************************************************************************/ | ||
457 | |||
458 | acpi_status acpi_enable_all_runtime_gpes(void) | ||
459 | { | ||
460 | acpi_status status; | ||
461 | |||
462 | ACPI_FUNCTION_TRACE(acpi_enable_all_runtime_gpes); | ||
463 | |||
464 | status = acpi_ut_acquire_mutex(ACPI_MTX_EVENTS); | ||
465 | if (ACPI_FAILURE(status)) { | ||
466 | return_ACPI_STATUS(status); | ||
467 | } | ||
468 | |||
469 | status = acpi_hw_enable_all_runtime_gpes(); | ||
470 | (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); | ||
471 | |||
472 | return_ACPI_STATUS(status); | ||
473 | } | ||
474 | |||
475 | ACPI_EXPORT_SYMBOL(acpi_enable_all_runtime_gpes) | ||
476 | |||
477 | /******************************************************************************* | ||
478 | * | ||
479 | * FUNCTION: acpi_install_gpe_block | ||
480 | * | ||
481 | * PARAMETERS: gpe_device - Handle to the parent GPE Block Device | ||
482 | * gpe_block_address - Address and space_iD | ||
483 | * register_count - Number of GPE register pairs in the block | ||
484 | * interrupt_number - H/W interrupt for the block | ||
485 | * | ||
486 | * RETURN: Status | ||
487 | * | ||
488 | * DESCRIPTION: Create and Install a block of GPE registers. The GPEs are not | ||
489 | * enabled here. | ||
490 | * | ||
491 | ******************************************************************************/ | ||
492 | acpi_status | ||
493 | acpi_install_gpe_block(acpi_handle gpe_device, | ||
494 | struct acpi_generic_address *gpe_block_address, | ||
495 | u32 register_count, u32 interrupt_number) | ||
496 | { | ||
497 | acpi_status status; | ||
498 | union acpi_operand_object *obj_desc; | ||
499 | struct acpi_namespace_node *node; | ||
500 | struct acpi_gpe_block_info *gpe_block; | ||
501 | |||
502 | ACPI_FUNCTION_TRACE(acpi_install_gpe_block); | ||
503 | |||
504 | if ((!gpe_device) || (!gpe_block_address) || (!register_count)) { | ||
505 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
506 | } | ||
507 | |||
508 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
509 | if (ACPI_FAILURE(status)) { | ||
510 | return (status); | ||
511 | } | ||
512 | |||
513 | node = acpi_ns_validate_handle(gpe_device); | ||
514 | if (!node) { | ||
515 | status = AE_BAD_PARAMETER; | ||
516 | goto unlock_and_exit; | ||
517 | } | ||
518 | |||
519 | /* | ||
520 | * For user-installed GPE Block Devices, the gpe_block_base_number | ||
521 | * is always zero | ||
522 | */ | ||
523 | status = | ||
524 | acpi_ev_create_gpe_block(node, gpe_block_address, register_count, 0, | ||
525 | interrupt_number, &gpe_block); | ||
526 | if (ACPI_FAILURE(status)) { | ||
527 | goto unlock_and_exit; | ||
528 | } | ||
529 | |||
530 | /* Install block in the device_object attached to the node */ | ||
531 | |||
532 | obj_desc = acpi_ns_get_attached_object(node); | ||
533 | if (!obj_desc) { | ||
534 | |||
535 | /* | ||
536 | * No object, create a new one (Device nodes do not always have | ||
537 | * an attached object) | ||
538 | */ | ||
539 | obj_desc = acpi_ut_create_internal_object(ACPI_TYPE_DEVICE); | ||
540 | if (!obj_desc) { | ||
541 | status = AE_NO_MEMORY; | ||
542 | goto unlock_and_exit; | ||
543 | } | ||
544 | |||
545 | status = | ||
546 | acpi_ns_attach_object(node, obj_desc, ACPI_TYPE_DEVICE); | ||
547 | |||
548 | /* Remove local reference to the object */ | ||
549 | |||
550 | acpi_ut_remove_reference(obj_desc); | ||
551 | |||
552 | if (ACPI_FAILURE(status)) { | ||
553 | goto unlock_and_exit; | ||
554 | } | ||
555 | } | ||
556 | |||
557 | /* Now install the GPE block in the device_object */ | ||
558 | |||
559 | obj_desc->device.gpe_block = gpe_block; | ||
560 | |||
561 | unlock_and_exit: | ||
562 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
563 | return_ACPI_STATUS(status); | ||
564 | } | ||
565 | |||
566 | ACPI_EXPORT_SYMBOL(acpi_install_gpe_block) | ||
567 | |||
568 | /******************************************************************************* | ||
569 | * | ||
570 | * FUNCTION: acpi_remove_gpe_block | ||
571 | * | ||
572 | * PARAMETERS: gpe_device - Handle to the parent GPE Block Device | ||
573 | * | ||
574 | * RETURN: Status | ||
575 | * | ||
576 | * DESCRIPTION: Remove a previously installed block of GPE registers | ||
577 | * | ||
578 | ******************************************************************************/ | ||
579 | acpi_status acpi_remove_gpe_block(acpi_handle gpe_device) | ||
580 | { | ||
581 | union acpi_operand_object *obj_desc; | ||
582 | acpi_status status; | ||
583 | struct acpi_namespace_node *node; | ||
584 | |||
585 | ACPI_FUNCTION_TRACE(acpi_remove_gpe_block); | ||
586 | |||
587 | if (!gpe_device) { | ||
588 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
589 | } | ||
590 | |||
591 | status = acpi_ut_acquire_mutex(ACPI_MTX_NAMESPACE); | ||
592 | if (ACPI_FAILURE(status)) { | ||
593 | return (status); | ||
594 | } | ||
595 | |||
596 | node = acpi_ns_validate_handle(gpe_device); | ||
597 | if (!node) { | ||
598 | status = AE_BAD_PARAMETER; | ||
599 | goto unlock_and_exit; | ||
600 | } | ||
601 | |||
602 | /* Get the device_object attached to the node */ | ||
603 | |||
604 | obj_desc = acpi_ns_get_attached_object(node); | ||
605 | if (!obj_desc || !obj_desc->device.gpe_block) { | ||
606 | return_ACPI_STATUS(AE_NULL_OBJECT); | ||
607 | } | ||
608 | |||
609 | /* Delete the GPE block (but not the device_object) */ | ||
610 | |||
611 | status = acpi_ev_delete_gpe_block(obj_desc->device.gpe_block); | ||
612 | if (ACPI_SUCCESS(status)) { | ||
613 | obj_desc->device.gpe_block = NULL; | ||
614 | } | ||
615 | |||
616 | unlock_and_exit: | ||
617 | (void)acpi_ut_release_mutex(ACPI_MTX_NAMESPACE); | ||
618 | return_ACPI_STATUS(status); | ||
619 | } | ||
620 | |||
621 | ACPI_EXPORT_SYMBOL(acpi_remove_gpe_block) | ||
622 | |||
623 | /******************************************************************************* | ||
624 | * | ||
625 | * FUNCTION: acpi_get_gpe_device | ||
626 | * | ||
627 | * PARAMETERS: Index - System GPE index (0-current_gpe_count) | ||
628 | * gpe_device - Where the parent GPE Device is returned | ||
629 | * | ||
630 | * RETURN: Status | ||
631 | * | ||
632 | * DESCRIPTION: Obtain the GPE device associated with the input index. A NULL | ||
633 | * gpe device indicates that the gpe number is contained in one of | ||
634 | * the FADT-defined gpe blocks. Otherwise, the GPE block device. | ||
635 | * | ||
636 | ******************************************************************************/ | ||
637 | acpi_status | ||
638 | acpi_get_gpe_device(u32 index, acpi_handle *gpe_device) | ||
639 | { | ||
640 | struct acpi_gpe_device_info info; | ||
641 | acpi_status status; | ||
642 | |||
643 | ACPI_FUNCTION_TRACE(acpi_get_gpe_device); | ||
644 | |||
645 | if (!gpe_device) { | ||
646 | return_ACPI_STATUS(AE_BAD_PARAMETER); | ||
647 | } | ||
648 | |||
649 | if (index >= acpi_current_gpe_count) { | ||
650 | return_ACPI_STATUS(AE_NOT_EXIST); | ||
651 | } | ||
652 | |||
653 | /* Setup and walk the GPE list */ | ||
654 | |||
655 | info.index = index; | ||
656 | info.status = AE_NOT_EXIST; | ||
657 | info.gpe_device = NULL; | ||
658 | info.next_block_base_index = 0; | ||
659 | |||
660 | status = acpi_ev_walk_gpe_list(acpi_ev_get_gpe_device, &info); | ||
661 | if (ACPI_FAILURE(status)) { | ||
662 | return_ACPI_STATUS(status); | ||
663 | } | ||
664 | |||
665 | *gpe_device = ACPI_CAST_PTR(acpi_handle, info.gpe_device); | ||
666 | return_ACPI_STATUS(info.status); | ||
667 | } | ||
668 | |||
669 | ACPI_EXPORT_SYMBOL(acpi_get_gpe_device) | ||
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c index 14750db2a1b8..85c3cbd4304d 100644 --- a/drivers/acpi/acpica/hwgpe.c +++ b/drivers/acpi/acpica/hwgpe.c | |||
@@ -62,10 +62,10 @@ acpi_hw_enable_wakeup_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info, | |||
62 | * PARAMETERS: gpe_event_info - Info block for the GPE | 62 | * PARAMETERS: gpe_event_info - Info block for the GPE |
63 | * gpe_register_info - Info block for the GPE register | 63 | * gpe_register_info - Info block for the GPE register |
64 | * | 64 | * |
65 | * RETURN: Status | 65 | * RETURN: Register mask with a one in the GPE bit position |
66 | * | 66 | * |
67 | * DESCRIPTION: Compute GPE enable mask with one bit corresponding to the given | 67 | * DESCRIPTION: Compute the register mask for this GPE. One bit is set in the |
68 | * GPE set. | 68 | * correct position for the input GPE. |
69 | * | 69 | * |
70 | ******************************************************************************/ | 70 | ******************************************************************************/ |
71 | 71 | ||
@@ -85,12 +85,12 @@ u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info, | |||
85 | * | 85 | * |
86 | * RETURN: Status | 86 | * RETURN: Status |
87 | * | 87 | * |
88 | * DESCRIPTION: Enable or disable a single GPE in its enable register. | 88 | * DESCRIPTION: Enable or disable a single GPE in the parent enable register. |
89 | * | 89 | * |
90 | ******************************************************************************/ | 90 | ******************************************************************************/ |
91 | 91 | ||
92 | acpi_status | 92 | acpi_status |
93 | acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action) | 93 | acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action) |
94 | { | 94 | { |
95 | struct acpi_gpe_register_info *gpe_register_info; | 95 | struct acpi_gpe_register_info *gpe_register_info; |
96 | acpi_status status; | 96 | acpi_status status; |
@@ -113,14 +113,20 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action) | |||
113 | return (status); | 113 | return (status); |
114 | } | 114 | } |
115 | 115 | ||
116 | /* Set ot clear just the bit that corresponds to this GPE */ | 116 | /* Set or clear just the bit that corresponds to this GPE */ |
117 | 117 | ||
118 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info, | 118 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info, |
119 | gpe_register_info); | 119 | gpe_register_info); |
120 | switch (action) { | 120 | switch (action) { |
121 | case ACPI_GPE_COND_ENABLE: | 121 | case ACPI_GPE_CONDITIONAL_ENABLE: |
122 | if (!(register_bit & gpe_register_info->enable_for_run)) | 122 | |
123 | /* Only enable if the enable_for_run bit is set */ | ||
124 | |||
125 | if (!(register_bit & gpe_register_info->enable_for_run)) { | ||
123 | return (AE_BAD_PARAMETER); | 126 | return (AE_BAD_PARAMETER); |
127 | } | ||
128 | |||
129 | /*lint -fallthrough */ | ||
124 | 130 | ||
125 | case ACPI_GPE_ENABLE: | 131 | case ACPI_GPE_ENABLE: |
126 | ACPI_SET_BIT(enable_mask, register_bit); | 132 | ACPI_SET_BIT(enable_mask, register_bit); |
@@ -131,7 +137,7 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u8 action) | |||
131 | break; | 137 | break; |
132 | 138 | ||
133 | default: | 139 | default: |
134 | ACPI_ERROR((AE_INFO, "Invalid action\n")); | 140 | ACPI_ERROR((AE_INFO, "Invalid GPE Action, %u\n", action)); |
135 | return (AE_BAD_PARAMETER); | 141 | return (AE_BAD_PARAMETER); |
136 | } | 142 | } |
137 | 143 | ||
@@ -168,13 +174,13 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info * gpe_event_info) | |||
168 | return (AE_NOT_EXIST); | 174 | return (AE_NOT_EXIST); |
169 | } | 175 | } |
170 | 176 | ||
171 | register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info, | ||
172 | gpe_register_info); | ||
173 | |||
174 | /* | 177 | /* |
175 | * Write a one to the appropriate bit in the status register to | 178 | * Write a one to the appropriate bit in the status register to |
176 | * clear this GPE. | 179 | * clear this GPE. |
177 | */ | 180 | */ |
181 | register_bit = | ||
182 | acpi_hw_get_gpe_register_bit(gpe_event_info, gpe_register_info); | ||
183 | |||
178 | status = acpi_hw_write(register_bit, | 184 | status = acpi_hw_write(register_bit, |
179 | &gpe_register_info->status_address); | 185 | &gpe_register_info->status_address); |
180 | 186 | ||
@@ -201,8 +207,8 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info * gpe_event_info, | |||
201 | u32 in_byte; | 207 | u32 in_byte; |
202 | u32 register_bit; | 208 | u32 register_bit; |
203 | struct acpi_gpe_register_info *gpe_register_info; | 209 | struct acpi_gpe_register_info *gpe_register_info; |
204 | acpi_status status; | ||
205 | acpi_event_status local_event_status = 0; | 210 | acpi_event_status local_event_status = 0; |
211 | acpi_status status; | ||
206 | 212 | ||
207 | ACPI_FUNCTION_ENTRY(); | 213 | ACPI_FUNCTION_ENTRY(); |
208 | 214 | ||
diff --git a/drivers/acpi/acpica/utglobal.c b/drivers/acpi/acpica/utglobal.c index e87bc6760be6..508537f884ac 100644 --- a/drivers/acpi/acpica/utglobal.c +++ b/drivers/acpi/acpica/utglobal.c | |||
@@ -768,7 +768,7 @@ acpi_status acpi_ut_init_globals(void) | |||
768 | acpi_gbl_gpe_fadt_blocks[0] = NULL; | 768 | acpi_gbl_gpe_fadt_blocks[0] = NULL; |
769 | acpi_gbl_gpe_fadt_blocks[1] = NULL; | 769 | acpi_gbl_gpe_fadt_blocks[1] = NULL; |
770 | acpi_current_gpe_count = 0; | 770 | acpi_current_gpe_count = 0; |
771 | acpi_all_gpes_initialized = FALSE; | 771 | acpi_gbl_all_gpes_initialized = FALSE; |
772 | 772 | ||
773 | /* Global handlers */ | 773 | /* Global handlers */ |
774 | 774 | ||
@@ -778,6 +778,7 @@ acpi_status acpi_ut_init_globals(void) | |||
778 | acpi_gbl_init_handler = NULL; | 778 | acpi_gbl_init_handler = NULL; |
779 | acpi_gbl_table_handler = NULL; | 779 | acpi_gbl_table_handler = NULL; |
780 | acpi_gbl_interface_handler = NULL; | 780 | acpi_gbl_interface_handler = NULL; |
781 | acpi_gbl_global_event_handler = NULL; | ||
781 | 782 | ||
782 | /* Global Lock support */ | 783 | /* Global Lock support */ |
783 | 784 | ||
diff --git a/drivers/acpi/apei/erst.c b/drivers/acpi/apei/erst.c index 1211c03149e8..5850d320404c 100644 --- a/drivers/acpi/apei/erst.c +++ b/drivers/acpi/apei/erst.c | |||
@@ -86,7 +86,7 @@ static struct erst_erange { | |||
86 | * It is used to provide exclusive accessing for ERST Error Log | 86 | * It is used to provide exclusive accessing for ERST Error Log |
87 | * Address Range too. | 87 | * Address Range too. |
88 | */ | 88 | */ |
89 | static DEFINE_SPINLOCK(erst_lock); | 89 | static DEFINE_RAW_SPINLOCK(erst_lock); |
90 | 90 | ||
91 | static inline int erst_errno(int command_status) | 91 | static inline int erst_errno(int command_status) |
92 | { | 92 | { |
@@ -421,9 +421,9 @@ ssize_t erst_get_record_count(void) | |||
421 | if (erst_disable) | 421 | if (erst_disable) |
422 | return -ENODEV; | 422 | return -ENODEV; |
423 | 423 | ||
424 | spin_lock_irqsave(&erst_lock, flags); | 424 | raw_spin_lock_irqsave(&erst_lock, flags); |
425 | count = __erst_get_record_count(); | 425 | count = __erst_get_record_count(); |
426 | spin_unlock_irqrestore(&erst_lock, flags); | 426 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
427 | 427 | ||
428 | return count; | 428 | return count; |
429 | } | 429 | } |
@@ -456,9 +456,9 @@ int erst_get_next_record_id(u64 *record_id) | |||
456 | if (erst_disable) | 456 | if (erst_disable) |
457 | return -ENODEV; | 457 | return -ENODEV; |
458 | 458 | ||
459 | spin_lock_irqsave(&erst_lock, flags); | 459 | raw_spin_lock_irqsave(&erst_lock, flags); |
460 | rc = __erst_get_next_record_id(record_id); | 460 | rc = __erst_get_next_record_id(record_id); |
461 | spin_unlock_irqrestore(&erst_lock, flags); | 461 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
462 | 462 | ||
463 | return rc; | 463 | return rc; |
464 | } | 464 | } |
@@ -624,17 +624,17 @@ int erst_write(const struct cper_record_header *record) | |||
624 | return -EINVAL; | 624 | return -EINVAL; |
625 | 625 | ||
626 | if (erst_erange.attr & ERST_RANGE_NVRAM) { | 626 | if (erst_erange.attr & ERST_RANGE_NVRAM) { |
627 | if (!spin_trylock_irqsave(&erst_lock, flags)) | 627 | if (!raw_spin_trylock_irqsave(&erst_lock, flags)) |
628 | return -EBUSY; | 628 | return -EBUSY; |
629 | rc = __erst_write_to_nvram(record); | 629 | rc = __erst_write_to_nvram(record); |
630 | spin_unlock_irqrestore(&erst_lock, flags); | 630 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
631 | return rc; | 631 | return rc; |
632 | } | 632 | } |
633 | 633 | ||
634 | if (record->record_length > erst_erange.size) | 634 | if (record->record_length > erst_erange.size) |
635 | return -EINVAL; | 635 | return -EINVAL; |
636 | 636 | ||
637 | if (!spin_trylock_irqsave(&erst_lock, flags)) | 637 | if (!raw_spin_trylock_irqsave(&erst_lock, flags)) |
638 | return -EBUSY; | 638 | return -EBUSY; |
639 | memcpy(erst_erange.vaddr, record, record->record_length); | 639 | memcpy(erst_erange.vaddr, record, record->record_length); |
640 | rcd_erange = erst_erange.vaddr; | 640 | rcd_erange = erst_erange.vaddr; |
@@ -642,7 +642,7 @@ int erst_write(const struct cper_record_header *record) | |||
642 | memcpy(&rcd_erange->persistence_information, "ER", 2); | 642 | memcpy(&rcd_erange->persistence_information, "ER", 2); |
643 | 643 | ||
644 | rc = __erst_write_to_storage(0); | 644 | rc = __erst_write_to_storage(0); |
645 | spin_unlock_irqrestore(&erst_lock, flags); | 645 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
646 | 646 | ||
647 | return rc; | 647 | return rc; |
648 | } | 648 | } |
@@ -696,9 +696,9 @@ ssize_t erst_read(u64 record_id, struct cper_record_header *record, | |||
696 | if (erst_disable) | 696 | if (erst_disable) |
697 | return -ENODEV; | 697 | return -ENODEV; |
698 | 698 | ||
699 | spin_lock_irqsave(&erst_lock, flags); | 699 | raw_spin_lock_irqsave(&erst_lock, flags); |
700 | len = __erst_read(record_id, record, buflen); | 700 | len = __erst_read(record_id, record, buflen); |
701 | spin_unlock_irqrestore(&erst_lock, flags); | 701 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
702 | return len; | 702 | return len; |
703 | } | 703 | } |
704 | EXPORT_SYMBOL_GPL(erst_read); | 704 | EXPORT_SYMBOL_GPL(erst_read); |
@@ -719,20 +719,20 @@ ssize_t erst_read_next(struct cper_record_header *record, size_t buflen) | |||
719 | if (erst_disable) | 719 | if (erst_disable) |
720 | return -ENODEV; | 720 | return -ENODEV; |
721 | 721 | ||
722 | spin_lock_irqsave(&erst_lock, flags); | 722 | raw_spin_lock_irqsave(&erst_lock, flags); |
723 | rc = __erst_get_next_record_id(&record_id); | 723 | rc = __erst_get_next_record_id(&record_id); |
724 | if (rc) { | 724 | if (rc) { |
725 | spin_unlock_irqrestore(&erst_lock, flags); | 725 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
726 | return rc; | 726 | return rc; |
727 | } | 727 | } |
728 | /* no more record */ | 728 | /* no more record */ |
729 | if (record_id == APEI_ERST_INVALID_RECORD_ID) { | 729 | if (record_id == APEI_ERST_INVALID_RECORD_ID) { |
730 | spin_unlock_irqrestore(&erst_lock, flags); | 730 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
731 | return 0; | 731 | return 0; |
732 | } | 732 | } |
733 | 733 | ||
734 | len = __erst_read(record_id, record, buflen); | 734 | len = __erst_read(record_id, record, buflen); |
735 | spin_unlock_irqrestore(&erst_lock, flags); | 735 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
736 | 736 | ||
737 | return len; | 737 | return len; |
738 | } | 738 | } |
@@ -746,12 +746,12 @@ int erst_clear(u64 record_id) | |||
746 | if (erst_disable) | 746 | if (erst_disable) |
747 | return -ENODEV; | 747 | return -ENODEV; |
748 | 748 | ||
749 | spin_lock_irqsave(&erst_lock, flags); | 749 | raw_spin_lock_irqsave(&erst_lock, flags); |
750 | if (erst_erange.attr & ERST_RANGE_NVRAM) | 750 | if (erst_erange.attr & ERST_RANGE_NVRAM) |
751 | rc = __erst_clear_from_nvram(record_id); | 751 | rc = __erst_clear_from_nvram(record_id); |
752 | else | 752 | else |
753 | rc = __erst_clear_from_storage(record_id); | 753 | rc = __erst_clear_from_storage(record_id); |
754 | spin_unlock_irqrestore(&erst_lock, flags); | 754 | raw_spin_unlock_irqrestore(&erst_lock, flags); |
755 | 755 | ||
756 | return rc; | 756 | return rc; |
757 | } | 757 | } |
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index 1a3508a7fe03..daa7bc63f1d4 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c | |||
@@ -46,9 +46,9 @@ EXPORT_SYMBOL_GPL(hest_disable); | |||
46 | 46 | ||
47 | /* HEST table parsing */ | 47 | /* HEST table parsing */ |
48 | 48 | ||
49 | static struct acpi_table_hest *hest_tab; | 49 | static struct acpi_table_hest *__read_mostly hest_tab; |
50 | 50 | ||
51 | static int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { | 51 | static const int hest_esrc_len_tab[ACPI_HEST_TYPE_RESERVED] = { |
52 | [ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */ | 52 | [ACPI_HEST_TYPE_IA32_CHECK] = -1, /* need further calculation */ |
53 | [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1, | 53 | [ACPI_HEST_TYPE_IA32_CORRECTED_CHECK] = -1, |
54 | [ACPI_HEST_TYPE_IA32_NMI] = sizeof(struct acpi_hest_ia_nmi), | 54 | [ACPI_HEST_TYPE_IA32_NMI] = sizeof(struct acpi_hest_ia_nmi), |
@@ -126,7 +126,7 @@ struct ghes_arr { | |||
126 | unsigned int count; | 126 | unsigned int count; |
127 | }; | 127 | }; |
128 | 128 | ||
129 | static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) | 129 | static int __init hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) |
130 | { | 130 | { |
131 | int *count = data; | 131 | int *count = data; |
132 | 132 | ||
@@ -135,7 +135,7 @@ static int hest_parse_ghes_count(struct acpi_hest_header *hest_hdr, void *data) | |||
135 | return 0; | 135 | return 0; |
136 | } | 136 | } |
137 | 137 | ||
138 | static int hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) | 138 | static int __init hest_parse_ghes(struct acpi_hest_header *hest_hdr, void *data) |
139 | { | 139 | { |
140 | struct platform_device *ghes_dev; | 140 | struct platform_device *ghes_dev; |
141 | struct ghes_arr *ghes_arr = data; | 141 | struct ghes_arr *ghes_arr = data; |
@@ -165,7 +165,7 @@ err: | |||
165 | return rc; | 165 | return rc; |
166 | } | 166 | } |
167 | 167 | ||
168 | static int hest_ghes_dev_register(unsigned int ghes_count) | 168 | static int __init hest_ghes_dev_register(unsigned int ghes_count) |
169 | { | 169 | { |
170 | int rc, i; | 170 | int rc, i; |
171 | struct ghes_arr ghes_arr; | 171 | struct ghes_arr ghes_arr; |
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index d68bd61072bb..7ced61f39492 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c | |||
@@ -52,22 +52,6 @@ EXPORT_SYMBOL(acpi_root_dir); | |||
52 | 52 | ||
53 | #define STRUCT_TO_INT(s) (*((int*)&s)) | 53 | #define STRUCT_TO_INT(s) (*((int*)&s)) |
54 | 54 | ||
55 | static int set_power_nocheck(const struct dmi_system_id *id) | ||
56 | { | ||
57 | printk(KERN_NOTICE PREFIX "%s detected - " | ||
58 | "disable power check in power transition\n", id->ident); | ||
59 | acpi_power_nocheck = 1; | ||
60 | return 0; | ||
61 | } | ||
62 | static struct dmi_system_id __cpuinitdata power_nocheck_dmi_table[] = { | ||
63 | { | ||
64 | set_power_nocheck, "HP Pavilion 05", { | ||
65 | DMI_MATCH(DMI_BIOS_VENDOR, "Phoenix Technologies LTD"), | ||
66 | DMI_MATCH(DMI_SYS_VENDOR, "HP Pavilion 05"), | ||
67 | DMI_MATCH(DMI_PRODUCT_VERSION, "2001211RE101GLEND") }, NULL}, | ||
68 | {}, | ||
69 | }; | ||
70 | |||
71 | 55 | ||
72 | #ifdef CONFIG_X86 | 56 | #ifdef CONFIG_X86 |
73 | static int set_copy_dsdt(const struct dmi_system_id *id) | 57 | static int set_copy_dsdt(const struct dmi_system_id *id) |
@@ -196,33 +180,24 @@ EXPORT_SYMBOL(acpi_bus_get_private_data); | |||
196 | Power Management | 180 | Power Management |
197 | -------------------------------------------------------------------------- */ | 181 | -------------------------------------------------------------------------- */ |
198 | 182 | ||
199 | int acpi_bus_get_power(acpi_handle handle, int *state) | 183 | static int __acpi_bus_get_power(struct acpi_device *device, int *state) |
200 | { | 184 | { |
201 | int result = 0; | 185 | int result = 0; |
202 | acpi_status status = 0; | 186 | acpi_status status = 0; |
203 | struct acpi_device *device = NULL; | ||
204 | unsigned long long psc = 0; | 187 | unsigned long long psc = 0; |
205 | 188 | ||
206 | 189 | if (!device || !state) | |
207 | result = acpi_bus_get_device(handle, &device); | 190 | return -EINVAL; |
208 | if (result) | ||
209 | return result; | ||
210 | 191 | ||
211 | *state = ACPI_STATE_UNKNOWN; | 192 | *state = ACPI_STATE_UNKNOWN; |
212 | 193 | ||
213 | if (!device->flags.power_manageable) { | 194 | if (device->flags.power_manageable) { |
214 | /* TBD: Non-recursive algorithm for walking up hierarchy */ | ||
215 | if (device->parent) | ||
216 | *state = device->parent->power.state; | ||
217 | else | ||
218 | *state = ACPI_STATE_D0; | ||
219 | } else { | ||
220 | /* | 195 | /* |
221 | * Get the device's power state either directly (via _PSC) or | 196 | * Get the device's power state either directly (via _PSC) or |
222 | * indirectly (via power resources). | 197 | * indirectly (via power resources). |
223 | */ | 198 | */ |
224 | if (device->power.flags.power_resources) { | 199 | if (device->power.flags.power_resources) { |
225 | result = acpi_power_get_inferred_state(device); | 200 | result = acpi_power_get_inferred_state(device, state); |
226 | if (result) | 201 | if (result) |
227 | return result; | 202 | return result; |
228 | } else if (device->power.flags.explicit_get) { | 203 | } else if (device->power.flags.explicit_get) { |
@@ -230,59 +205,33 @@ int acpi_bus_get_power(acpi_handle handle, int *state) | |||
230 | NULL, &psc); | 205 | NULL, &psc); |
231 | if (ACPI_FAILURE(status)) | 206 | if (ACPI_FAILURE(status)) |
232 | return -ENODEV; | 207 | return -ENODEV; |
233 | device->power.state = (int)psc; | 208 | *state = (int)psc; |
234 | } | 209 | } |
235 | 210 | } else { | |
236 | *state = device->power.state; | 211 | /* TBD: Non-recursive algorithm for walking up hierarchy. */ |
212 | *state = device->parent ? | ||
213 | device->parent->power.state : ACPI_STATE_D0; | ||
237 | } | 214 | } |
238 | 215 | ||
239 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n", | 216 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] power state is D%d\n", |
240 | device->pnp.bus_id, device->power.state)); | 217 | device->pnp.bus_id, *state)); |
241 | 218 | ||
242 | return 0; | 219 | return 0; |
243 | } | 220 | } |
244 | 221 | ||
245 | EXPORT_SYMBOL(acpi_bus_get_power); | ||
246 | 222 | ||
247 | int acpi_bus_set_power(acpi_handle handle, int state) | 223 | static int __acpi_bus_set_power(struct acpi_device *device, int state) |
248 | { | 224 | { |
249 | int result = 0; | 225 | int result = 0; |
250 | acpi_status status = AE_OK; | 226 | acpi_status status = AE_OK; |
251 | struct acpi_device *device = NULL; | ||
252 | char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' }; | 227 | char object_name[5] = { '_', 'P', 'S', '0' + state, '\0' }; |
253 | 228 | ||
254 | 229 | if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) | |
255 | result = acpi_bus_get_device(handle, &device); | ||
256 | if (result) | ||
257 | return result; | ||
258 | |||
259 | if ((state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) | ||
260 | return -EINVAL; | 230 | return -EINVAL; |
261 | 231 | ||
262 | /* Make sure this is a valid target state */ | 232 | /* Make sure this is a valid target state */ |
263 | 233 | ||
264 | if (!device->flags.power_manageable) { | 234 | if (state == device->power.state) { |
265 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device `[%s]' is not power manageable\n", | ||
266 | kobject_name(&device->dev.kobj))); | ||
267 | return -ENODEV; | ||
268 | } | ||
269 | /* | ||
270 | * Get device's current power state | ||
271 | */ | ||
272 | if (!acpi_power_nocheck) { | ||
273 | /* | ||
274 | * Maybe the incorrect power state is returned on the bogus | ||
275 | * bios, which is different with the real power state. | ||
276 | * For example: the bios returns D0 state and the real power | ||
277 | * state is D3. OS expects to set the device to D0 state. In | ||
278 | * such case if OS uses the power state returned by the BIOS, | ||
279 | * the device can't be transisted to the correct power state. | ||
280 | * So if the acpi_power_nocheck is set, it is unnecessary to | ||
281 | * get the power state by calling acpi_bus_get_power. | ||
282 | */ | ||
283 | acpi_bus_get_power(device->handle, &device->power.state); | ||
284 | } | ||
285 | if ((state == device->power.state) && !device->flags.force_power_state) { | ||
286 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", | 235 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", |
287 | state)); | 236 | state)); |
288 | return 0; | 237 | return 0; |
@@ -351,8 +300,75 @@ int acpi_bus_set_power(acpi_handle handle, int state) | |||
351 | return result; | 300 | return result; |
352 | } | 301 | } |
353 | 302 | ||
303 | |||
304 | int acpi_bus_set_power(acpi_handle handle, int state) | ||
305 | { | ||
306 | struct acpi_device *device; | ||
307 | int result; | ||
308 | |||
309 | result = acpi_bus_get_device(handle, &device); | ||
310 | if (result) | ||
311 | return result; | ||
312 | |||
313 | if (!device->flags.power_manageable) { | ||
314 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | ||
315 | "Device [%s] is not power manageable\n", | ||
316 | dev_name(&device->dev))); | ||
317 | return -ENODEV; | ||
318 | } | ||
319 | |||
320 | return __acpi_bus_set_power(device, state); | ||
321 | } | ||
354 | EXPORT_SYMBOL(acpi_bus_set_power); | 322 | EXPORT_SYMBOL(acpi_bus_set_power); |
355 | 323 | ||
324 | |||
325 | int acpi_bus_init_power(struct acpi_device *device) | ||
326 | { | ||
327 | int state; | ||
328 | int result; | ||
329 | |||
330 | if (!device) | ||
331 | return -EINVAL; | ||
332 | |||
333 | device->power.state = ACPI_STATE_UNKNOWN; | ||
334 | |||
335 | result = __acpi_bus_get_power(device, &state); | ||
336 | if (result) | ||
337 | return result; | ||
338 | |||
339 | if (device->power.flags.power_resources) | ||
340 | result = acpi_power_on_resources(device, state); | ||
341 | |||
342 | if (!result) | ||
343 | device->power.state = state; | ||
344 | |||
345 | return result; | ||
346 | } | ||
347 | |||
348 | |||
349 | int acpi_bus_update_power(acpi_handle handle, int *state_p) | ||
350 | { | ||
351 | struct acpi_device *device; | ||
352 | int state; | ||
353 | int result; | ||
354 | |||
355 | result = acpi_bus_get_device(handle, &device); | ||
356 | if (result) | ||
357 | return result; | ||
358 | |||
359 | result = __acpi_bus_get_power(device, &state); | ||
360 | if (result) | ||
361 | return result; | ||
362 | |||
363 | result = __acpi_bus_set_power(device, state); | ||
364 | if (!result && state_p) | ||
365 | *state_p = state; | ||
366 | |||
367 | return result; | ||
368 | } | ||
369 | EXPORT_SYMBOL_GPL(acpi_bus_update_power); | ||
370 | |||
371 | |||
356 | bool acpi_bus_power_manageable(acpi_handle handle) | 372 | bool acpi_bus_power_manageable(acpi_handle handle) |
357 | { | 373 | { |
358 | struct acpi_device *device; | 374 | struct acpi_device *device; |
@@ -1023,15 +1039,8 @@ static int __init acpi_init(void) | |||
1023 | if (acpi_disabled) | 1039 | if (acpi_disabled) |
1024 | return result; | 1040 | return result; |
1025 | 1041 | ||
1026 | /* | ||
1027 | * If the laptop falls into the DMI check table, the power state check | ||
1028 | * will be disabled in the course of device power transition. | ||
1029 | */ | ||
1030 | dmi_check_system(power_nocheck_dmi_table); | ||
1031 | |||
1032 | acpi_scan_init(); | 1042 | acpi_scan_init(); |
1033 | acpi_ec_init(); | 1043 | acpi_ec_init(); |
1034 | acpi_power_init(); | ||
1035 | acpi_debugfs_init(); | 1044 | acpi_debugfs_init(); |
1036 | acpi_sleep_proc_init(); | 1045 | acpi_sleep_proc_init(); |
1037 | acpi_wakeup_device_init(); | 1046 | acpi_wakeup_device_init(); |
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 71ef9cd0735f..76bbb78a5ad9 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -279,6 +279,9 @@ static int acpi_lid_send_state(struct acpi_device *device) | |||
279 | input_report_switch(button->input, SW_LID, !state); | 279 | input_report_switch(button->input, SW_LID, !state); |
280 | input_sync(button->input); | 280 | input_sync(button->input); |
281 | 281 | ||
282 | if (state) | ||
283 | pm_wakeup_event(&device->dev, 0); | ||
284 | |||
282 | ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device); | 285 | ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, device); |
283 | if (ret == NOTIFY_DONE) | 286 | if (ret == NOTIFY_DONE) |
284 | ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, | 287 | ret = blocking_notifier_call_chain(&acpi_lid_notifier, state, |
@@ -314,6 +317,8 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) | |||
314 | input_sync(input); | 317 | input_sync(input); |
315 | input_report_key(input, keycode, 0); | 318 | input_report_key(input, keycode, 0); |
316 | input_sync(input); | 319 | input_sync(input); |
320 | |||
321 | pm_wakeup_event(&device->dev, 0); | ||
317 | } | 322 | } |
318 | 323 | ||
319 | acpi_bus_generate_proc_event(device, event, ++button->pushed); | 324 | acpi_bus_generate_proc_event(device, event, ++button->pushed); |
@@ -426,7 +431,7 @@ static int acpi_button_add(struct acpi_device *device) | |||
426 | acpi_enable_gpe(device->wakeup.gpe_device, | 431 | acpi_enable_gpe(device->wakeup.gpe_device, |
427 | device->wakeup.gpe_number); | 432 | device->wakeup.gpe_number); |
428 | device->wakeup.run_wake_count++; | 433 | device->wakeup.run_wake_count++; |
429 | device->wakeup.state.enabled = 1; | 434 | device_set_wakeup_enable(&device->dev, true); |
430 | } | 435 | } |
431 | 436 | ||
432 | printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device)); | 437 | printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device)); |
@@ -449,7 +454,7 @@ static int acpi_button_remove(struct acpi_device *device, int type) | |||
449 | acpi_disable_gpe(device->wakeup.gpe_device, | 454 | acpi_disable_gpe(device->wakeup.gpe_device, |
450 | device->wakeup.gpe_number); | 455 | device->wakeup.gpe_number); |
451 | device->wakeup.run_wake_count--; | 456 | device->wakeup.run_wake_count--; |
452 | device->wakeup.state.enabled = 0; | 457 | device_set_wakeup_enable(&device->dev, false); |
453 | } | 458 | } |
454 | 459 | ||
455 | acpi_button_remove_fs(device); | 460 | acpi_button_remove_fs(device); |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 81514a4918cc..1864ad3cf895 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -725,7 +725,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) | |||
725 | complete_dock(ds); | 725 | complete_dock(ds); |
726 | dock_event(ds, event, DOCK_EVENT); | 726 | dock_event(ds, event, DOCK_EVENT); |
727 | dock_lock(ds, 1); | 727 | dock_lock(ds, 1); |
728 | acpi_update_gpes(); | 728 | acpi_update_all_gpes(); |
729 | break; | 729 | break; |
730 | } | 730 | } |
731 | if (dock_present(ds) || dock_in_progress(ds)) | 731 | if (dock_present(ds) || dock_in_progress(ds)) |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 372ff80b7b0c..fa848c4116a8 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -606,7 +606,8 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state) | |||
606 | return 0; | 606 | return 0; |
607 | } | 607 | } |
608 | 608 | ||
609 | static u32 acpi_ec_gpe_handler(void *data) | 609 | static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, |
610 | u32 gpe_number, void *data) | ||
610 | { | 611 | { |
611 | struct acpi_ec *ec = data; | 612 | struct acpi_ec *ec = data; |
612 | 613 | ||
@@ -618,7 +619,7 @@ static u32 acpi_ec_gpe_handler(void *data) | |||
618 | wake_up(&ec->wait); | 619 | wake_up(&ec->wait); |
619 | ec_check_sci(ec, acpi_ec_read_status(ec)); | 620 | ec_check_sci(ec, acpi_ec_read_status(ec)); |
620 | } | 621 | } |
621 | return ACPI_INTERRUPT_HANDLED; | 622 | return ACPI_INTERRUPT_HANDLED | ACPI_REENABLE_GPE; |
622 | } | 623 | } |
623 | 624 | ||
624 | /* -------------------------------------------------------------------------- | 625 | /* -------------------------------------------------------------------------- |
@@ -934,6 +935,9 @@ static struct dmi_system_id __initdata ec_dmi_table[] = { | |||
934 | ec_flag_msi, "MSI hardware", { | 935 | ec_flag_msi, "MSI hardware", { |
935 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL}, | 936 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-Star")}, NULL}, |
936 | { | 937 | { |
938 | ec_flag_msi, "MSI hardware", { | ||
939 | DMI_MATCH(DMI_CHASSIS_VENDOR, "MICRO-STAR")}, NULL}, | ||
940 | { | ||
937 | ec_validate_ecdt, "ASUS hardware", { | 941 | ec_validate_ecdt, "ASUS hardware", { |
938 | DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, | 942 | DMI_MATCH(DMI_BIOS_VENDOR, "ASUS") }, NULL}, |
939 | {}, | 943 | {}, |
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 60049080c869..467479f07c1f 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -86,7 +86,7 @@ static int fan_get_cur_state(struct thermal_cooling_device *cdev, unsigned long | |||
86 | if (!device) | 86 | if (!device) |
87 | return -EINVAL; | 87 | return -EINVAL; |
88 | 88 | ||
89 | result = acpi_bus_get_power(device->handle, &acpi_state); | 89 | result = acpi_bus_update_power(device->handle, &acpi_state); |
90 | if (result) | 90 | if (result) |
91 | return result; | 91 | return result; |
92 | 92 | ||
@@ -123,7 +123,6 @@ static struct thermal_cooling_device_ops fan_cooling_ops = { | |||
123 | static int acpi_fan_add(struct acpi_device *device) | 123 | static int acpi_fan_add(struct acpi_device *device) |
124 | { | 124 | { |
125 | int result = 0; | 125 | int result = 0; |
126 | int state = 0; | ||
127 | struct thermal_cooling_device *cdev; | 126 | struct thermal_cooling_device *cdev; |
128 | 127 | ||
129 | if (!device) | 128 | if (!device) |
@@ -132,16 +131,12 @@ static int acpi_fan_add(struct acpi_device *device) | |||
132 | strcpy(acpi_device_name(device), "Fan"); | 131 | strcpy(acpi_device_name(device), "Fan"); |
133 | strcpy(acpi_device_class(device), ACPI_FAN_CLASS); | 132 | strcpy(acpi_device_class(device), ACPI_FAN_CLASS); |
134 | 133 | ||
135 | result = acpi_bus_get_power(device->handle, &state); | 134 | result = acpi_bus_update_power(device->handle, NULL); |
136 | if (result) { | 135 | if (result) { |
137 | printk(KERN_ERR PREFIX "Reading power state\n"); | 136 | printk(KERN_ERR PREFIX "Setting initial power state\n"); |
138 | goto end; | 137 | goto end; |
139 | } | 138 | } |
140 | 139 | ||
141 | device->flags.force_power_state = 1; | ||
142 | acpi_bus_set_power(device->handle, state); | ||
143 | device->flags.force_power_state = 0; | ||
144 | |||
145 | cdev = thermal_cooling_device_register("Fan", device, | 140 | cdev = thermal_cooling_device_register("Fan", device, |
146 | &fan_cooling_ops); | 141 | &fan_cooling_ops); |
147 | if (IS_ERR(cdev)) { | 142 | if (IS_ERR(cdev)) { |
@@ -200,22 +195,14 @@ static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state) | |||
200 | 195 | ||
201 | static int acpi_fan_resume(struct acpi_device *device) | 196 | static int acpi_fan_resume(struct acpi_device *device) |
202 | { | 197 | { |
203 | int result = 0; | 198 | int result; |
204 | int power_state = 0; | ||
205 | 199 | ||
206 | if (!device) | 200 | if (!device) |
207 | return -EINVAL; | 201 | return -EINVAL; |
208 | 202 | ||
209 | result = acpi_bus_get_power(device->handle, &power_state); | 203 | result = acpi_bus_update_power(device->handle, NULL); |
210 | if (result) { | 204 | if (result) |
211 | printk(KERN_ERR PREFIX | 205 | printk(KERN_ERR PREFIX "Error updating fan power state\n"); |
212 | "Error reading fan power state\n"); | ||
213 | return result; | ||
214 | } | ||
215 | |||
216 | device->flags.force_power_state = 1; | ||
217 | acpi_bus_set_power(device->handle, power_state); | ||
218 | device->flags.force_power_state = 0; | ||
219 | 206 | ||
220 | return result; | 207 | return result; |
221 | } | 208 | } |
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 78b0164c35b2..7c47ed55e528 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c | |||
@@ -167,11 +167,8 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) | |||
167 | "firmware_node"); | 167 | "firmware_node"); |
168 | ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, | 168 | ret = sysfs_create_link(&acpi_dev->dev.kobj, &dev->kobj, |
169 | "physical_node"); | 169 | "physical_node"); |
170 | if (acpi_dev->wakeup.flags.valid) { | 170 | if (acpi_dev->wakeup.flags.valid) |
171 | device_set_wakeup_capable(dev, true); | 171 | device_set_wakeup_capable(dev, true); |
172 | device_set_wakeup_enable(dev, | ||
173 | acpi_dev->wakeup.state.enabled); | ||
174 | } | ||
175 | } | 172 | } |
176 | 173 | ||
177 | return 0; | 174 | return 0; |
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index a212bfeddf8c..bc428a9607df 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -41,9 +41,10 @@ static inline int acpi_debugfs_init(void) { return 0; } | |||
41 | int acpi_power_init(void); | 41 | int acpi_power_init(void); |
42 | int acpi_device_sleep_wake(struct acpi_device *dev, | 42 | int acpi_device_sleep_wake(struct acpi_device *dev, |
43 | int enable, int sleep_state, int dev_state); | 43 | int enable, int sleep_state, int dev_state); |
44 | int acpi_power_get_inferred_state(struct acpi_device *device); | 44 | int acpi_power_get_inferred_state(struct acpi_device *device, int *state); |
45 | int acpi_power_on_resources(struct acpi_device *device, int state); | ||
45 | int acpi_power_transition(struct acpi_device *device, int state); | 46 | int acpi_power_transition(struct acpi_device *device, int state); |
46 | extern int acpi_power_nocheck; | 47 | int acpi_bus_init_power(struct acpi_device *device); |
47 | 48 | ||
48 | int acpi_wakeup_device_init(void); | 49 | int acpi_wakeup_device_init(void); |
49 | void acpi_early_processor_set_pdc(void); | 50 | void acpi_early_processor_set_pdc(void); |
@@ -82,8 +83,16 @@ extern int acpi_sleep_init(void); | |||
82 | 83 | ||
83 | #ifdef CONFIG_ACPI_SLEEP | 84 | #ifdef CONFIG_ACPI_SLEEP |
84 | int acpi_sleep_proc_init(void); | 85 | int acpi_sleep_proc_init(void); |
86 | int suspend_nvs_alloc(void); | ||
87 | void suspend_nvs_free(void); | ||
88 | int suspend_nvs_save(void); | ||
89 | void suspend_nvs_restore(void); | ||
85 | #else | 90 | #else |
86 | static inline int acpi_sleep_proc_init(void) { return 0; } | 91 | static inline int acpi_sleep_proc_init(void) { return 0; } |
92 | static inline int suspend_nvs_alloc(void) { return 0; } | ||
93 | static inline void suspend_nvs_free(void) {} | ||
94 | static inline int suspend_nvs_save(void) {} | ||
95 | static inline void suspend_nvs_restore(void) {} | ||
87 | #endif | 96 | #endif |
88 | 97 | ||
89 | #endif /* _ACPI_INTERNAL_H_ */ | 98 | #endif /* _ACPI_INTERNAL_H_ */ |
diff --git a/kernel/power/nvs.c b/drivers/acpi/nvs.c index 1836db60bbb6..54b6ab8040a6 100644 --- a/kernel/power/nvs.c +++ b/drivers/acpi/nvs.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * linux/kernel/power/hibernate_nvs.c - Routines for handling NVS memory | 2 | * nvs.c - Routines for saving and restoring ACPI NVS memory region |
3 | * | 3 | * |
4 | * Copyright (C) 2008,2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. | 4 | * Copyright (C) 2008-2011 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc. |
5 | * | 5 | * |
6 | * This file is released under the GPLv2. | 6 | * This file is released under the GPLv2. |
7 | */ | 7 | */ |
@@ -11,7 +11,8 @@ | |||
11 | #include <linux/list.h> | 11 | #include <linux/list.h> |
12 | #include <linux/mm.h> | 12 | #include <linux/mm.h> |
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/suspend.h> | 14 | #include <linux/acpi.h> |
15 | #include <acpi/acpiosxf.h> | ||
15 | 16 | ||
16 | /* | 17 | /* |
17 | * Platforms, like ACPI, may want us to save some memory used by them during | 18 | * Platforms, like ACPI, may want us to save some memory used by them during |
@@ -79,7 +80,7 @@ void suspend_nvs_free(void) | |||
79 | free_page((unsigned long)entry->data); | 80 | free_page((unsigned long)entry->data); |
80 | entry->data = NULL; | 81 | entry->data = NULL; |
81 | if (entry->kaddr) { | 82 | if (entry->kaddr) { |
82 | iounmap(entry->kaddr); | 83 | acpi_os_unmap_memory(entry->kaddr, entry->size); |
83 | entry->kaddr = NULL; | 84 | entry->kaddr = NULL; |
84 | } | 85 | } |
85 | } | 86 | } |
@@ -105,7 +106,7 @@ int suspend_nvs_alloc(void) | |||
105 | /** | 106 | /** |
106 | * suspend_nvs_save - save NVS memory regions | 107 | * suspend_nvs_save - save NVS memory regions |
107 | */ | 108 | */ |
108 | void suspend_nvs_save(void) | 109 | int suspend_nvs_save(void) |
109 | { | 110 | { |
110 | struct nvs_page *entry; | 111 | struct nvs_page *entry; |
111 | 112 | ||
@@ -113,9 +114,16 @@ void suspend_nvs_save(void) | |||
113 | 114 | ||
114 | list_for_each_entry(entry, &nvs_list, node) | 115 | list_for_each_entry(entry, &nvs_list, node) |
115 | if (entry->data) { | 116 | if (entry->data) { |
116 | entry->kaddr = ioremap(entry->phys_start, entry->size); | 117 | entry->kaddr = acpi_os_map_memory(entry->phys_start, |
118 | entry->size); | ||
119 | if (!entry->kaddr) { | ||
120 | suspend_nvs_free(); | ||
121 | return -ENOMEM; | ||
122 | } | ||
117 | memcpy(entry->data, entry->kaddr, entry->size); | 123 | memcpy(entry->data, entry->kaddr, entry->size); |
118 | } | 124 | } |
125 | |||
126 | return 0; | ||
119 | } | 127 | } |
120 | 128 | ||
121 | /** | 129 | /** |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 966feddf6b1b..3a7b4879fd99 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -110,9 +110,6 @@ struct acpi_ioremap { | |||
110 | static LIST_HEAD(acpi_ioremaps); | 110 | static LIST_HEAD(acpi_ioremaps); |
111 | static DEFINE_SPINLOCK(acpi_ioremap_lock); | 111 | static DEFINE_SPINLOCK(acpi_ioremap_lock); |
112 | 112 | ||
113 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ | ||
114 | static char osi_setup_string[OSI_STRING_LENGTH_MAX]; | ||
115 | |||
116 | static void __init acpi_osi_setup_late(void); | 113 | static void __init acpi_osi_setup_late(void); |
117 | 114 | ||
118 | /* | 115 | /* |
@@ -152,8 +149,7 @@ static struct osi_linux { | |||
152 | unsigned int enable:1; | 149 | unsigned int enable:1; |
153 | unsigned int dmi:1; | 150 | unsigned int dmi:1; |
154 | unsigned int cmdline:1; | 151 | unsigned int cmdline:1; |
155 | unsigned int known:1; | 152 | } osi_linux = {0, 0, 0}; |
156 | } osi_linux = { 0, 0, 0, 0}; | ||
157 | 153 | ||
158 | static u32 acpi_osi_handler(acpi_string interface, u32 supported) | 154 | static u32 acpi_osi_handler(acpi_string interface, u32 supported) |
159 | { | 155 | { |
@@ -324,7 +320,7 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size) | |||
324 | 320 | ||
325 | pg_off = round_down(phys, PAGE_SIZE); | 321 | pg_off = round_down(phys, PAGE_SIZE); |
326 | pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off; | 322 | pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off; |
327 | virt = ioremap(pg_off, pg_sz); | 323 | virt = ioremap_cache(pg_off, pg_sz); |
328 | if (!virt) { | 324 | if (!virt) { |
329 | kfree(map); | 325 | kfree(map); |
330 | return NULL; | 326 | return NULL; |
@@ -646,7 +642,7 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) | |||
646 | virt_addr = acpi_map_vaddr_lookup(phys_addr, size); | 642 | virt_addr = acpi_map_vaddr_lookup(phys_addr, size); |
647 | rcu_read_unlock(); | 643 | rcu_read_unlock(); |
648 | if (!virt_addr) { | 644 | if (!virt_addr) { |
649 | virt_addr = ioremap(phys_addr, size); | 645 | virt_addr = ioremap_cache(phys_addr, size); |
650 | unmap = 1; | 646 | unmap = 1; |
651 | } | 647 | } |
652 | if (!value) | 648 | if (!value) |
@@ -682,7 +678,7 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) | |||
682 | virt_addr = acpi_map_vaddr_lookup(phys_addr, size); | 678 | virt_addr = acpi_map_vaddr_lookup(phys_addr, size); |
683 | rcu_read_unlock(); | 679 | rcu_read_unlock(); |
684 | if (!virt_addr) { | 680 | if (!virt_addr) { |
685 | virt_addr = ioremap(phys_addr, size); | 681 | virt_addr = ioremap_cache(phys_addr, size); |
686 | unmap = 1; | 682 | unmap = 1; |
687 | } | 683 | } |
688 | 684 | ||
@@ -1055,13 +1051,53 @@ static int __init acpi_os_name_setup(char *str) | |||
1055 | 1051 | ||
1056 | __setup("acpi_os_name=", acpi_os_name_setup); | 1052 | __setup("acpi_os_name=", acpi_os_name_setup); |
1057 | 1053 | ||
1054 | #define OSI_STRING_LENGTH_MAX 64 /* arbitrary */ | ||
1055 | #define OSI_STRING_ENTRIES_MAX 16 /* arbitrary */ | ||
1056 | |||
1057 | struct osi_setup_entry { | ||
1058 | char string[OSI_STRING_LENGTH_MAX]; | ||
1059 | bool enable; | ||
1060 | }; | ||
1061 | |||
1062 | static struct osi_setup_entry __initdata osi_setup_entries[OSI_STRING_ENTRIES_MAX]; | ||
1063 | |||
1064 | void __init acpi_osi_setup(char *str) | ||
1065 | { | ||
1066 | struct osi_setup_entry *osi; | ||
1067 | bool enable = true; | ||
1068 | int i; | ||
1069 | |||
1070 | if (!acpi_gbl_create_osi_method) | ||
1071 | return; | ||
1072 | |||
1073 | if (str == NULL || *str == '\0') { | ||
1074 | printk(KERN_INFO PREFIX "_OSI method disabled\n"); | ||
1075 | acpi_gbl_create_osi_method = FALSE; | ||
1076 | return; | ||
1077 | } | ||
1078 | |||
1079 | if (*str == '!') { | ||
1080 | str++; | ||
1081 | enable = false; | ||
1082 | } | ||
1083 | |||
1084 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { | ||
1085 | osi = &osi_setup_entries[i]; | ||
1086 | if (!strcmp(osi->string, str)) { | ||
1087 | osi->enable = enable; | ||
1088 | break; | ||
1089 | } else if (osi->string[0] == '\0') { | ||
1090 | osi->enable = enable; | ||
1091 | strncpy(osi->string, str, OSI_STRING_LENGTH_MAX); | ||
1092 | break; | ||
1093 | } | ||
1094 | } | ||
1095 | } | ||
1096 | |||
1058 | static void __init set_osi_linux(unsigned int enable) | 1097 | static void __init set_osi_linux(unsigned int enable) |
1059 | { | 1098 | { |
1060 | if (osi_linux.enable != enable) { | 1099 | if (osi_linux.enable != enable) |
1061 | osi_linux.enable = enable; | 1100 | osi_linux.enable = enable; |
1062 | printk(KERN_NOTICE PREFIX "%sed _OSI(Linux)\n", | ||
1063 | enable ? "Add": "Delet"); | ||
1064 | } | ||
1065 | 1101 | ||
1066 | if (osi_linux.enable) | 1102 | if (osi_linux.enable) |
1067 | acpi_osi_setup("Linux"); | 1103 | acpi_osi_setup("Linux"); |
@@ -1073,7 +1109,8 @@ static void __init set_osi_linux(unsigned int enable) | |||
1073 | 1109 | ||
1074 | static void __init acpi_cmdline_osi_linux(unsigned int enable) | 1110 | static void __init acpi_cmdline_osi_linux(unsigned int enable) |
1075 | { | 1111 | { |
1076 | osi_linux.cmdline = 1; /* cmdline set the default */ | 1112 | osi_linux.cmdline = 1; /* cmdline set the default and override DMI */ |
1113 | osi_linux.dmi = 0; | ||
1077 | set_osi_linux(enable); | 1114 | set_osi_linux(enable); |
1078 | 1115 | ||
1079 | return; | 1116 | return; |
@@ -1081,15 +1118,12 @@ static void __init acpi_cmdline_osi_linux(unsigned int enable) | |||
1081 | 1118 | ||
1082 | void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) | 1119 | void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) |
1083 | { | 1120 | { |
1084 | osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */ | ||
1085 | |||
1086 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); | 1121 | printk(KERN_NOTICE PREFIX "DMI detected: %s\n", d->ident); |
1087 | 1122 | ||
1088 | if (enable == -1) | 1123 | if (enable == -1) |
1089 | return; | 1124 | return; |
1090 | 1125 | ||
1091 | osi_linux.known = 1; /* DMI knows which OSI(Linux) default needed */ | 1126 | osi_linux.dmi = 1; /* DMI knows that this box asks OSI(Linux) */ |
1092 | |||
1093 | set_osi_linux(enable); | 1127 | set_osi_linux(enable); |
1094 | 1128 | ||
1095 | return; | 1129 | return; |
@@ -1104,37 +1138,44 @@ void __init acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d) | |||
1104 | */ | 1138 | */ |
1105 | static void __init acpi_osi_setup_late(void) | 1139 | static void __init acpi_osi_setup_late(void) |
1106 | { | 1140 | { |
1107 | char *str = osi_setup_string; | 1141 | struct osi_setup_entry *osi; |
1142 | char *str; | ||
1143 | int i; | ||
1144 | acpi_status status; | ||
1108 | 1145 | ||
1109 | if (*str == '\0') | 1146 | for (i = 0; i < OSI_STRING_ENTRIES_MAX; i++) { |
1110 | return; | 1147 | osi = &osi_setup_entries[i]; |
1148 | str = osi->string; | ||
1111 | 1149 | ||
1112 | if (!strcmp("!Linux", str)) { | 1150 | if (*str == '\0') |
1113 | acpi_cmdline_osi_linux(0); /* !enable */ | 1151 | break; |
1114 | } else if (*str == '!') { | 1152 | if (osi->enable) { |
1115 | if (acpi_remove_interface(++str) == AE_OK) | 1153 | status = acpi_install_interface(str); |
1116 | printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); | 1154 | |
1117 | } else if (!strcmp("Linux", str)) { | 1155 | if (ACPI_SUCCESS(status)) |
1118 | acpi_cmdline_osi_linux(1); /* enable */ | 1156 | printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); |
1119 | } else { | 1157 | } else { |
1120 | if (acpi_install_interface(str) == AE_OK) | 1158 | status = acpi_remove_interface(str); |
1121 | printk(KERN_INFO PREFIX "Added _OSI(%s)\n", str); | 1159 | |
1160 | if (ACPI_SUCCESS(status)) | ||
1161 | printk(KERN_INFO PREFIX "Deleted _OSI(%s)\n", str); | ||
1162 | } | ||
1122 | } | 1163 | } |
1123 | } | 1164 | } |
1124 | 1165 | ||
1125 | int __init acpi_osi_setup(char *str) | 1166 | static int __init osi_setup(char *str) |
1126 | { | 1167 | { |
1127 | if (str == NULL || *str == '\0') { | 1168 | if (str && !strcmp("Linux", str)) |
1128 | printk(KERN_INFO PREFIX "_OSI method disabled\n"); | 1169 | acpi_cmdline_osi_linux(1); |
1129 | acpi_gbl_create_osi_method = FALSE; | 1170 | else if (str && !strcmp("!Linux", str)) |
1130 | } else { | 1171 | acpi_cmdline_osi_linux(0); |
1131 | strncpy(osi_setup_string, str, OSI_STRING_LENGTH_MAX); | 1172 | else |
1132 | } | 1173 | acpi_osi_setup(str); |
1133 | 1174 | ||
1134 | return 1; | 1175 | return 1; |
1135 | } | 1176 | } |
1136 | 1177 | ||
1137 | __setup("acpi_osi=", acpi_osi_setup); | 1178 | __setup("acpi_osi=", osi_setup); |
1138 | 1179 | ||
1139 | /* enable serialization to combat AE_ALREADY_EXISTS errors */ | 1180 | /* enable serialization to combat AE_ALREADY_EXISTS errors */ |
1140 | static int __init acpi_serialize_setup(char *str) | 1181 | static int __init acpi_serialize_setup(char *str) |
@@ -1530,7 +1571,7 @@ acpi_status __init acpi_os_initialize(void) | |||
1530 | return AE_OK; | 1571 | return AE_OK; |
1531 | } | 1572 | } |
1532 | 1573 | ||
1533 | acpi_status acpi_os_initialize1(void) | 1574 | acpi_status __init acpi_os_initialize1(void) |
1534 | { | 1575 | { |
1535 | kacpid_wq = create_workqueue("kacpid"); | 1576 | kacpid_wq = create_workqueue("kacpid"); |
1536 | kacpi_notify_wq = create_workqueue("kacpi_notify"); | 1577 | kacpi_notify_wq = create_workqueue("kacpi_notify"); |
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 67dedeed144c..0003f1009885 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -56,9 +56,6 @@ ACPI_MODULE_NAME("power"); | |||
56 | #define ACPI_POWER_RESOURCE_STATE_ON 0x01 | 56 | #define ACPI_POWER_RESOURCE_STATE_ON 0x01 |
57 | #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF | 57 | #define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF |
58 | 58 | ||
59 | int acpi_power_nocheck; | ||
60 | module_param_named(power_nocheck, acpi_power_nocheck, bool, 000); | ||
61 | |||
62 | static int acpi_power_add(struct acpi_device *device); | 59 | static int acpi_power_add(struct acpi_device *device); |
63 | static int acpi_power_remove(struct acpi_device *device, int type); | 60 | static int acpi_power_remove(struct acpi_device *device, int type); |
64 | static int acpi_power_resume(struct acpi_device *device); | 61 | static int acpi_power_resume(struct acpi_device *device); |
@@ -213,11 +210,13 @@ static int acpi_power_on(acpi_handle handle) | |||
213 | resource->name)); | 210 | resource->name)); |
214 | } else { | 211 | } else { |
215 | result = __acpi_power_on(resource); | 212 | result = __acpi_power_on(resource); |
213 | if (result) | ||
214 | resource->ref_count--; | ||
216 | } | 215 | } |
217 | 216 | ||
218 | mutex_unlock(&resource->resource_lock); | 217 | mutex_unlock(&resource->resource_lock); |
219 | 218 | ||
220 | return 0; | 219 | return result; |
221 | } | 220 | } |
222 | 221 | ||
223 | static int acpi_power_off_device(acpi_handle handle) | 222 | static int acpi_power_off_device(acpi_handle handle) |
@@ -264,6 +263,35 @@ static int acpi_power_off_device(acpi_handle handle) | |||
264 | return result; | 263 | return result; |
265 | } | 264 | } |
266 | 265 | ||
266 | static void __acpi_power_off_list(struct acpi_handle_list *list, int num_res) | ||
267 | { | ||
268 | int i; | ||
269 | |||
270 | for (i = num_res - 1; i >= 0 ; i--) | ||
271 | acpi_power_off_device(list->handles[i]); | ||
272 | } | ||
273 | |||
274 | static void acpi_power_off_list(struct acpi_handle_list *list) | ||
275 | { | ||
276 | __acpi_power_off_list(list, list->count); | ||
277 | } | ||
278 | |||
279 | static int acpi_power_on_list(struct acpi_handle_list *list) | ||
280 | { | ||
281 | int result = 0; | ||
282 | int i; | ||
283 | |||
284 | for (i = 0; i < list->count; i++) { | ||
285 | result = acpi_power_on(list->handles[i]); | ||
286 | if (result) { | ||
287 | __acpi_power_off_list(list, i); | ||
288 | break; | ||
289 | } | ||
290 | } | ||
291 | |||
292 | return result; | ||
293 | } | ||
294 | |||
267 | /** | 295 | /** |
268 | * acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in | 296 | * acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in |
269 | * ACPI 3.0) _PSW (Power State Wake) | 297 | * ACPI 3.0) _PSW (Power State Wake) |
@@ -421,19 +449,16 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev) | |||
421 | Device Power Management | 449 | Device Power Management |
422 | -------------------------------------------------------------------------- */ | 450 | -------------------------------------------------------------------------- */ |
423 | 451 | ||
424 | int acpi_power_get_inferred_state(struct acpi_device *device) | 452 | int acpi_power_get_inferred_state(struct acpi_device *device, int *state) |
425 | { | 453 | { |
426 | int result = 0; | 454 | int result = 0; |
427 | struct acpi_handle_list *list = NULL; | 455 | struct acpi_handle_list *list = NULL; |
428 | int list_state = 0; | 456 | int list_state = 0; |
429 | int i = 0; | 457 | int i = 0; |
430 | 458 | ||
431 | 459 | if (!device || !state) | |
432 | if (!device) | ||
433 | return -EINVAL; | 460 | return -EINVAL; |
434 | 461 | ||
435 | device->power.state = ACPI_STATE_UNKNOWN; | ||
436 | |||
437 | /* | 462 | /* |
438 | * We know a device's inferred power state when all the resources | 463 | * We know a device's inferred power state when all the resources |
439 | * required for a given D-state are 'on'. | 464 | * required for a given D-state are 'on'. |
@@ -448,66 +473,51 @@ int acpi_power_get_inferred_state(struct acpi_device *device) | |||
448 | return result; | 473 | return result; |
449 | 474 | ||
450 | if (list_state == ACPI_POWER_RESOURCE_STATE_ON) { | 475 | if (list_state == ACPI_POWER_RESOURCE_STATE_ON) { |
451 | device->power.state = i; | 476 | *state = i; |
452 | return 0; | 477 | return 0; |
453 | } | 478 | } |
454 | } | 479 | } |
455 | 480 | ||
456 | device->power.state = ACPI_STATE_D3; | 481 | *state = ACPI_STATE_D3; |
457 | |||
458 | return 0; | 482 | return 0; |
459 | } | 483 | } |
460 | 484 | ||
461 | int acpi_power_transition(struct acpi_device *device, int state) | 485 | int acpi_power_on_resources(struct acpi_device *device, int state) |
462 | { | 486 | { |
463 | int result = 0; | 487 | if (!device || state < ACPI_STATE_D0 || state > ACPI_STATE_D3) |
464 | struct acpi_handle_list *cl = NULL; /* Current Resources */ | 488 | return -EINVAL; |
465 | struct acpi_handle_list *tl = NULL; /* Target Resources */ | ||
466 | int i = 0; | ||
467 | 489 | ||
490 | return acpi_power_on_list(&device->power.states[state].resources); | ||
491 | } | ||
492 | |||
493 | int acpi_power_transition(struct acpi_device *device, int state) | ||
494 | { | ||
495 | int result; | ||
468 | 496 | ||
469 | if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) | 497 | if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) |
470 | return -EINVAL; | 498 | return -EINVAL; |
471 | 499 | ||
500 | if (device->power.state == state) | ||
501 | return 0; | ||
502 | |||
472 | if ((device->power.state < ACPI_STATE_D0) | 503 | if ((device->power.state < ACPI_STATE_D0) |
473 | || (device->power.state > ACPI_STATE_D3)) | 504 | || (device->power.state > ACPI_STATE_D3)) |
474 | return -ENODEV; | 505 | return -ENODEV; |
475 | 506 | ||
476 | cl = &device->power.states[device->power.state].resources; | ||
477 | tl = &device->power.states[state].resources; | ||
478 | |||
479 | /* TBD: Resources must be ordered. */ | 507 | /* TBD: Resources must be ordered. */ |
480 | 508 | ||
481 | /* | 509 | /* |
482 | * First we reference all power resources required in the target list | 510 | * First we reference all power resources required in the target list |
483 | * (e.g. so the device doesn't lose power while transitioning). | 511 | * (e.g. so the device doesn't lose power while transitioning). Then, |
512 | * we dereference all power resources used in the current list. | ||
484 | */ | 513 | */ |
485 | for (i = 0; i < tl->count; i++) { | 514 | result = acpi_power_on_list(&device->power.states[state].resources); |
486 | result = acpi_power_on(tl->handles[i]); | 515 | if (!result) |
487 | if (result) | 516 | acpi_power_off_list( |
488 | goto end; | 517 | &device->power.states[device->power.state].resources); |
489 | } | ||
490 | |||
491 | if (device->power.state == state) { | ||
492 | goto end; | ||
493 | } | ||
494 | |||
495 | /* | ||
496 | * Then we dereference all power resources used in the current list. | ||
497 | */ | ||
498 | for (i = 0; i < cl->count; i++) { | ||
499 | result = acpi_power_off_device(cl->handles[i]); | ||
500 | if (result) | ||
501 | goto end; | ||
502 | } | ||
503 | 518 | ||
504 | end: | 519 | /* We shouldn't change the state unless the above operations succeed. */ |
505 | if (result) | 520 | device->power.state = result ? ACPI_STATE_UNKNOWN : state; |
506 | device->power.state = ACPI_STATE_UNKNOWN; | ||
507 | else { | ||
508 | /* We shouldn't change the state till all above operations succeed */ | ||
509 | device->power.state = state; | ||
510 | } | ||
511 | 521 | ||
512 | return result; | 522 | return result; |
513 | } | 523 | } |
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index afad67769db6..f5f986991b52 100644 --- a/drivers/acpi/proc.c +++ b/drivers/acpi/proc.c | |||
@@ -311,7 +311,9 @@ acpi_system_wakeup_device_seq_show(struct seq_file *seq, void *offset) | |||
311 | dev->pnp.bus_id, | 311 | dev->pnp.bus_id, |
312 | (u32) dev->wakeup.sleep_state, | 312 | (u32) dev->wakeup.sleep_state, |
313 | dev->wakeup.flags.run_wake ? '*' : ' ', | 313 | dev->wakeup.flags.run_wake ? '*' : ' ', |
314 | dev->wakeup.state.enabled ? "enabled" : "disabled"); | 314 | (device_may_wakeup(&dev->dev) |
315 | || (ldev && device_may_wakeup(ldev))) ? | ||
316 | "enabled" : "disabled"); | ||
315 | if (ldev) | 317 | if (ldev) |
316 | seq_printf(seq, "%s:%s", | 318 | seq_printf(seq, "%s:%s", |
317 | ldev->bus ? ldev->bus->name : "no-bus", | 319 | ldev->bus ? ldev->bus->name : "no-bus", |
@@ -328,8 +330,10 @@ static void physical_device_enable_wakeup(struct acpi_device *adev) | |||
328 | { | 330 | { |
329 | struct device *dev = acpi_get_physical_device(adev->handle); | 331 | struct device *dev = acpi_get_physical_device(adev->handle); |
330 | 332 | ||
331 | if (dev && device_can_wakeup(dev)) | 333 | if (dev && device_can_wakeup(dev)) { |
332 | device_set_wakeup_enable(dev, adev->wakeup.state.enabled); | 334 | bool enable = !device_may_wakeup(dev); |
335 | device_set_wakeup_enable(dev, enable); | ||
336 | } | ||
333 | } | 337 | } |
334 | 338 | ||
335 | static ssize_t | 339 | static ssize_t |
@@ -341,7 +345,6 @@ acpi_system_write_wakeup_device(struct file *file, | |||
341 | char strbuf[5]; | 345 | char strbuf[5]; |
342 | char str[5] = ""; | 346 | char str[5] = ""; |
343 | unsigned int len = count; | 347 | unsigned int len = count; |
344 | struct acpi_device *found_dev = NULL; | ||
345 | 348 | ||
346 | if (len > 4) | 349 | if (len > 4) |
347 | len = 4; | 350 | len = 4; |
@@ -361,33 +364,13 @@ acpi_system_write_wakeup_device(struct file *file, | |||
361 | continue; | 364 | continue; |
362 | 365 | ||
363 | if (!strncmp(dev->pnp.bus_id, str, 4)) { | 366 | if (!strncmp(dev->pnp.bus_id, str, 4)) { |
364 | dev->wakeup.state.enabled = | 367 | if (device_can_wakeup(&dev->dev)) { |
365 | dev->wakeup.state.enabled ? 0 : 1; | 368 | bool enable = !device_may_wakeup(&dev->dev); |
366 | found_dev = dev; | 369 | device_set_wakeup_enable(&dev->dev, enable); |
367 | break; | 370 | } else { |
368 | } | ||
369 | } | ||
370 | if (found_dev) { | ||
371 | physical_device_enable_wakeup(found_dev); | ||
372 | list_for_each_safe(node, next, &acpi_wakeup_device_list) { | ||
373 | struct acpi_device *dev = container_of(node, | ||
374 | struct | ||
375 | acpi_device, | ||
376 | wakeup_list); | ||
377 | |||
378 | if ((dev != found_dev) && | ||
379 | (dev->wakeup.gpe_number == | ||
380 | found_dev->wakeup.gpe_number) | ||
381 | && (dev->wakeup.gpe_device == | ||
382 | found_dev->wakeup.gpe_device)) { | ||
383 | printk(KERN_WARNING | ||
384 | "ACPI: '%s' and '%s' have the same GPE, " | ||
385 | "can't disable/enable one separately\n", | ||
386 | dev->pnp.bus_id, found_dev->pnp.bus_id); | ||
387 | dev->wakeup.state.enabled = | ||
388 | found_dev->wakeup.state.enabled; | ||
389 | physical_device_enable_wakeup(dev); | 371 | physical_device_enable_wakeup(dev); |
390 | } | 372 | } |
373 | break; | ||
391 | } | 374 | } |
392 | } | 375 | } |
393 | mutex_unlock(&acpi_device_lock); | 376 | mutex_unlock(&acpi_device_lock); |
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index fde49b9b1d99..79cb65332894 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c | |||
@@ -156,15 +156,6 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state) | |||
156 | return 0; | 156 | return 0; |
157 | } | 157 | } |
158 | 158 | ||
159 | static int acpi_thermal_cpufreq_increase(unsigned int cpu) | ||
160 | { | ||
161 | return -ENODEV; | ||
162 | } | ||
163 | static int acpi_thermal_cpufreq_decrease(unsigned int cpu) | ||
164 | { | ||
165 | return -ENODEV; | ||
166 | } | ||
167 | |||
168 | #endif | 159 | #endif |
169 | 160 | ||
170 | int acpi_processor_get_limit_info(struct acpi_processor *pr) | 161 | int acpi_processor_get_limit_info(struct acpi_processor *pr) |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 2b6c21d86b98..64d4da0d6d52 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -705,54 +705,85 @@ static int acpi_bus_get_perf_flags(struct acpi_device *device) | |||
705 | } | 705 | } |
706 | 706 | ||
707 | static acpi_status | 707 | static acpi_status |
708 | acpi_bus_extract_wakeup_device_power_package(struct acpi_device *device, | 708 | acpi_bus_extract_wakeup_device_power_package(acpi_handle handle, |
709 | union acpi_object *package) | 709 | struct acpi_device_wakeup *wakeup) |
710 | { | 710 | { |
711 | int i = 0; | 711 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
712 | union acpi_object *package = NULL; | ||
712 | union acpi_object *element = NULL; | 713 | union acpi_object *element = NULL; |
714 | acpi_status status; | ||
715 | int i = 0; | ||
713 | 716 | ||
714 | if (!device || !package || (package->package.count < 2)) | 717 | if (!wakeup) |
715 | return AE_BAD_PARAMETER; | 718 | return AE_BAD_PARAMETER; |
716 | 719 | ||
720 | /* _PRW */ | ||
721 | status = acpi_evaluate_object(handle, "_PRW", NULL, &buffer); | ||
722 | if (ACPI_FAILURE(status)) { | ||
723 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW")); | ||
724 | return status; | ||
725 | } | ||
726 | |||
727 | package = (union acpi_object *)buffer.pointer; | ||
728 | |||
729 | if (!package || (package->package.count < 2)) { | ||
730 | status = AE_BAD_DATA; | ||
731 | goto out; | ||
732 | } | ||
733 | |||
717 | element = &(package->package.elements[0]); | 734 | element = &(package->package.elements[0]); |
718 | if (!element) | 735 | if (!element) { |
719 | return AE_BAD_PARAMETER; | 736 | status = AE_BAD_DATA; |
737 | goto out; | ||
738 | } | ||
720 | if (element->type == ACPI_TYPE_PACKAGE) { | 739 | if (element->type == ACPI_TYPE_PACKAGE) { |
721 | if ((element->package.count < 2) || | 740 | if ((element->package.count < 2) || |
722 | (element->package.elements[0].type != | 741 | (element->package.elements[0].type != |
723 | ACPI_TYPE_LOCAL_REFERENCE) | 742 | ACPI_TYPE_LOCAL_REFERENCE) |
724 | || (element->package.elements[1].type != ACPI_TYPE_INTEGER)) | 743 | || (element->package.elements[1].type != ACPI_TYPE_INTEGER)) { |
725 | return AE_BAD_DATA; | 744 | status = AE_BAD_DATA; |
726 | device->wakeup.gpe_device = | 745 | goto out; |
746 | } | ||
747 | wakeup->gpe_device = | ||
727 | element->package.elements[0].reference.handle; | 748 | element->package.elements[0].reference.handle; |
728 | device->wakeup.gpe_number = | 749 | wakeup->gpe_number = |
729 | (u32) element->package.elements[1].integer.value; | 750 | (u32) element->package.elements[1].integer.value; |
730 | } else if (element->type == ACPI_TYPE_INTEGER) { | 751 | } else if (element->type == ACPI_TYPE_INTEGER) { |
731 | device->wakeup.gpe_number = element->integer.value; | 752 | wakeup->gpe_device = NULL; |
732 | } else | 753 | wakeup->gpe_number = element->integer.value; |
733 | return AE_BAD_DATA; | 754 | } else { |
755 | status = AE_BAD_DATA; | ||
756 | goto out; | ||
757 | } | ||
734 | 758 | ||
735 | element = &(package->package.elements[1]); | 759 | element = &(package->package.elements[1]); |
736 | if (element->type != ACPI_TYPE_INTEGER) { | 760 | if (element->type != ACPI_TYPE_INTEGER) { |
737 | return AE_BAD_DATA; | 761 | status = AE_BAD_DATA; |
762 | goto out; | ||
738 | } | 763 | } |
739 | device->wakeup.sleep_state = element->integer.value; | 764 | wakeup->sleep_state = element->integer.value; |
740 | 765 | ||
741 | if ((package->package.count - 2) > ACPI_MAX_HANDLES) { | 766 | if ((package->package.count - 2) > ACPI_MAX_HANDLES) { |
742 | return AE_NO_MEMORY; | 767 | status = AE_NO_MEMORY; |
768 | goto out; | ||
743 | } | 769 | } |
744 | device->wakeup.resources.count = package->package.count - 2; | 770 | wakeup->resources.count = package->package.count - 2; |
745 | for (i = 0; i < device->wakeup.resources.count; i++) { | 771 | for (i = 0; i < wakeup->resources.count; i++) { |
746 | element = &(package->package.elements[i + 2]); | 772 | element = &(package->package.elements[i + 2]); |
747 | if (element->type != ACPI_TYPE_LOCAL_REFERENCE) | 773 | if (element->type != ACPI_TYPE_LOCAL_REFERENCE) { |
748 | return AE_BAD_DATA; | 774 | status = AE_BAD_DATA; |
775 | goto out; | ||
776 | } | ||
749 | 777 | ||
750 | device->wakeup.resources.handles[i] = element->reference.handle; | 778 | wakeup->resources.handles[i] = element->reference.handle; |
751 | } | 779 | } |
752 | 780 | ||
753 | acpi_gpe_can_wake(device->wakeup.gpe_device, device->wakeup.gpe_number); | 781 | acpi_setup_gpe_for_wake(handle, wakeup->gpe_device, wakeup->gpe_number); |
754 | 782 | ||
755 | return AE_OK; | 783 | out: |
784 | kfree(buffer.pointer); | ||
785 | |||
786 | return status; | ||
756 | } | 787 | } |
757 | 788 | ||
758 | static void acpi_bus_set_run_wake_flags(struct acpi_device *device) | 789 | static void acpi_bus_set_run_wake_flags(struct acpi_device *device) |
@@ -772,7 +803,7 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device) | |||
772 | /* Power button, Lid switch always enable wakeup */ | 803 | /* Power button, Lid switch always enable wakeup */ |
773 | if (!acpi_match_device_ids(device, button_device_ids)) { | 804 | if (!acpi_match_device_ids(device, button_device_ids)) { |
774 | device->wakeup.flags.run_wake = 1; | 805 | device->wakeup.flags.run_wake = 1; |
775 | device->wakeup.flags.always_enabled = 1; | 806 | device_set_wakeup_capable(&device->dev, true); |
776 | return; | 807 | return; |
777 | } | 808 | } |
778 | 809 | ||
@@ -787,26 +818,15 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device) | |||
787 | static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) | 818 | static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) |
788 | { | 819 | { |
789 | acpi_status status = 0; | 820 | acpi_status status = 0; |
790 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
791 | union acpi_object *package = NULL; | ||
792 | int psw_error; | 821 | int psw_error; |
793 | 822 | ||
794 | /* _PRW */ | 823 | status = acpi_bus_extract_wakeup_device_power_package(device->handle, |
795 | status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer); | 824 | &device->wakeup); |
796 | if (ACPI_FAILURE(status)) { | ||
797 | ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PRW")); | ||
798 | goto end; | ||
799 | } | ||
800 | |||
801 | package = (union acpi_object *)buffer.pointer; | ||
802 | status = acpi_bus_extract_wakeup_device_power_package(device, package); | ||
803 | if (ACPI_FAILURE(status)) { | 825 | if (ACPI_FAILURE(status)) { |
804 | ACPI_EXCEPTION((AE_INFO, status, "Extracting _PRW package")); | 826 | ACPI_EXCEPTION((AE_INFO, status, "Extracting _PRW package")); |
805 | goto end; | 827 | goto end; |
806 | } | 828 | } |
807 | 829 | ||
808 | kfree(buffer.pointer); | ||
809 | |||
810 | device->wakeup.flags.valid = 1; | 830 | device->wakeup.flags.valid = 1; |
811 | device->wakeup.prepare_count = 0; | 831 | device->wakeup.prepare_count = 0; |
812 | acpi_bus_set_run_wake_flags(device); | 832 | acpi_bus_set_run_wake_flags(device); |
@@ -827,6 +847,8 @@ end: | |||
827 | return 0; | 847 | return 0; |
828 | } | 848 | } |
829 | 849 | ||
850 | static void acpi_bus_add_power_resource(acpi_handle handle); | ||
851 | |||
830 | static int acpi_bus_get_power_flags(struct acpi_device *device) | 852 | static int acpi_bus_get_power_flags(struct acpi_device *device) |
831 | { | 853 | { |
832 | acpi_status status = 0; | 854 | acpi_status status = 0; |
@@ -855,8 +877,12 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) | |||
855 | acpi_evaluate_reference(device->handle, object_name, NULL, | 877 | acpi_evaluate_reference(device->handle, object_name, NULL, |
856 | &ps->resources); | 878 | &ps->resources); |
857 | if (ps->resources.count) { | 879 | if (ps->resources.count) { |
880 | int j; | ||
881 | |||
858 | device->power.flags.power_resources = 1; | 882 | device->power.flags.power_resources = 1; |
859 | ps->flags.valid = 1; | 883 | ps->flags.valid = 1; |
884 | for (j = 0; j < ps->resources.count; j++) | ||
885 | acpi_bus_add_power_resource(ps->resources.handles[j]); | ||
860 | } | 886 | } |
861 | 887 | ||
862 | /* Evaluate "_PSx" to see if we can do explicit sets */ | 888 | /* Evaluate "_PSx" to see if we can do explicit sets */ |
@@ -881,10 +907,7 @@ static int acpi_bus_get_power_flags(struct acpi_device *device) | |||
881 | device->power.states[ACPI_STATE_D3].flags.valid = 1; | 907 | device->power.states[ACPI_STATE_D3].flags.valid = 1; |
882 | device->power.states[ACPI_STATE_D3].power = 0; | 908 | device->power.states[ACPI_STATE_D3].power = 0; |
883 | 909 | ||
884 | /* TBD: System wake support and resource requirements. */ | 910 | acpi_bus_init_power(device); |
885 | |||
886 | device->power.state = ACPI_STATE_UNKNOWN; | ||
887 | acpi_bus_get_power(device->handle, &(device->power.state)); | ||
888 | 911 | ||
889 | return 0; | 912 | return 0; |
890 | } | 913 | } |
@@ -1306,6 +1329,20 @@ end: | |||
1306 | #define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \ | 1329 | #define ACPI_STA_DEFAULT (ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED | \ |
1307 | ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING) | 1330 | ACPI_STA_DEVICE_UI | ACPI_STA_DEVICE_FUNCTIONING) |
1308 | 1331 | ||
1332 | static void acpi_bus_add_power_resource(acpi_handle handle) | ||
1333 | { | ||
1334 | struct acpi_bus_ops ops = { | ||
1335 | .acpi_op_add = 1, | ||
1336 | .acpi_op_start = 1, | ||
1337 | }; | ||
1338 | struct acpi_device *device = NULL; | ||
1339 | |||
1340 | acpi_bus_get_device(handle, &device); | ||
1341 | if (!device) | ||
1342 | acpi_add_single_object(&device, handle, ACPI_BUS_TYPE_POWER, | ||
1343 | ACPI_STA_DEFAULT, &ops); | ||
1344 | } | ||
1345 | |||
1309 | static int acpi_bus_type_and_status(acpi_handle handle, int *type, | 1346 | static int acpi_bus_type_and_status(acpi_handle handle, int *type, |
1310 | unsigned long long *sta) | 1347 | unsigned long long *sta) |
1311 | { | 1348 | { |
@@ -1351,6 +1388,7 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl, | |||
1351 | struct acpi_bus_ops *ops = context; | 1388 | struct acpi_bus_ops *ops = context; |
1352 | int type; | 1389 | int type; |
1353 | unsigned long long sta; | 1390 | unsigned long long sta; |
1391 | struct acpi_device_wakeup wakeup; | ||
1354 | struct acpi_device *device; | 1392 | struct acpi_device *device; |
1355 | acpi_status status; | 1393 | acpi_status status; |
1356 | int result; | 1394 | int result; |
@@ -1360,8 +1398,10 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl, | |||
1360 | return AE_OK; | 1398 | return AE_OK; |
1361 | 1399 | ||
1362 | if (!(sta & ACPI_STA_DEVICE_PRESENT) && | 1400 | if (!(sta & ACPI_STA_DEVICE_PRESENT) && |
1363 | !(sta & ACPI_STA_DEVICE_FUNCTIONING)) | 1401 | !(sta & ACPI_STA_DEVICE_FUNCTIONING)) { |
1402 | acpi_bus_extract_wakeup_device_power_package(handle, &wakeup); | ||
1364 | return AE_CTRL_DEPTH; | 1403 | return AE_CTRL_DEPTH; |
1404 | } | ||
1365 | 1405 | ||
1366 | /* | 1406 | /* |
1367 | * We may already have an acpi_device from a previous enumeration. If | 1407 | * We may already have an acpi_device from a previous enumeration. If |
@@ -1444,7 +1484,7 @@ int acpi_bus_start(struct acpi_device *device) | |||
1444 | 1484 | ||
1445 | result = acpi_bus_scan(device->handle, &ops, NULL); | 1485 | result = acpi_bus_scan(device->handle, &ops, NULL); |
1446 | 1486 | ||
1447 | acpi_update_gpes(); | 1487 | acpi_update_all_gpes(); |
1448 | 1488 | ||
1449 | return result; | 1489 | return result; |
1450 | } | 1490 | } |
@@ -1550,6 +1590,8 @@ int __init acpi_scan_init(void) | |||
1550 | printk(KERN_ERR PREFIX "Could not register bus type\n"); | 1590 | printk(KERN_ERR PREFIX "Could not register bus type\n"); |
1551 | } | 1591 | } |
1552 | 1592 | ||
1593 | acpi_power_init(); | ||
1594 | |||
1553 | /* | 1595 | /* |
1554 | * Enumerate devices in the ACPI namespace. | 1596 | * Enumerate devices in the ACPI namespace. |
1555 | */ | 1597 | */ |
@@ -1561,7 +1603,7 @@ int __init acpi_scan_init(void) | |||
1561 | if (result) | 1603 | if (result) |
1562 | acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); | 1604 | acpi_device_unregister(acpi_root, ACPI_BUS_REMOVAL_NORMAL); |
1563 | else | 1605 | else |
1564 | acpi_update_gpes(); | 1606 | acpi_update_all_gpes(); |
1565 | 1607 | ||
1566 | return result; | 1608 | return result; |
1567 | } | 1609 | } |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 721d93b3ceee..75c232084740 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -27,8 +27,6 @@ | |||
27 | 27 | ||
28 | static u8 sleep_states[ACPI_S_STATE_COUNT]; | 28 | static u8 sleep_states[ACPI_S_STATE_COUNT]; |
29 | 29 | ||
30 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | ||
31 | |||
32 | static void acpi_sleep_tts_switch(u32 acpi_state) | 30 | static void acpi_sleep_tts_switch(u32 acpi_state) |
33 | { | 31 | { |
34 | union acpi_object in_arg = { ACPI_TYPE_INTEGER }; | 32 | union acpi_object in_arg = { ACPI_TYPE_INTEGER }; |
@@ -81,6 +79,8 @@ static int acpi_sleep_prepare(u32 acpi_state) | |||
81 | } | 79 | } |
82 | 80 | ||
83 | #ifdef CONFIG_ACPI_SLEEP | 81 | #ifdef CONFIG_ACPI_SLEEP |
82 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | ||
83 | |||
84 | /* | 84 | /* |
85 | * The ACPI specification wants us to save NVS memory regions during hibernation | 85 | * The ACPI specification wants us to save NVS memory regions during hibernation |
86 | * and to restore them during the subsequent resume. Windows does that also for | 86 | * and to restore them during the subsequent resume. Windows does that also for |
@@ -124,8 +124,7 @@ static int acpi_pm_freeze(void) | |||
124 | static int acpi_pm_pre_suspend(void) | 124 | static int acpi_pm_pre_suspend(void) |
125 | { | 125 | { |
126 | acpi_pm_freeze(); | 126 | acpi_pm_freeze(); |
127 | suspend_nvs_save(); | 127 | return suspend_nvs_save(); |
128 | return 0; | ||
129 | } | 128 | } |
130 | 129 | ||
131 | /** | 130 | /** |
@@ -151,7 +150,7 @@ static int acpi_pm_prepare(void) | |||
151 | { | 150 | { |
152 | int error = __acpi_pm_prepare(); | 151 | int error = __acpi_pm_prepare(); |
153 | if (!error) | 152 | if (!error) |
154 | acpi_pm_pre_suspend(); | 153 | error = acpi_pm_pre_suspend(); |
155 | 154 | ||
156 | return error; | 155 | return error; |
157 | } | 156 | } |
@@ -427,6 +426,22 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
427 | DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"), | 426 | DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1Z1E"), |
428 | }, | 427 | }, |
429 | }, | 428 | }, |
429 | { | ||
430 | .callback = init_nvs_nosave, | ||
431 | .ident = "Sony Vaio VGN-NW130D", | ||
432 | .matches = { | ||
433 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
434 | DMI_MATCH(DMI_PRODUCT_NAME, "VGN-NW130D"), | ||
435 | }, | ||
436 | }, | ||
437 | { | ||
438 | .callback = init_nvs_nosave, | ||
439 | .ident = "Averatec AV1020-ED2", | ||
440 | .matches = { | ||
441 | DMI_MATCH(DMI_SYS_VENDOR, "AVERATEC"), | ||
442 | DMI_MATCH(DMI_PRODUCT_NAME, "1000 Series"), | ||
443 | }, | ||
444 | }, | ||
430 | {}, | 445 | {}, |
431 | }; | 446 | }; |
432 | #endif /* CONFIG_SUSPEND */ | 447 | #endif /* CONFIG_SUSPEND */ |
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index f8588f81048a..61891e75583d 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c | |||
@@ -438,7 +438,7 @@ static void delete_gpe_attr_array(void) | |||
438 | return; | 438 | return; |
439 | } | 439 | } |
440 | 440 | ||
441 | void acpi_os_gpe_count(u32 gpe_number) | 441 | static void gpe_count(u32 gpe_number) |
442 | { | 442 | { |
443 | acpi_gpe_count++; | 443 | acpi_gpe_count++; |
444 | 444 | ||
@@ -454,7 +454,7 @@ void acpi_os_gpe_count(u32 gpe_number) | |||
454 | return; | 454 | return; |
455 | } | 455 | } |
456 | 456 | ||
457 | void acpi_os_fixed_event_count(u32 event_number) | 457 | static void fixed_event_count(u32 event_number) |
458 | { | 458 | { |
459 | if (!all_counters) | 459 | if (!all_counters) |
460 | return; | 460 | return; |
@@ -468,6 +468,16 @@ void acpi_os_fixed_event_count(u32 event_number) | |||
468 | return; | 468 | return; |
469 | } | 469 | } |
470 | 470 | ||
471 | static void acpi_gbl_event_handler(u32 event_type, acpi_handle device, | ||
472 | u32 event_number, void *context) | ||
473 | { | ||
474 | if (event_type == ACPI_EVENT_TYPE_GPE) | ||
475 | gpe_count(event_number); | ||
476 | |||
477 | if (event_type == ACPI_EVENT_TYPE_FIXED) | ||
478 | fixed_event_count(event_number); | ||
479 | } | ||
480 | |||
471 | static int get_status(u32 index, acpi_event_status *status, | 481 | static int get_status(u32 index, acpi_event_status *status, |
472 | acpi_handle *handle) | 482 | acpi_handle *handle) |
473 | { | 483 | { |
@@ -601,6 +611,7 @@ end: | |||
601 | 611 | ||
602 | void acpi_irq_stats_init(void) | 612 | void acpi_irq_stats_init(void) |
603 | { | 613 | { |
614 | acpi_status status; | ||
604 | int i; | 615 | int i; |
605 | 616 | ||
606 | if (all_counters) | 617 | if (all_counters) |
@@ -619,6 +630,10 @@ void acpi_irq_stats_init(void) | |||
619 | if (all_counters == NULL) | 630 | if (all_counters == NULL) |
620 | goto fail; | 631 | goto fail; |
621 | 632 | ||
633 | status = acpi_install_global_event_handler(acpi_gbl_event_handler, NULL); | ||
634 | if (ACPI_FAILURE(status)) | ||
635 | goto fail; | ||
636 | |||
622 | counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters), | 637 | counter_attrs = kzalloc(sizeof(struct kobj_attribute) * (num_counters), |
623 | GFP_KERNEL); | 638 | GFP_KERNEL); |
624 | if (counter_attrs == NULL) | 639 | if (counter_attrs == NULL) |
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 5a27b0a31315..2607e17b520f 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -1059,8 +1059,9 @@ static int acpi_thermal_resume(struct acpi_device *device) | |||
1059 | break; | 1059 | break; |
1060 | tz->trips.active[i].flags.enabled = 1; | 1060 | tz->trips.active[i].flags.enabled = 1; |
1061 | for (j = 0; j < tz->trips.active[i].devices.count; j++) { | 1061 | for (j = 0; j < tz->trips.active[i].devices.count; j++) { |
1062 | result = acpi_bus_get_power(tz->trips.active[i].devices. | 1062 | result = acpi_bus_update_power( |
1063 | handles[j], &power_state); | 1063 | tz->trips.active[i].devices.handles[j], |
1064 | &power_state); | ||
1064 | if (result || (power_state != ACPI_STATE_D0)) { | 1065 | if (result || (power_state != ACPI_STATE_D0)) { |
1065 | tz->trips.active[i].flags.enabled = 0; | 1066 | tz->trips.active[i].flags.enabled = 0; |
1066 | break; | 1067 | break; |
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c index f62a50c3ed34..ed6501452507 100644 --- a/drivers/acpi/wakeup.c +++ b/drivers/acpi/wakeup.c | |||
@@ -37,15 +37,16 @@ void acpi_enable_wakeup_devices(u8 sleep_state) | |||
37 | container_of(node, struct acpi_device, wakeup_list); | 37 | container_of(node, struct acpi_device, wakeup_list); |
38 | 38 | ||
39 | if (!dev->wakeup.flags.valid | 39 | if (!dev->wakeup.flags.valid |
40 | || !(dev->wakeup.state.enabled || dev->wakeup.prepare_count) | 40 | || sleep_state > (u32) dev->wakeup.sleep_state |
41 | || sleep_state > (u32) dev->wakeup.sleep_state) | 41 | || !(device_may_wakeup(&dev->dev) |
42 | || dev->wakeup.prepare_count)) | ||
42 | continue; | 43 | continue; |
43 | 44 | ||
44 | if (dev->wakeup.state.enabled) | 45 | if (device_may_wakeup(&dev->dev)) |
45 | acpi_enable_wakeup_device_power(dev, sleep_state); | 46 | acpi_enable_wakeup_device_power(dev, sleep_state); |
46 | 47 | ||
47 | /* The wake-up power should have been enabled already. */ | 48 | /* The wake-up power should have been enabled already. */ |
48 | acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number, | 49 | acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number, |
49 | ACPI_GPE_ENABLE); | 50 | ACPI_GPE_ENABLE); |
50 | } | 51 | } |
51 | } | 52 | } |
@@ -63,14 +64,15 @@ void acpi_disable_wakeup_devices(u8 sleep_state) | |||
63 | container_of(node, struct acpi_device, wakeup_list); | 64 | container_of(node, struct acpi_device, wakeup_list); |
64 | 65 | ||
65 | if (!dev->wakeup.flags.valid | 66 | if (!dev->wakeup.flags.valid |
66 | || !(dev->wakeup.state.enabled || dev->wakeup.prepare_count) | 67 | || sleep_state > (u32) dev->wakeup.sleep_state |
67 | || (sleep_state > (u32) dev->wakeup.sleep_state)) | 68 | || !(device_may_wakeup(&dev->dev) |
69 | || dev->wakeup.prepare_count)) | ||
68 | continue; | 70 | continue; |
69 | 71 | ||
70 | acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number, | 72 | acpi_set_gpe_wake_mask(dev->wakeup.gpe_device, dev->wakeup.gpe_number, |
71 | ACPI_GPE_DISABLE); | 73 | ACPI_GPE_DISABLE); |
72 | 74 | ||
73 | if (dev->wakeup.state.enabled) | 75 | if (device_may_wakeup(&dev->dev)) |
74 | acpi_disable_wakeup_device_power(dev); | 76 | acpi_disable_wakeup_device_power(dev); |
75 | } | 77 | } |
76 | } | 78 | } |
@@ -84,8 +86,8 @@ int __init acpi_wakeup_device_init(void) | |||
84 | struct acpi_device *dev = container_of(node, | 86 | struct acpi_device *dev = container_of(node, |
85 | struct acpi_device, | 87 | struct acpi_device, |
86 | wakeup_list); | 88 | wakeup_list); |
87 | if (dev->wakeup.flags.always_enabled) | 89 | if (device_can_wakeup(&dev->dev)) |
88 | dev->wakeup.state.enabled = 1; | 90 | device_set_wakeup_enable(&dev->dev, true); |
89 | } | 91 | } |
90 | mutex_unlock(&acpi_device_lock); | 92 | mutex_unlock(&acpi_device_lock); |
91 | return 0; | 93 | return 0; |
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 11ec911016c6..36e2319264bd 100644 --- a/drivers/ata/Kconfig +++ b/drivers/ata/Kconfig | |||
@@ -128,16 +128,6 @@ config PDC_ADMA | |||
128 | 128 | ||
129 | If unsure, say N. | 129 | If unsure, say N. |
130 | 130 | ||
131 | config PATA_MPC52xx | ||
132 | tristate "Freescale MPC52xx SoC internal IDE" | ||
133 | depends on PPC_MPC52xx && PPC_BESTCOMM | ||
134 | select PPC_BESTCOMM_ATA | ||
135 | help | ||
136 | This option enables support for integrated IDE controller | ||
137 | of the Freescale MPC52xx SoC. | ||
138 | |||
139 | If unsure, say N. | ||
140 | |||
141 | config PATA_OCTEON_CF | 131 | config PATA_OCTEON_CF |
142 | tristate "OCTEON Boot Bus Compact Flash support" | 132 | tristate "OCTEON Boot Bus Compact Flash support" |
143 | depends on CPU_CAVIUM_OCTEON | 133 | depends on CPU_CAVIUM_OCTEON |
@@ -366,7 +356,7 @@ config PATA_CS5535 | |||
366 | 356 | ||
367 | config PATA_CS5536 | 357 | config PATA_CS5536 |
368 | tristate "CS5536 PATA support" | 358 | tristate "CS5536 PATA support" |
369 | depends on PCI && X86 && !X86_64 | 359 | depends on PCI |
370 | help | 360 | help |
371 | This option enables support for the AMD CS5536 | 361 | This option enables support for the AMD CS5536 |
372 | companion chip used with the Geode LX processor family. | 362 | companion chip used with the Geode LX processor family. |
@@ -491,6 +481,16 @@ config PATA_MARVELL | |||
491 | 481 | ||
492 | If unsure, say N. | 482 | If unsure, say N. |
493 | 483 | ||
484 | config PATA_MPC52xx | ||
485 | tristate "Freescale MPC52xx SoC internal IDE" | ||
486 | depends on PPC_MPC52xx && PPC_BESTCOMM | ||
487 | select PPC_BESTCOMM_ATA | ||
488 | help | ||
489 | This option enables support for integrated IDE controller | ||
490 | of the Freescale MPC52xx SoC. | ||
491 | |||
492 | If unsure, say N. | ||
493 | |||
494 | config PATA_NETCELL | 494 | config PATA_NETCELL |
495 | tristate "NETCELL Revolution RAID support" | 495 | tristate "NETCELL Revolution RAID support" |
496 | depends on PCI | 496 | depends on PCI |
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile index c501af5b12b9..2b67c900a459 100644 --- a/drivers/ata/Makefile +++ b/drivers/ata/Makefile | |||
@@ -11,7 +11,6 @@ obj-$(CONFIG_SATA_DWC) += sata_dwc_460ex.o | |||
11 | 11 | ||
12 | # SFF w/ custom DMA | 12 | # SFF w/ custom DMA |
13 | obj-$(CONFIG_PDC_ADMA) += pdc_adma.o | 13 | obj-$(CONFIG_PDC_ADMA) += pdc_adma.o |
14 | obj-$(CONFIG_PATA_MPC52xx) += pata_mpc52xx.o | ||
15 | obj-$(CONFIG_PATA_OCTEON_CF) += pata_octeon_cf.o | 14 | obj-$(CONFIG_PATA_OCTEON_CF) += pata_octeon_cf.o |
16 | obj-$(CONFIG_SATA_QSTOR) += sata_qstor.o | 15 | obj-$(CONFIG_SATA_QSTOR) += sata_qstor.o |
17 | obj-$(CONFIG_SATA_SX4) += sata_sx4.o | 16 | obj-$(CONFIG_SATA_SX4) += sata_sx4.o |
@@ -52,6 +51,7 @@ obj-$(CONFIG_PATA_IT821X) += pata_it821x.o | |||
52 | obj-$(CONFIG_PATA_JMICRON) += pata_jmicron.o | 51 | obj-$(CONFIG_PATA_JMICRON) += pata_jmicron.o |
53 | obj-$(CONFIG_PATA_MACIO) += pata_macio.o | 52 | obj-$(CONFIG_PATA_MACIO) += pata_macio.o |
54 | obj-$(CONFIG_PATA_MARVELL) += pata_marvell.o | 53 | obj-$(CONFIG_PATA_MARVELL) += pata_marvell.o |
54 | obj-$(CONFIG_PATA_MPC52xx) += pata_mpc52xx.o | ||
55 | obj-$(CONFIG_PATA_NETCELL) += pata_netcell.o | 55 | obj-$(CONFIG_PATA_NETCELL) += pata_netcell.o |
56 | obj-$(CONFIG_PATA_NINJA32) += pata_ninja32.o | 56 | obj-$(CONFIG_PATA_NINJA32) += pata_ninja32.o |
57 | obj-$(CONFIG_PATA_NS87415) += pata_ns87415.o | 57 | obj-$(CONFIG_PATA_NS87415) += pata_ns87415.o |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 7f77c67d267c..f23d6d46b95b 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -4807,9 +4807,6 @@ static void ata_verify_xfer(struct ata_queued_cmd *qc) | |||
4807 | { | 4807 | { |
4808 | struct ata_device *dev = qc->dev; | 4808 | struct ata_device *dev = qc->dev; |
4809 | 4809 | ||
4810 | if (ata_tag_internal(qc->tag)) | ||
4811 | return; | ||
4812 | |||
4813 | if (ata_is_nodata(qc->tf.protocol)) | 4810 | if (ata_is_nodata(qc->tf.protocol)) |
4814 | return; | 4811 | return; |
4815 | 4812 | ||
@@ -4858,14 +4855,23 @@ void ata_qc_complete(struct ata_queued_cmd *qc) | |||
4858 | if (unlikely(qc->err_mask)) | 4855 | if (unlikely(qc->err_mask)) |
4859 | qc->flags |= ATA_QCFLAG_FAILED; | 4856 | qc->flags |= ATA_QCFLAG_FAILED; |
4860 | 4857 | ||
4861 | if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) { | 4858 | /* |
4862 | /* always fill result TF for failed qc */ | 4859 | * Finish internal commands without any further processing |
4860 | * and always with the result TF filled. | ||
4861 | */ | ||
4862 | if (unlikely(ata_tag_internal(qc->tag))) { | ||
4863 | fill_result_tf(qc); | 4863 | fill_result_tf(qc); |
4864 | __ata_qc_complete(qc); | ||
4865 | return; | ||
4866 | } | ||
4864 | 4867 | ||
4865 | if (!ata_tag_internal(qc->tag)) | 4868 | /* |
4866 | ata_qc_schedule_eh(qc); | 4869 | * Non-internal qc has failed. Fill the result TF and |
4867 | else | 4870 | * summon EH. |
4868 | __ata_qc_complete(qc); | 4871 | */ |
4872 | if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) { | ||
4873 | fill_result_tf(qc); | ||
4874 | ata_qc_schedule_eh(qc); | ||
4869 | return; | 4875 | return; |
4870 | } | 4876 | } |
4871 | 4877 | ||
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 5e590504f3aa..17a637877d03 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
@@ -3275,6 +3275,7 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, | |||
3275 | struct ata_port *ap = ata_is_host_link(link) ? link->ap : NULL; | 3275 | struct ata_port *ap = ata_is_host_link(link) ? link->ap : NULL; |
3276 | struct ata_eh_context *ehc = &link->eh_context; | 3276 | struct ata_eh_context *ehc = &link->eh_context; |
3277 | struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL; | 3277 | struct ata_device *dev, *link_dev = NULL, *lpm_dev = NULL; |
3278 | enum ata_lpm_policy old_policy = link->lpm_policy; | ||
3278 | unsigned int hints = ATA_LPM_EMPTY | ATA_LPM_HIPM; | 3279 | unsigned int hints = ATA_LPM_EMPTY | ATA_LPM_HIPM; |
3279 | unsigned int err_mask; | 3280 | unsigned int err_mask; |
3280 | int rc; | 3281 | int rc; |
@@ -3338,6 +3339,14 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, | |||
3338 | goto fail; | 3339 | goto fail; |
3339 | } | 3340 | } |
3340 | 3341 | ||
3342 | /* | ||
3343 | * Low level driver acked the transition. Issue DIPM command | ||
3344 | * with the new policy set. | ||
3345 | */ | ||
3346 | link->lpm_policy = policy; | ||
3347 | if (ap && ap->slave_link) | ||
3348 | ap->slave_link->lpm_policy = policy; | ||
3349 | |||
3341 | /* host config updated, enable DIPM if transitioning to MIN_POWER */ | 3350 | /* host config updated, enable DIPM if transitioning to MIN_POWER */ |
3342 | ata_for_each_dev(dev, link, ENABLED) { | 3351 | ata_for_each_dev(dev, link, ENABLED) { |
3343 | if (policy == ATA_LPM_MIN_POWER && ata_id_has_dipm(dev->id)) { | 3352 | if (policy == ATA_LPM_MIN_POWER && ata_id_has_dipm(dev->id)) { |
@@ -3353,12 +3362,14 @@ static int ata_eh_set_lpm(struct ata_link *link, enum ata_lpm_policy policy, | |||
3353 | } | 3362 | } |
3354 | } | 3363 | } |
3355 | 3364 | ||
3356 | link->lpm_policy = policy; | ||
3357 | if (ap && ap->slave_link) | ||
3358 | ap->slave_link->lpm_policy = policy; | ||
3359 | return 0; | 3365 | return 0; |
3360 | 3366 | ||
3361 | fail: | 3367 | fail: |
3368 | /* restore the old policy */ | ||
3369 | link->lpm_policy = old_policy; | ||
3370 | if (ap && ap->slave_link) | ||
3371 | ap->slave_link->lpm_policy = old_policy; | ||
3372 | |||
3362 | /* if no device or only one more chance is left, disable LPM */ | 3373 | /* if no device or only one more chance is left, disable LPM */ |
3363 | if (!dev || ehc->tries[dev->devno] <= 2) { | 3374 | if (!dev || ehc->tries[dev->devno] <= 2) { |
3364 | ata_link_printk(link, KERN_WARNING, | 3375 | ata_link_printk(link, KERN_WARNING, |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index d05387d1e14b..484697fef386 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -1532,11 +1532,10 @@ static unsigned int __ata_sff_port_intr(struct ata_port *ap, | |||
1532 | if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) | 1532 | if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) |
1533 | return ata_sff_idle_irq(ap); | 1533 | return ata_sff_idle_irq(ap); |
1534 | break; | 1534 | break; |
1535 | case HSM_ST: | 1535 | case HSM_ST_IDLE: |
1536 | case HSM_ST_LAST: | ||
1537 | break; | ||
1538 | default: | ||
1539 | return ata_sff_idle_irq(ap); | 1536 | return ata_sff_idle_irq(ap); |
1537 | default: | ||
1538 | break; | ||
1540 | } | 1539 | } |
1541 | 1540 | ||
1542 | /* check main status, clearing INTRQ if needed */ | 1541 | /* check main status, clearing INTRQ if needed */ |
diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c index 21ee23f89e88..628c8fae5937 100644 --- a/drivers/ata/pata_cs5536.c +++ b/drivers/ata/pata_cs5536.c | |||
@@ -37,10 +37,22 @@ | |||
37 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
38 | #include <linux/libata.h> | 38 | #include <linux/libata.h> |
39 | #include <scsi/scsi_host.h> | 39 | #include <scsi/scsi_host.h> |
40 | |||
41 | #ifdef CONFIG_X86_32 | ||
40 | #include <asm/msr.h> | 42 | #include <asm/msr.h> |
43 | static int use_msr; | ||
44 | module_param_named(msr, use_msr, int, 0644); | ||
45 | MODULE_PARM_DESC(msr, "Force using MSR to configure IDE function (Default: 0)"); | ||
46 | #else | ||
47 | #undef rdmsr /* avoid accidental MSR usage on, e.g. x86-64 */ | ||
48 | #undef wrmsr | ||
49 | #define rdmsr(x, y, z) do { } while (0) | ||
50 | #define wrmsr(x, y, z) do { } while (0) | ||
51 | #define use_msr 0 | ||
52 | #endif | ||
41 | 53 | ||
42 | #define DRV_NAME "pata_cs5536" | 54 | #define DRV_NAME "pata_cs5536" |
43 | #define DRV_VERSION "0.0.7" | 55 | #define DRV_VERSION "0.0.8" |
44 | 56 | ||
45 | enum { | 57 | enum { |
46 | CFG = 0, | 58 | CFG = 0, |
@@ -75,8 +87,6 @@ enum { | |||
75 | IDE_ETC_NODMA = 0x03, | 87 | IDE_ETC_NODMA = 0x03, |
76 | }; | 88 | }; |
77 | 89 | ||
78 | static int use_msr; | ||
79 | |||
80 | static const u32 msr_reg[4] = { | 90 | static const u32 msr_reg[4] = { |
81 | MSR_IDE_CFG, MSR_IDE_DTC, MSR_IDE_CAST, MSR_IDE_ETC, | 91 | MSR_IDE_CFG, MSR_IDE_DTC, MSR_IDE_CAST, MSR_IDE_ETC, |
82 | }; | 92 | }; |
@@ -88,7 +98,7 @@ static const u8 pci_reg[4] = { | |||
88 | static inline int cs5536_read(struct pci_dev *pdev, int reg, u32 *val) | 98 | static inline int cs5536_read(struct pci_dev *pdev, int reg, u32 *val) |
89 | { | 99 | { |
90 | if (unlikely(use_msr)) { | 100 | if (unlikely(use_msr)) { |
91 | u32 dummy; | 101 | u32 dummy __maybe_unused; |
92 | 102 | ||
93 | rdmsr(msr_reg[reg], *val, dummy); | 103 | rdmsr(msr_reg[reg], *val, dummy); |
94 | return 0; | 104 | return 0; |
@@ -294,8 +304,6 @@ MODULE_DESCRIPTION("low-level driver for the CS5536 IDE controller"); | |||
294 | MODULE_LICENSE("GPL"); | 304 | MODULE_LICENSE("GPL"); |
295 | MODULE_DEVICE_TABLE(pci, cs5536); | 305 | MODULE_DEVICE_TABLE(pci, cs5536); |
296 | MODULE_VERSION(DRV_VERSION); | 306 | MODULE_VERSION(DRV_VERSION); |
297 | module_param_named(msr, use_msr, int, 0644); | ||
298 | MODULE_PARM_DESC(msr, "Force using MSR to configure IDE function (Default: 0)"); | ||
299 | 307 | ||
300 | module_init(cs5536_init); | 308 | module_init(cs5536_init); |
301 | module_exit(cs5536_exit); | 309 | module_exit(cs5536_exit); |
diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c index 46b94762125b..f9b983ae6877 100644 --- a/drivers/atm/adummy.c +++ b/drivers/atm/adummy.c | |||
@@ -154,7 +154,7 @@ static int __init adummy_init(void) | |||
154 | err = -ENOMEM; | 154 | err = -ENOMEM; |
155 | goto out; | 155 | goto out; |
156 | } | 156 | } |
157 | atm_dev = atm_dev_register(DEV_LABEL, &adummy_ops, -1, NULL); | 157 | atm_dev = atm_dev_register(DEV_LABEL, NULL, &adummy_ops, -1, NULL); |
158 | if (!atm_dev) { | 158 | if (!atm_dev) { |
159 | printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n"); | 159 | printk(KERN_ERR DEV_LABEL ": atm_dev_register() failed\n"); |
160 | err = -ENODEV; | 160 | err = -ENODEV; |
diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c index a33896a482e6..ffe9b655292e 100644 --- a/drivers/atm/ambassador.c +++ b/drivers/atm/ambassador.c | |||
@@ -2244,7 +2244,8 @@ static int __devinit amb_probe(struct pci_dev *pci_dev, const struct pci_device_ | |||
2244 | goto out_reset; | 2244 | goto out_reset; |
2245 | } | 2245 | } |
2246 | 2246 | ||
2247 | dev->atm_dev = atm_dev_register (DEV_LABEL, &amb_ops, -1, NULL); | 2247 | dev->atm_dev = atm_dev_register (DEV_LABEL, &pci_dev->dev, &amb_ops, -1, |
2248 | NULL); | ||
2248 | if (!dev->atm_dev) { | 2249 | if (!dev->atm_dev) { |
2249 | PRINTD (DBG_ERR, "failed to register Madge ATM adapter"); | 2250 | PRINTD (DBG_ERR, "failed to register Madge ATM adapter"); |
2250 | err = -EINVAL; | 2251 | err = -EINVAL; |
diff --git a/drivers/atm/atmtcp.c b/drivers/atm/atmtcp.c index b9101818b47b..0b0625054a87 100644 --- a/drivers/atm/atmtcp.c +++ b/drivers/atm/atmtcp.c | |||
@@ -366,7 +366,7 @@ static int atmtcp_create(int itf,int persist,struct atm_dev **result) | |||
366 | if (!dev_data) | 366 | if (!dev_data) |
367 | return -ENOMEM; | 367 | return -ENOMEM; |
368 | 368 | ||
369 | dev = atm_dev_register(DEV_LABEL,&atmtcp_v_dev_ops,itf,NULL); | 369 | dev = atm_dev_register(DEV_LABEL,NULL,&atmtcp_v_dev_ops,itf,NULL); |
370 | if (!dev) { | 370 | if (!dev) { |
371 | kfree(dev_data); | 371 | kfree(dev_data); |
372 | return itf == -1 ? -ENOMEM : -EBUSY; | 372 | return itf == -1 ? -ENOMEM : -EBUSY; |
@@ -392,7 +392,10 @@ static int atmtcp_attach(struct atm_vcc *vcc,int itf) | |||
392 | atm_dev_put(dev); | 392 | atm_dev_put(dev); |
393 | return -EMEDIUMTYPE; | 393 | return -EMEDIUMTYPE; |
394 | } | 394 | } |
395 | if (PRIV(dev)->vcc) return -EBUSY; | 395 | if (PRIV(dev)->vcc) { |
396 | atm_dev_put(dev); | ||
397 | return -EBUSY; | ||
398 | } | ||
396 | } | 399 | } |
397 | else { | 400 | else { |
398 | int error; | 401 | int error; |
diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c index 97c5898cd76e..c495fae74200 100644 --- a/drivers/atm/eni.c +++ b/drivers/atm/eni.c | |||
@@ -2244,7 +2244,7 @@ static int __devinit eni_init_one(struct pci_dev *pci_dev, | |||
2244 | &zeroes); | 2244 | &zeroes); |
2245 | if (!cpu_zeroes) goto out1; | 2245 | if (!cpu_zeroes) goto out1; |
2246 | } | 2246 | } |
2247 | dev = atm_dev_register(DEV_LABEL,&ops,-1,NULL); | 2247 | dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL); |
2248 | if (!dev) goto out2; | 2248 | if (!dev) goto out2; |
2249 | pci_set_drvdata(pci_dev, dev); | 2249 | pci_set_drvdata(pci_dev, dev); |
2250 | eni_dev->pci_dev = pci_dev; | 2250 | eni_dev->pci_dev = pci_dev; |
diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index 5d86bb803e94..7d912baf01d4 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c | |||
@@ -1911,7 +1911,7 @@ static int __devinit firestream_init_one (struct pci_dev *pci_dev, | |||
1911 | fs_dev, sizeof (struct fs_dev)); | 1911 | fs_dev, sizeof (struct fs_dev)); |
1912 | if (!fs_dev) | 1912 | if (!fs_dev) |
1913 | goto err_out; | 1913 | goto err_out; |
1914 | atm_dev = atm_dev_register("fs", &ops, -1, NULL); | 1914 | atm_dev = atm_dev_register("fs", &pci_dev->dev, &ops, -1, NULL); |
1915 | if (!atm_dev) | 1915 | if (!atm_dev) |
1916 | goto err_out_free_fs_dev; | 1916 | goto err_out_free_fs_dev; |
1917 | 1917 | ||
diff --git a/drivers/atm/fore200e.c b/drivers/atm/fore200e.c index c8fc69c85a06..962c309b40c0 100644 --- a/drivers/atm/fore200e.c +++ b/drivers/atm/fore200e.c | |||
@@ -2567,14 +2567,14 @@ release: | |||
2567 | 2567 | ||
2568 | 2568 | ||
2569 | static int __devinit | 2569 | static int __devinit |
2570 | fore200e_register(struct fore200e* fore200e) | 2570 | fore200e_register(struct fore200e* fore200e, struct device *parent) |
2571 | { | 2571 | { |
2572 | struct atm_dev* atm_dev; | 2572 | struct atm_dev* atm_dev; |
2573 | 2573 | ||
2574 | DPRINTK(2, "device %s being registered\n", fore200e->name); | 2574 | DPRINTK(2, "device %s being registered\n", fore200e->name); |
2575 | 2575 | ||
2576 | atm_dev = atm_dev_register(fore200e->bus->proc_name, &fore200e_ops, -1, | 2576 | atm_dev = atm_dev_register(fore200e->bus->proc_name, parent, &fore200e_ops, |
2577 | NULL); | 2577 | -1, NULL); |
2578 | if (atm_dev == NULL) { | 2578 | if (atm_dev == NULL) { |
2579 | printk(FORE200E "unable to register device %s\n", fore200e->name); | 2579 | printk(FORE200E "unable to register device %s\n", fore200e->name); |
2580 | return -ENODEV; | 2580 | return -ENODEV; |
@@ -2594,9 +2594,9 @@ fore200e_register(struct fore200e* fore200e) | |||
2594 | 2594 | ||
2595 | 2595 | ||
2596 | static int __devinit | 2596 | static int __devinit |
2597 | fore200e_init(struct fore200e* fore200e) | 2597 | fore200e_init(struct fore200e* fore200e, struct device *parent) |
2598 | { | 2598 | { |
2599 | if (fore200e_register(fore200e) < 0) | 2599 | if (fore200e_register(fore200e, parent) < 0) |
2600 | return -ENODEV; | 2600 | return -ENODEV; |
2601 | 2601 | ||
2602 | if (fore200e->bus->configure(fore200e) < 0) | 2602 | if (fore200e->bus->configure(fore200e) < 0) |
@@ -2662,7 +2662,7 @@ static int __devinit fore200e_sba_probe(struct platform_device *op, | |||
2662 | 2662 | ||
2663 | sprintf(fore200e->name, "%s-%d", bus->model_name, index); | 2663 | sprintf(fore200e->name, "%s-%d", bus->model_name, index); |
2664 | 2664 | ||
2665 | err = fore200e_init(fore200e); | 2665 | err = fore200e_init(fore200e, &op->dev); |
2666 | if (err < 0) { | 2666 | if (err < 0) { |
2667 | fore200e_shutdown(fore200e); | 2667 | fore200e_shutdown(fore200e); |
2668 | kfree(fore200e); | 2668 | kfree(fore200e); |
@@ -2740,7 +2740,7 @@ fore200e_pca_detect(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent | |||
2740 | 2740 | ||
2741 | sprintf(fore200e->name, "%s-%d", bus->model_name, index); | 2741 | sprintf(fore200e->name, "%s-%d", bus->model_name, index); |
2742 | 2742 | ||
2743 | err = fore200e_init(fore200e); | 2743 | err = fore200e_init(fore200e, &pci_dev->dev); |
2744 | if (err < 0) { | 2744 | if (err < 0) { |
2745 | fore200e_shutdown(fore200e); | 2745 | fore200e_shutdown(fore200e); |
2746 | goto out_free; | 2746 | goto out_free; |
diff --git a/drivers/atm/he.c b/drivers/atm/he.c index 801e8b6e9d1f..6cf59bf281dc 100644 --- a/drivers/atm/he.c +++ b/drivers/atm/he.c | |||
@@ -366,7 +366,7 @@ he_init_one(struct pci_dev *pci_dev, const struct pci_device_id *pci_ent) | |||
366 | goto init_one_failure; | 366 | goto init_one_failure; |
367 | } | 367 | } |
368 | 368 | ||
369 | atm_dev = atm_dev_register(DEV_LABEL, &he_ops, -1, NULL); | 369 | atm_dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &he_ops, -1, NULL); |
370 | if (!atm_dev) { | 370 | if (!atm_dev) { |
371 | err = -ENODEV; | 371 | err = -ENODEV; |
372 | goto init_one_failure; | 372 | goto init_one_failure; |
diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c index a95790452a68..24761e1d6642 100644 --- a/drivers/atm/horizon.c +++ b/drivers/atm/horizon.c | |||
@@ -2733,7 +2733,8 @@ static int __devinit hrz_probe(struct pci_dev *pci_dev, const struct pci_device_ | |||
2733 | PRINTD(DBG_INFO, "found Madge ATM adapter (hrz) at: IO %x, IRQ %u, MEM %p", | 2733 | PRINTD(DBG_INFO, "found Madge ATM adapter (hrz) at: IO %x, IRQ %u, MEM %p", |
2734 | iobase, irq, membase); | 2734 | iobase, irq, membase); |
2735 | 2735 | ||
2736 | dev->atm_dev = atm_dev_register(DEV_LABEL, &hrz_ops, -1, NULL); | 2736 | dev->atm_dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &hrz_ops, -1, |
2737 | NULL); | ||
2737 | if (!(dev->atm_dev)) { | 2738 | if (!(dev->atm_dev)) { |
2738 | PRINTD(DBG_ERR, "failed to register Madge ATM adapter"); | 2739 | PRINTD(DBG_ERR, "failed to register Madge ATM adapter"); |
2739 | err = -EINVAL; | 2740 | err = -EINVAL; |
diff --git a/drivers/atm/idt77252.c b/drivers/atm/idt77252.c index bce57328ddde..bfb7feee0400 100644 --- a/drivers/atm/idt77252.c +++ b/drivers/atm/idt77252.c | |||
@@ -3698,7 +3698,8 @@ idt77252_init_one(struct pci_dev *pcidev, const struct pci_device_id *id) | |||
3698 | goto err_out_iounmap; | 3698 | goto err_out_iounmap; |
3699 | } | 3699 | } |
3700 | 3700 | ||
3701 | dev = atm_dev_register("idt77252", &idt77252_ops, -1, NULL); | 3701 | dev = atm_dev_register("idt77252", &pcidev->dev, &idt77252_ops, -1, |
3702 | NULL); | ||
3702 | if (!dev) { | 3703 | if (!dev) { |
3703 | printk("%s: can't register atm device\n", card->name); | 3704 | printk("%s: can't register atm device\n", card->name); |
3704 | err = -EIO; | 3705 | err = -EIO; |
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index 9309d4724e13..729254053758 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c | |||
@@ -3172,7 +3172,7 @@ static int __devinit ia_init_one(struct pci_dev *pdev, | |||
3172 | ret = -ENODEV; | 3172 | ret = -ENODEV; |
3173 | goto err_out_free_iadev; | 3173 | goto err_out_free_iadev; |
3174 | } | 3174 | } |
3175 | dev = atm_dev_register(DEV_LABEL, &ops, -1, NULL); | 3175 | dev = atm_dev_register(DEV_LABEL, &pdev->dev, &ops, -1, NULL); |
3176 | if (!dev) { | 3176 | if (!dev) { |
3177 | ret = -ENOMEM; | 3177 | ret = -ENOMEM; |
3178 | goto err_out_disable_dev; | 3178 | goto err_out_disable_dev; |
diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c index cbe15a86c669..a395c9aab146 100644 --- a/drivers/atm/lanai.c +++ b/drivers/atm/lanai.c | |||
@@ -2591,7 +2591,7 @@ static int __devinit lanai_init_one(struct pci_dev *pci, | |||
2591 | return -ENOMEM; | 2591 | return -ENOMEM; |
2592 | } | 2592 | } |
2593 | 2593 | ||
2594 | atmdev = atm_dev_register(DEV_LABEL, &ops, -1, NULL); | 2594 | atmdev = atm_dev_register(DEV_LABEL, &pci->dev, &ops, -1, NULL); |
2595 | if (atmdev == NULL) { | 2595 | if (atmdev == NULL) { |
2596 | printk(KERN_ERR DEV_LABEL | 2596 | printk(KERN_ERR DEV_LABEL |
2597 | ": couldn't register atm device!\n"); | 2597 | ": couldn't register atm device!\n"); |
diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c index 2f3516b7f118..6b313ee9231b 100644 --- a/drivers/atm/nicstar.c +++ b/drivers/atm/nicstar.c | |||
@@ -771,7 +771,8 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev) | |||
771 | } | 771 | } |
772 | 772 | ||
773 | /* Register device */ | 773 | /* Register device */ |
774 | card->atmdev = atm_dev_register("nicstar", &atm_ops, -1, NULL); | 774 | card->atmdev = atm_dev_register("nicstar", &card->pcidev->dev, &atm_ops, |
775 | -1, NULL); | ||
775 | if (card->atmdev == NULL) { | 776 | if (card->atmdev == NULL) { |
776 | printk("nicstar%d: can't register device.\n", i); | 777 | printk("nicstar%d: can't register device.\n", i); |
777 | error = 17; | 778 | error = 17; |
diff --git a/drivers/atm/solos-pci.c b/drivers/atm/solos-pci.c index 2e08c996fd30..73fb1c4f4cd4 100644 --- a/drivers/atm/solos-pci.c +++ b/drivers/atm/solos-pci.c | |||
@@ -166,7 +166,7 @@ static irqreturn_t solos_irq(int irq, void *dev_id); | |||
166 | static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci); | 166 | static struct atm_vcc* find_vcc(struct atm_dev *dev, short vpi, int vci); |
167 | static int list_vccs(int vci); | 167 | static int list_vccs(int vci); |
168 | static void release_vccs(struct atm_dev *dev); | 168 | static void release_vccs(struct atm_dev *dev); |
169 | static int atm_init(struct solos_card *); | 169 | static int atm_init(struct solos_card *, struct device *); |
170 | static void atm_remove(struct solos_card *); | 170 | static void atm_remove(struct solos_card *); |
171 | static int send_command(struct solos_card *card, int dev, const char *buf, size_t size); | 171 | static int send_command(struct solos_card *card, int dev, const char *buf, size_t size); |
172 | static void solos_bh(unsigned long); | 172 | static void solos_bh(unsigned long); |
@@ -1210,7 +1210,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1210 | if (db_firmware_upgrade) | 1210 | if (db_firmware_upgrade) |
1211 | flash_upgrade(card, 3); | 1211 | flash_upgrade(card, 3); |
1212 | 1212 | ||
1213 | err = atm_init(card); | 1213 | err = atm_init(card, &dev->dev); |
1214 | if (err) | 1214 | if (err) |
1215 | goto out_free_irq; | 1215 | goto out_free_irq; |
1216 | 1216 | ||
@@ -1233,7 +1233,7 @@ static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
1233 | return err; | 1233 | return err; |
1234 | } | 1234 | } |
1235 | 1235 | ||
1236 | static int atm_init(struct solos_card *card) | 1236 | static int atm_init(struct solos_card *card, struct device *parent) |
1237 | { | 1237 | { |
1238 | int i; | 1238 | int i; |
1239 | 1239 | ||
@@ -1244,7 +1244,7 @@ static int atm_init(struct solos_card *card) | |||
1244 | skb_queue_head_init(&card->tx_queue[i]); | 1244 | skb_queue_head_init(&card->tx_queue[i]); |
1245 | skb_queue_head_init(&card->cli_queue[i]); | 1245 | skb_queue_head_init(&card->cli_queue[i]); |
1246 | 1246 | ||
1247 | card->atmdev[i] = atm_dev_register("solos-pci", &fpga_ops, -1, NULL); | 1247 | card->atmdev[i] = atm_dev_register("solos-pci", parent, &fpga_ops, -1, NULL); |
1248 | if (!card->atmdev[i]) { | 1248 | if (!card->atmdev[i]) { |
1249 | dev_err(&card->dev->dev, "Could not register ATM device %d\n", i); | 1249 | dev_err(&card->dev->dev, "Could not register ATM device %d\n", i); |
1250 | atm_remove(card); | 1250 | atm_remove(card); |
diff --git a/drivers/atm/zatm.c b/drivers/atm/zatm.c index 4e885d2da49c..624917902b65 100644 --- a/drivers/atm/zatm.c +++ b/drivers/atm/zatm.c | |||
@@ -1597,7 +1597,7 @@ static int __devinit zatm_init_one(struct pci_dev *pci_dev, | |||
1597 | goto out; | 1597 | goto out; |
1598 | } | 1598 | } |
1599 | 1599 | ||
1600 | dev = atm_dev_register(DEV_LABEL, &ops, -1, NULL); | 1600 | dev = atm_dev_register(DEV_LABEL, &pci_dev->dev, &ops, -1, NULL); |
1601 | if (!dev) | 1601 | if (!dev) |
1602 | goto out_free; | 1602 | goto out_free; |
1603 | 1603 | ||
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index f291587d753e..8e0f9256eb58 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -2834,6 +2834,8 @@ static int cciss_revalidate(struct gendisk *disk) | |||
2834 | InquiryData_struct *inq_buff = NULL; | 2834 | InquiryData_struct *inq_buff = NULL; |
2835 | 2835 | ||
2836 | for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { | 2836 | for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { |
2837 | if (!h->drv[logvol]) | ||
2838 | continue; | ||
2837 | if (memcmp(h->drv[logvol]->LunID, drv->LunID, | 2839 | if (memcmp(h->drv[logvol]->LunID, drv->LunID, |
2838 | sizeof(drv->LunID)) == 0) { | 2840 | sizeof(drv->LunID)) == 0) { |
2839 | FOUND = 1; | 2841 | FOUND = 1; |
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 89d8a7cc4054..24487d4fb202 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -3627,17 +3627,19 @@ static void drbdd(struct drbd_conf *mdev) | |||
3627 | } | 3627 | } |
3628 | 3628 | ||
3629 | shs = drbd_cmd_handler[cmd].pkt_size - sizeof(union p_header); | 3629 | shs = drbd_cmd_handler[cmd].pkt_size - sizeof(union p_header); |
3630 | rv = drbd_recv(mdev, &header->h80.payload, shs); | ||
3631 | if (unlikely(rv != shs)) { | ||
3632 | dev_err(DEV, "short read while reading sub header: rv=%d\n", rv); | ||
3633 | goto err_out; | ||
3634 | } | ||
3635 | |||
3636 | if (packet_size - shs > 0 && !drbd_cmd_handler[cmd].expect_payload) { | 3630 | if (packet_size - shs > 0 && !drbd_cmd_handler[cmd].expect_payload) { |
3637 | dev_err(DEV, "No payload expected %s l:%d\n", cmdname(cmd), packet_size); | 3631 | dev_err(DEV, "No payload expected %s l:%d\n", cmdname(cmd), packet_size); |
3638 | goto err_out; | 3632 | goto err_out; |
3639 | } | 3633 | } |
3640 | 3634 | ||
3635 | if (shs) { | ||
3636 | rv = drbd_recv(mdev, &header->h80.payload, shs); | ||
3637 | if (unlikely(rv != shs)) { | ||
3638 | dev_err(DEV, "short read while reading sub header: rv=%d\n", rv); | ||
3639 | goto err_out; | ||
3640 | } | ||
3641 | } | ||
3642 | |||
3641 | rv = drbd_cmd_handler[cmd].function(mdev, cmd, packet_size - shs); | 3643 | rv = drbd_cmd_handler[cmd].function(mdev, cmd, packet_size - shs); |
3642 | 3644 | ||
3643 | if (unlikely(!rv)) { | 3645 | if (unlikely(!rv)) { |
diff --git a/drivers/block/drbd/drbd_req.h b/drivers/block/drbd/drbd_req.h index 181ea0364822..ab2bd09d54b4 100644 --- a/drivers/block/drbd/drbd_req.h +++ b/drivers/block/drbd/drbd_req.h | |||
@@ -339,7 +339,8 @@ static inline int _req_mod(struct drbd_request *req, enum drbd_req_event what) | |||
339 | } | 339 | } |
340 | 340 | ||
341 | /* completion of master bio is outside of spinlock. | 341 | /* completion of master bio is outside of spinlock. |
342 | * If you need it irqsave, do it your self! */ | 342 | * If you need it irqsave, do it your self! |
343 | * Which means: don't use from bio endio callback. */ | ||
343 | static inline int req_mod(struct drbd_request *req, | 344 | static inline int req_mod(struct drbd_request *req, |
344 | enum drbd_req_event what) | 345 | enum drbd_req_event what) |
345 | { | 346 | { |
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index 47d223c2409c..34f224b018b3 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c | |||
@@ -193,8 +193,10 @@ void drbd_endio_sec(struct bio *bio, int error) | |||
193 | */ | 193 | */ |
194 | void drbd_endio_pri(struct bio *bio, int error) | 194 | void drbd_endio_pri(struct bio *bio, int error) |
195 | { | 195 | { |
196 | unsigned long flags; | ||
196 | struct drbd_request *req = bio->bi_private; | 197 | struct drbd_request *req = bio->bi_private; |
197 | struct drbd_conf *mdev = req->mdev; | 198 | struct drbd_conf *mdev = req->mdev; |
199 | struct bio_and_error m; | ||
198 | enum drbd_req_event what; | 200 | enum drbd_req_event what; |
199 | int uptodate = bio_flagged(bio, BIO_UPTODATE); | 201 | int uptodate = bio_flagged(bio, BIO_UPTODATE); |
200 | 202 | ||
@@ -220,7 +222,13 @@ void drbd_endio_pri(struct bio *bio, int error) | |||
220 | bio_put(req->private_bio); | 222 | bio_put(req->private_bio); |
221 | req->private_bio = ERR_PTR(error); | 223 | req->private_bio = ERR_PTR(error); |
222 | 224 | ||
223 | req_mod(req, what); | 225 | /* not req_mod(), we need irqsave here! */ |
226 | spin_lock_irqsave(&mdev->req_lock, flags); | ||
227 | __req_mod(req, what, &m); | ||
228 | spin_unlock_irqrestore(&mdev->req_lock, flags); | ||
229 | |||
230 | if (m.bio) | ||
231 | complete_master_bio(mdev, &m); | ||
224 | } | 232 | } |
225 | 233 | ||
226 | int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel) | 234 | int w_read_retry_remote(struct drbd_conf *mdev, struct drbd_work *w, int cancel) |
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c index 4f9e22f29138..657873e4328d 100644 --- a/drivers/block/xen-blkfront.c +++ b/drivers/block/xen-blkfront.c | |||
@@ -72,7 +72,7 @@ struct blk_shadow { | |||
72 | static DEFINE_MUTEX(blkfront_mutex); | 72 | static DEFINE_MUTEX(blkfront_mutex); |
73 | static const struct block_device_operations xlvbd_block_fops; | 73 | static const struct block_device_operations xlvbd_block_fops; |
74 | 74 | ||
75 | #define BLK_RING_SIZE __RING_SIZE((struct blkif_sring *)0, PAGE_SIZE) | 75 | #define BLK_RING_SIZE __CONST_RING_SIZE(blkif, PAGE_SIZE) |
76 | 76 | ||
77 | /* | 77 | /* |
78 | * We have one of these per vbd, whether ide, scsi or 'other'. They | 78 | * We have one of these per vbd, whether ide, scsi or 'other'. They |
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 128cae4e8629..949ed09c6361 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c | |||
@@ -35,6 +35,10 @@ | |||
35 | static struct usb_device_id ath3k_table[] = { | 35 | static struct usb_device_id ath3k_table[] = { |
36 | /* Atheros AR3011 */ | 36 | /* Atheros AR3011 */ |
37 | { USB_DEVICE(0x0CF3, 0x3000) }, | 37 | { USB_DEVICE(0x0CF3, 0x3000) }, |
38 | |||
39 | /* Atheros AR3011 with sflash firmware*/ | ||
40 | { USB_DEVICE(0x0CF3, 0x3002) }, | ||
41 | |||
38 | { } /* Terminating entry */ | 42 | { } /* Terminating entry */ |
39 | }; | 43 | }; |
40 | 44 | ||
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index ab3894f742c3..1da773f899a2 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -99,6 +99,9 @@ static struct usb_device_id blacklist_table[] = { | |||
99 | /* Broadcom BCM2033 without firmware */ | 99 | /* Broadcom BCM2033 without firmware */ |
100 | { USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE }, | 100 | { USB_DEVICE(0x0a5c, 0x2033), .driver_info = BTUSB_IGNORE }, |
101 | 101 | ||
102 | /* Atheros 3011 with sflash firmware */ | ||
103 | { USB_DEVICE(0x0cf3, 0x3002), .driver_info = BTUSB_IGNORE }, | ||
104 | |||
102 | /* Broadcom BCM2035 */ | 105 | /* Broadcom BCM2035 */ |
103 | { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, | 106 | { USB_DEVICE(0x0a5c, 0x2035), .driver_info = BTUSB_WRONG_SCO_MTU }, |
104 | { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU }, | 107 | { USB_DEVICE(0x0a5c, 0x200a), .driver_info = BTUSB_WRONG_SCO_MTU }, |
@@ -239,7 +242,8 @@ static void btusb_intr_complete(struct urb *urb) | |||
239 | 242 | ||
240 | err = usb_submit_urb(urb, GFP_ATOMIC); | 243 | err = usb_submit_urb(urb, GFP_ATOMIC); |
241 | if (err < 0) { | 244 | if (err < 0) { |
242 | BT_ERR("%s urb %p failed to resubmit (%d)", | 245 | if (err != -EPERM) |
246 | BT_ERR("%s urb %p failed to resubmit (%d)", | ||
243 | hdev->name, urb, -err); | 247 | hdev->name, urb, -err); |
244 | usb_unanchor_urb(urb); | 248 | usb_unanchor_urb(urb); |
245 | } | 249 | } |
@@ -323,7 +327,8 @@ static void btusb_bulk_complete(struct urb *urb) | |||
323 | 327 | ||
324 | err = usb_submit_urb(urb, GFP_ATOMIC); | 328 | err = usb_submit_urb(urb, GFP_ATOMIC); |
325 | if (err < 0) { | 329 | if (err < 0) { |
326 | BT_ERR("%s urb %p failed to resubmit (%d)", | 330 | if (err != -EPERM) |
331 | BT_ERR("%s urb %p failed to resubmit (%d)", | ||
327 | hdev->name, urb, -err); | 332 | hdev->name, urb, -err); |
328 | usb_unanchor_urb(urb); | 333 | usb_unanchor_urb(urb); |
329 | } | 334 | } |
@@ -412,7 +417,8 @@ static void btusb_isoc_complete(struct urb *urb) | |||
412 | 417 | ||
413 | err = usb_submit_urb(urb, GFP_ATOMIC); | 418 | err = usb_submit_urb(urb, GFP_ATOMIC); |
414 | if (err < 0) { | 419 | if (err < 0) { |
415 | BT_ERR("%s urb %p failed to resubmit (%d)", | 420 | if (err != -EPERM) |
421 | BT_ERR("%s urb %p failed to resubmit (%d)", | ||
416 | hdev->name, urb, -err); | 422 | hdev->name, urb, -err); |
417 | usb_unanchor_urb(urb); | 423 | usb_unanchor_urb(urb); |
418 | } | 424 | } |
diff --git a/drivers/bluetooth/hci_ldisc.c b/drivers/bluetooth/hci_ldisc.c index 720148294e64..3c6cabcb7d84 100644 --- a/drivers/bluetooth/hci_ldisc.c +++ b/drivers/bluetooth/hci_ldisc.c | |||
@@ -311,8 +311,10 @@ static void hci_uart_tty_close(struct tty_struct *tty) | |||
311 | 311 | ||
312 | if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) { | 312 | if (test_and_clear_bit(HCI_UART_PROTO_SET, &hu->flags)) { |
313 | hu->proto->close(hu); | 313 | hu->proto->close(hu); |
314 | hci_unregister_dev(hdev); | 314 | if (hdev) { |
315 | hci_free_dev(hdev); | 315 | hci_unregister_dev(hdev); |
316 | hci_free_dev(hdev); | ||
317 | } | ||
316 | } | 318 | } |
317 | } | 319 | } |
318 | } | 320 | } |
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 9272c38dd3c6..29ac6d499fa6 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c | |||
@@ -812,8 +812,10 @@ static int intel_fake_agp_fetch_size(void) | |||
812 | 812 | ||
813 | static void i830_cleanup(void) | 813 | static void i830_cleanup(void) |
814 | { | 814 | { |
815 | kunmap(intel_private.i8xx_page); | 815 | if (intel_private.i8xx_flush_page) { |
816 | intel_private.i8xx_flush_page = NULL; | 816 | kunmap(intel_private.i8xx_flush_page); |
817 | intel_private.i8xx_flush_page = NULL; | ||
818 | } | ||
817 | 819 | ||
818 | __free_page(intel_private.i8xx_page); | 820 | __free_page(intel_private.i8xx_page); |
819 | intel_private.i8xx_page = NULL; | 821 | intel_private.i8xx_page = NULL; |
@@ -1190,12 +1192,19 @@ static void i9xx_chipset_flush(void) | |||
1190 | writel(1, intel_private.i9xx_flush_page); | 1192 | writel(1, intel_private.i9xx_flush_page); |
1191 | } | 1193 | } |
1192 | 1194 | ||
1193 | static void i965_write_entry(dma_addr_t addr, unsigned int entry, | 1195 | static void i965_write_entry(dma_addr_t addr, |
1196 | unsigned int entry, | ||
1194 | unsigned int flags) | 1197 | unsigned int flags) |
1195 | { | 1198 | { |
1199 | u32 pte_flags; | ||
1200 | |||
1201 | pte_flags = I810_PTE_VALID; | ||
1202 | if (flags == AGP_USER_CACHED_MEMORY) | ||
1203 | pte_flags |= I830_PTE_SYSTEM_CACHED; | ||
1204 | |||
1196 | /* Shift high bits down */ | 1205 | /* Shift high bits down */ |
1197 | addr |= (addr >> 28) & 0xf0; | 1206 | addr |= (addr >> 28) & 0xf0; |
1198 | writel(addr | I810_PTE_VALID, intel_private.gtt + entry); | 1207 | writel(addr | pte_flags, intel_private.gtt + entry); |
1199 | } | 1208 | } |
1200 | 1209 | ||
1201 | static bool gen6_check_flags(unsigned int flags) | 1210 | static bool gen6_check_flags(unsigned int flags) |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 035da9e64a17..c4bacc6ec450 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -1928,7 +1928,8 @@ static void __devinit hardcode_find_bmc(void) | |||
1928 | static int acpi_failure; | 1928 | static int acpi_failure; |
1929 | 1929 | ||
1930 | /* For GPE-type interrupts. */ | 1930 | /* For GPE-type interrupts. */ |
1931 | static u32 ipmi_acpi_gpe(void *context) | 1931 | static u32 ipmi_acpi_gpe(acpi_handle gpe_device, |
1932 | u32 gpe_number, void *context) | ||
1932 | { | 1933 | { |
1933 | struct smi_info *smi_info = context; | 1934 | struct smi_info *smi_info = context; |
1934 | unsigned long flags; | 1935 | unsigned long flags; |
diff --git a/drivers/char/ramoops.c b/drivers/char/ramoops.c index 73dcb0ee41fd..d3d63be2cd37 100644 --- a/drivers/char/ramoops.c +++ b/drivers/char/ramoops.c | |||
@@ -29,7 +29,6 @@ | |||
29 | #include <linux/ramoops.h> | 29 | #include <linux/ramoops.h> |
30 | 30 | ||
31 | #define RAMOOPS_KERNMSG_HDR "====" | 31 | #define RAMOOPS_KERNMSG_HDR "====" |
32 | #define RAMOOPS_HEADER_SIZE (5 + sizeof(struct timeval)) | ||
33 | 32 | ||
34 | #define RECORD_SIZE 4096 | 33 | #define RECORD_SIZE 4096 |
35 | 34 | ||
@@ -65,8 +64,8 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper, | |||
65 | struct ramoops_context, dump); | 64 | struct ramoops_context, dump); |
66 | unsigned long s1_start, s2_start; | 65 | unsigned long s1_start, s2_start; |
67 | unsigned long l1_cpy, l2_cpy; | 66 | unsigned long l1_cpy, l2_cpy; |
68 | int res; | 67 | int res, hdr_size; |
69 | char *buf; | 68 | char *buf, *buf_orig; |
70 | struct timeval timestamp; | 69 | struct timeval timestamp; |
71 | 70 | ||
72 | /* Only dump oopses if dump_oops is set */ | 71 | /* Only dump oopses if dump_oops is set */ |
@@ -74,6 +73,8 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper, | |||
74 | return; | 73 | return; |
75 | 74 | ||
76 | buf = (char *)(cxt->virt_addr + (cxt->count * RECORD_SIZE)); | 75 | buf = (char *)(cxt->virt_addr + (cxt->count * RECORD_SIZE)); |
76 | buf_orig = buf; | ||
77 | |||
77 | memset(buf, '\0', RECORD_SIZE); | 78 | memset(buf, '\0', RECORD_SIZE); |
78 | res = sprintf(buf, "%s", RAMOOPS_KERNMSG_HDR); | 79 | res = sprintf(buf, "%s", RAMOOPS_KERNMSG_HDR); |
79 | buf += res; | 80 | buf += res; |
@@ -81,8 +82,9 @@ static void ramoops_do_dump(struct kmsg_dumper *dumper, | |||
81 | res = sprintf(buf, "%lu.%lu\n", (long)timestamp.tv_sec, (long)timestamp.tv_usec); | 82 | res = sprintf(buf, "%lu.%lu\n", (long)timestamp.tv_sec, (long)timestamp.tv_usec); |
82 | buf += res; | 83 | buf += res; |
83 | 84 | ||
84 | l2_cpy = min(l2, (unsigned long)(RECORD_SIZE - RAMOOPS_HEADER_SIZE)); | 85 | hdr_size = buf - buf_orig; |
85 | l1_cpy = min(l1, (unsigned long)(RECORD_SIZE - RAMOOPS_HEADER_SIZE) - l2_cpy); | 86 | l2_cpy = min(l2, (unsigned long)(RECORD_SIZE - hdr_size)); |
87 | l1_cpy = min(l1, (unsigned long)(RECORD_SIZE - hdr_size) - l2_cpy); | ||
86 | 88 | ||
87 | s2_start = l2 - l2_cpy; | 89 | s2_start = l2 - l2_cpy; |
88 | s1_start = l1 - l1_cpy; | 90 | s1_start = l1 - l1_cpy; |
diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index d68d3aa1814b..f975d24890fa 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c | |||
@@ -283,16 +283,21 @@ static void sh_cmt_clock_event_program_verify(struct sh_cmt_priv *p, | |||
283 | } while (delay); | 283 | } while (delay); |
284 | } | 284 | } |
285 | 285 | ||
286 | static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta) | 286 | static void __sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta) |
287 | { | 287 | { |
288 | unsigned long flags; | ||
289 | |||
290 | if (delta > p->max_match_value) | 288 | if (delta > p->max_match_value) |
291 | dev_warn(&p->pdev->dev, "delta out of range\n"); | 289 | dev_warn(&p->pdev->dev, "delta out of range\n"); |
292 | 290 | ||
293 | spin_lock_irqsave(&p->lock, flags); | ||
294 | p->next_match_value = delta; | 291 | p->next_match_value = delta; |
295 | sh_cmt_clock_event_program_verify(p, 0); | 292 | sh_cmt_clock_event_program_verify(p, 0); |
293 | } | ||
294 | |||
295 | static void sh_cmt_set_next(struct sh_cmt_priv *p, unsigned long delta) | ||
296 | { | ||
297 | unsigned long flags; | ||
298 | |||
299 | spin_lock_irqsave(&p->lock, flags); | ||
300 | __sh_cmt_set_next(p, delta); | ||
296 | spin_unlock_irqrestore(&p->lock, flags); | 301 | spin_unlock_irqrestore(&p->lock, flags); |
297 | } | 302 | } |
298 | 303 | ||
@@ -359,7 +364,7 @@ static int sh_cmt_start(struct sh_cmt_priv *p, unsigned long flag) | |||
359 | 364 | ||
360 | /* setup timeout if no clockevent */ | 365 | /* setup timeout if no clockevent */ |
361 | if ((flag == FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT))) | 366 | if ((flag == FLAG_CLOCKSOURCE) && (!(p->flags & FLAG_CLOCKEVENT))) |
362 | sh_cmt_set_next(p, p->max_match_value); | 367 | __sh_cmt_set_next(p, p->max_match_value); |
363 | out: | 368 | out: |
364 | spin_unlock_irqrestore(&p->lock, flags); | 369 | spin_unlock_irqrestore(&p->lock, flags); |
365 | 370 | ||
@@ -381,7 +386,7 @@ static void sh_cmt_stop(struct sh_cmt_priv *p, unsigned long flag) | |||
381 | 386 | ||
382 | /* adjust the timeout to maximum if only clocksource left */ | 387 | /* adjust the timeout to maximum if only clocksource left */ |
383 | if ((flag == FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE)) | 388 | if ((flag == FLAG_CLOCKEVENT) && (p->flags & FLAG_CLOCKSOURCE)) |
384 | sh_cmt_set_next(p, p->max_match_value); | 389 | __sh_cmt_set_next(p, p->max_match_value); |
385 | 390 | ||
386 | spin_unlock_irqrestore(&p->lock, flags); | 391 | spin_unlock_irqrestore(&p->lock, flags); |
387 | } | 392 | } |
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c index e16c3fa8d2e3..05117f1ad867 100644 --- a/drivers/connector/connector.c +++ b/drivers/connector/connector.c | |||
@@ -36,6 +36,7 @@ | |||
36 | MODULE_LICENSE("GPL"); | 36 | MODULE_LICENSE("GPL"); |
37 | MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); | 37 | MODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>"); |
38 | MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector."); | 38 | MODULE_DESCRIPTION("Generic userspace <-> kernelspace connector."); |
39 | MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_CONNECTOR); | ||
39 | 40 | ||
40 | static struct cn_dev cdev; | 41 | static struct cn_dev cdev; |
41 | 42 | ||
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index a8a84f4587f2..64b21f5cd740 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile | |||
@@ -1,8 +1,8 @@ | |||
1 | ifeq ($(CONFIG_DMADEVICES_DEBUG),y) | 1 | ifeq ($(CONFIG_DMADEVICES_DEBUG),y) |
2 | EXTRA_CFLAGS += -DDEBUG | 2 | ccflags-y += -DDEBUG |
3 | endif | 3 | endif |
4 | ifeq ($(CONFIG_DMADEVICES_VDEBUG),y) | 4 | ifeq ($(CONFIG_DMADEVICES_VDEBUG),y) |
5 | EXTRA_CFLAGS += -DVERBOSE_DEBUG | 5 | ccflags-y += -DVERBOSE_DEBUG |
6 | endif | 6 | endif |
7 | 7 | ||
8 | obj-$(CONFIG_DMA_ENGINE) += dmaengine.o | 8 | obj-$(CONFIG_DMA_ENGINE) += dmaengine.o |
diff --git a/drivers/dma/at_hdmac.c b/drivers/dma/at_hdmac.c index a0f3e6a06e06..ea0ee81cff53 100644 --- a/drivers/dma/at_hdmac.c +++ b/drivers/dma/at_hdmac.c | |||
@@ -722,7 +722,7 @@ atc_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, | |||
722 | desc->lli.daddr = mem; | 722 | desc->lli.daddr = mem; |
723 | desc->lli.ctrla = ctrla | 723 | desc->lli.ctrla = ctrla |
724 | | ATC_DST_WIDTH(mem_width) | 724 | | ATC_DST_WIDTH(mem_width) |
725 | | len >> mem_width; | 725 | | len >> reg_width; |
726 | desc->lli.ctrlb = ctrlb; | 726 | desc->lli.ctrlb = ctrlb; |
727 | 727 | ||
728 | if (!first) { | 728 | if (!first) { |
diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 286c3ac6bdcc..e5e172d21692 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c | |||
@@ -50,9 +50,11 @@ static void dma_init(struct fsldma_chan *chan) | |||
50 | * EIE - Error interrupt enable | 50 | * EIE - Error interrupt enable |
51 | * EOSIE - End of segments interrupt enable (basic mode) | 51 | * EOSIE - End of segments interrupt enable (basic mode) |
52 | * EOLNIE - End of links interrupt enable | 52 | * EOLNIE - End of links interrupt enable |
53 | * BWC - Bandwidth sharing among channels | ||
53 | */ | 54 | */ |
54 | DMA_OUT(chan, &chan->regs->mr, FSL_DMA_MR_EIE | 55 | DMA_OUT(chan, &chan->regs->mr, FSL_DMA_MR_BWC |
55 | | FSL_DMA_MR_EOLNIE | FSL_DMA_MR_EOSIE, 32); | 56 | | FSL_DMA_MR_EIE | FSL_DMA_MR_EOLNIE |
57 | | FSL_DMA_MR_EOSIE, 32); | ||
56 | break; | 58 | break; |
57 | case FSL_DMA_IP_83XX: | 59 | case FSL_DMA_IP_83XX: |
58 | /* Set the channel to below modes: | 60 | /* Set the channel to below modes: |
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h index cb4d6ff51597..ba9f403c0fbe 100644 --- a/drivers/dma/fsldma.h +++ b/drivers/dma/fsldma.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved. | 2 | * Copyright (C) 2007-2010 Freescale Semiconductor, Inc. All rights reserved. |
3 | * | 3 | * |
4 | * Author: | 4 | * Author: |
5 | * Zhang Wei <wei.zhang@freescale.com>, Jul 2007 | 5 | * Zhang Wei <wei.zhang@freescale.com>, Jul 2007 |
@@ -36,6 +36,13 @@ | |||
36 | #define FSL_DMA_MR_DAHE 0x00002000 | 36 | #define FSL_DMA_MR_DAHE 0x00002000 |
37 | #define FSL_DMA_MR_SAHE 0x00001000 | 37 | #define FSL_DMA_MR_SAHE 0x00001000 |
38 | 38 | ||
39 | /* | ||
40 | * Bandwidth/pause control determines how many bytes a given | ||
41 | * channel is allowed to transfer before the DMA engine pauses | ||
42 | * the current channel and switches to the next channel | ||
43 | */ | ||
44 | #define FSL_DMA_MR_BWC 0x08000000 | ||
45 | |||
39 | /* Special MR definition for MPC8349 */ | 46 | /* Special MR definition for MPC8349 */ |
40 | #define FSL_DMA_MR_EOTIE 0x00000080 | 47 | #define FSL_DMA_MR_EOTIE 0x00000080 |
41 | #define FSL_DMA_MR_PRC_RM 0x00000800 | 48 | #define FSL_DMA_MR_PRC_RM 0x00000800 |
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index f629e4961af5..e53d438142bb 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c | |||
@@ -379,7 +379,7 @@ static int __init imxdma_probe(struct platform_device *pdev) | |||
379 | return 0; | 379 | return 0; |
380 | 380 | ||
381 | err_init: | 381 | err_init: |
382 | while (i-- >= 0) { | 382 | while (--i >= 0) { |
383 | struct imxdma_channel *imxdmac = &imxdma->channel[i]; | 383 | struct imxdma_channel *imxdmac = &imxdma->channel[i]; |
384 | imx_dma_free(imxdmac->imxdma_channel); | 384 | imx_dma_free(imxdmac->imxdma_channel); |
385 | } | 385 | } |
diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c index 0834323a0599..d0602dd5d1b2 100644 --- a/drivers/dma/imx-sdma.c +++ b/drivers/dma/imx-sdma.c | |||
@@ -951,7 +951,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg( | |||
951 | struct sdma_buffer_descriptor *bd = &sdmac->bd[i]; | 951 | struct sdma_buffer_descriptor *bd = &sdmac->bd[i]; |
952 | int param; | 952 | int param; |
953 | 953 | ||
954 | bd->buffer_addr = sgl->dma_address; | 954 | bd->buffer_addr = sg->dma_address; |
955 | 955 | ||
956 | count = sg->length; | 956 | count = sg->length; |
957 | 957 | ||
@@ -1385,7 +1385,7 @@ static int __init sdma_module_init(void) | |||
1385 | { | 1385 | { |
1386 | return platform_driver_probe(&sdma_driver, sdma_probe); | 1386 | return platform_driver_probe(&sdma_driver, sdma_probe); |
1387 | } | 1387 | } |
1388 | subsys_initcall(sdma_module_init); | 1388 | module_init(sdma_module_init); |
1389 | 1389 | ||
1390 | MODULE_AUTHOR("Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>"); | 1390 | MODULE_AUTHOR("Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>"); |
1391 | MODULE_DESCRIPTION("i.MX SDMA driver"); | 1391 | MODULE_DESCRIPTION("i.MX SDMA driver"); |
diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c index 338bc4eed1f3..3109bd94bc4f 100644 --- a/drivers/dma/intel_mid_dma.c +++ b/drivers/dma/intel_mid_dma.c | |||
@@ -1075,7 +1075,6 @@ static int mid_setup_dma(struct pci_dev *pdev) | |||
1075 | if (NULL == dma->dma_pool) { | 1075 | if (NULL == dma->dma_pool) { |
1076 | pr_err("ERR_MDMA:pci_pool_create failed\n"); | 1076 | pr_err("ERR_MDMA:pci_pool_create failed\n"); |
1077 | err = -ENOMEM; | 1077 | err = -ENOMEM; |
1078 | kfree(dma); | ||
1079 | goto err_dma_pool; | 1078 | goto err_dma_pool; |
1080 | } | 1079 | } |
1081 | 1080 | ||
@@ -1186,7 +1185,6 @@ err_engine: | |||
1186 | free_irq(pdev->irq, dma); | 1185 | free_irq(pdev->irq, dma); |
1187 | err_irq: | 1186 | err_irq: |
1188 | pci_pool_destroy(dma->dma_pool); | 1187 | pci_pool_destroy(dma->dma_pool); |
1189 | kfree(dma); | ||
1190 | err_dma_pool: | 1188 | err_dma_pool: |
1191 | pr_err("ERR_MDMA:setup_dma failed: %d\n", err); | 1189 | pr_err("ERR_MDMA:setup_dma failed: %d\n", err); |
1192 | return err; | 1190 | return err; |
@@ -1413,7 +1411,7 @@ static const struct dev_pm_ops intel_mid_dma_pm = { | |||
1413 | .runtime_idle = dma_runtime_idle, | 1411 | .runtime_idle = dma_runtime_idle, |
1414 | }; | 1412 | }; |
1415 | 1413 | ||
1416 | static struct pci_driver intel_mid_dma_pci = { | 1414 | static struct pci_driver intel_mid_dma_pci_driver = { |
1417 | .name = "Intel MID DMA", | 1415 | .name = "Intel MID DMA", |
1418 | .id_table = intel_mid_dma_ids, | 1416 | .id_table = intel_mid_dma_ids, |
1419 | .probe = intel_mid_dma_probe, | 1417 | .probe = intel_mid_dma_probe, |
@@ -1431,13 +1429,13 @@ static int __init intel_mid_dma_init(void) | |||
1431 | { | 1429 | { |
1432 | pr_debug("INFO_MDMA: LNW DMA Driver Version %s\n", | 1430 | pr_debug("INFO_MDMA: LNW DMA Driver Version %s\n", |
1433 | INTEL_MID_DMA_DRIVER_VERSION); | 1431 | INTEL_MID_DMA_DRIVER_VERSION); |
1434 | return pci_register_driver(&intel_mid_dma_pci); | 1432 | return pci_register_driver(&intel_mid_dma_pci_driver); |
1435 | } | 1433 | } |
1436 | fs_initcall(intel_mid_dma_init); | 1434 | fs_initcall(intel_mid_dma_init); |
1437 | 1435 | ||
1438 | static void __exit intel_mid_dma_exit(void) | 1436 | static void __exit intel_mid_dma_exit(void) |
1439 | { | 1437 | { |
1440 | pci_unregister_driver(&intel_mid_dma_pci); | 1438 | pci_unregister_driver(&intel_mid_dma_pci_driver); |
1441 | } | 1439 | } |
1442 | module_exit(intel_mid_dma_exit); | 1440 | module_exit(intel_mid_dma_exit); |
1443 | 1441 | ||
diff --git a/drivers/dma/ioat/Makefile b/drivers/dma/ioat/Makefile index 8997d3fb9051..0ff7270af25b 100644 --- a/drivers/dma/ioat/Makefile +++ b/drivers/dma/ioat/Makefile | |||
@@ -1,2 +1,2 @@ | |||
1 | obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o | 1 | obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o |
2 | ioatdma-objs := pci.o dma.o dma_v2.o dma_v3.o dca.o | 2 | ioatdma-y := pci.o dma.o dma_v2.o dma_v3.o dca.o |
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 411d5bf50fc4..a25f5f61e0e0 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c | |||
@@ -449,7 +449,7 @@ mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan) | |||
449 | static void mv_xor_tasklet(unsigned long data) | 449 | static void mv_xor_tasklet(unsigned long data) |
450 | { | 450 | { |
451 | struct mv_xor_chan *chan = (struct mv_xor_chan *) data; | 451 | struct mv_xor_chan *chan = (struct mv_xor_chan *) data; |
452 | __mv_xor_slot_cleanup(chan); | 452 | mv_xor_slot_cleanup(chan); |
453 | } | 453 | } |
454 | 454 | ||
455 | static struct mv_xor_desc_slot * | 455 | static struct mv_xor_desc_slot * |
diff --git a/drivers/dma/pch_dma.c b/drivers/dma/pch_dma.c index 92b679024fed..c064c89420d0 100644 --- a/drivers/dma/pch_dma.c +++ b/drivers/dma/pch_dma.c | |||
@@ -259,11 +259,6 @@ static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc) | |||
259 | return; | 259 | return; |
260 | } | 260 | } |
261 | 261 | ||
262 | channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr); | ||
263 | channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr); | ||
264 | channel_writel(pd_chan, SIZE, desc->regs.size); | ||
265 | channel_writel(pd_chan, NEXT, desc->regs.next); | ||
266 | |||
267 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> dev_addr: %x\n", | 262 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> dev_addr: %x\n", |
268 | pd_chan->chan.chan_id, desc->regs.dev_addr); | 263 | pd_chan->chan.chan_id, desc->regs.dev_addr); |
269 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> mem_addr: %x\n", | 264 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> mem_addr: %x\n", |
@@ -273,10 +268,16 @@ static void pdc_dostart(struct pch_dma_chan *pd_chan, struct pch_dma_desc* desc) | |||
273 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> next: %x\n", | 268 | dev_dbg(chan2dev(&pd_chan->chan), "chan %d -> next: %x\n", |
274 | pd_chan->chan.chan_id, desc->regs.next); | 269 | pd_chan->chan.chan_id, desc->regs.next); |
275 | 270 | ||
276 | if (list_empty(&desc->tx_list)) | 271 | if (list_empty(&desc->tx_list)) { |
272 | channel_writel(pd_chan, DEV_ADDR, desc->regs.dev_addr); | ||
273 | channel_writel(pd_chan, MEM_ADDR, desc->regs.mem_addr); | ||
274 | channel_writel(pd_chan, SIZE, desc->regs.size); | ||
275 | channel_writel(pd_chan, NEXT, desc->regs.next); | ||
277 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_ONESHOT); | 276 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_ONESHOT); |
278 | else | 277 | } else { |
278 | channel_writel(pd_chan, NEXT, desc->txd.phys); | ||
279 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_SG); | 279 | pdc_set_mode(&pd_chan->chan, DMA_CTL0_SG); |
280 | } | ||
280 | 281 | ||
281 | val = dma_readl(pd, CTL2); | 282 | val = dma_readl(pd, CTL2); |
282 | val |= 1 << (DMA_CTL2_START_SHIFT_BITS + pd_chan->chan.chan_id); | 283 | val |= 1 << (DMA_CTL2_START_SHIFT_BITS + pd_chan->chan.chan_id); |
diff --git a/drivers/dma/ppc4xx/adma.c b/drivers/dma/ppc4xx/adma.c index 0d58a4a4487f..cef584533ee8 100644 --- a/drivers/dma/ppc4xx/adma.c +++ b/drivers/dma/ppc4xx/adma.c | |||
@@ -4449,9 +4449,8 @@ static int __devinit ppc440spe_adma_probe(struct platform_device *ofdev, | |||
4449 | 4449 | ||
4450 | if (!request_mem_region(res.start, resource_size(&res), | 4450 | if (!request_mem_region(res.start, resource_size(&res), |
4451 | dev_driver_string(&ofdev->dev))) { | 4451 | dev_driver_string(&ofdev->dev))) { |
4452 | dev_err(&ofdev->dev, "failed to request memory region " | 4452 | dev_err(&ofdev->dev, "failed to request memory region %pR\n", |
4453 | "(0x%016llx-0x%016llx)\n", | 4453 | &res); |
4454 | (u64)res.start, (u64)res.end); | ||
4455 | initcode = PPC_ADMA_INIT_MEMREG; | 4454 | initcode = PPC_ADMA_INIT_MEMREG; |
4456 | ret = -EBUSY; | 4455 | ret = -EBUSY; |
4457 | goto out; | 4456 | goto out; |
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c index 8521401bbd75..eca9ba193e94 100644 --- a/drivers/edac/amd64_edac.c +++ b/drivers/edac/amd64_edac.c | |||
@@ -1572,7 +1572,7 @@ static int f10_match_to_this_node(struct amd64_pvt *pvt, int dram_range, | |||
1572 | debugf1(" HoleOffset=0x%x HoleValid=0x%x IntlvSel=0x%x\n", | 1572 | debugf1(" HoleOffset=0x%x HoleValid=0x%x IntlvSel=0x%x\n", |
1573 | hole_off, hole_valid, intlv_sel); | 1573 | hole_off, hole_valid, intlv_sel); |
1574 | 1574 | ||
1575 | if (intlv_en || | 1575 | if (intlv_en && |
1576 | (intlv_sel != ((sys_addr >> 12) & intlv_en))) | 1576 | (intlv_sel != ((sys_addr >> 12) & intlv_en))) |
1577 | return -EINVAL; | 1577 | return -EINVAL; |
1578 | 1578 | ||
diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h index d7ca43a828bd..251440cd50a3 100644 --- a/drivers/edac/edac_core.h +++ b/drivers/edac/edac_core.h | |||
@@ -41,10 +41,10 @@ | |||
41 | #define MC_PROC_NAME_MAX_LEN 7 | 41 | #define MC_PROC_NAME_MAX_LEN 7 |
42 | 42 | ||
43 | #if PAGE_SHIFT < 20 | 43 | #if PAGE_SHIFT < 20 |
44 | #define PAGES_TO_MiB( pages ) ( ( pages ) >> ( 20 - PAGE_SHIFT ) ) | 44 | #define PAGES_TO_MiB(pages) ((pages) >> (20 - PAGE_SHIFT)) |
45 | #define MiB_TO_PAGES(mb) ((mb) >> (20 - PAGE_SHIFT)) | 45 | #define MiB_TO_PAGES(mb) ((mb) << (20 - PAGE_SHIFT)) |
46 | #else /* PAGE_SHIFT > 20 */ | 46 | #else /* PAGE_SHIFT > 20 */ |
47 | #define PAGES_TO_MiB( pages ) ( ( pages ) << ( PAGE_SHIFT - 20 ) ) | 47 | #define PAGES_TO_MiB(pages) ((pages) << (PAGE_SHIFT - 20)) |
48 | #define MiB_TO_PAGES(mb) ((mb) >> (PAGE_SHIFT - 20)) | 48 | #define MiB_TO_PAGES(mb) ((mb) >> (PAGE_SHIFT - 20)) |
49 | #endif | 49 | #endif |
50 | 50 | ||
diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index ba6586a69ccc..795ea69c4d8f 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c | |||
@@ -586,14 +586,16 @@ struct mem_ctl_info *edac_mc_del_mc(struct device *dev) | |||
586 | return NULL; | 586 | return NULL; |
587 | } | 587 | } |
588 | 588 | ||
589 | /* marking MCI offline */ | ||
590 | mci->op_state = OP_OFFLINE; | ||
591 | |||
592 | del_mc_from_global_list(mci); | 589 | del_mc_from_global_list(mci); |
593 | mutex_unlock(&mem_ctls_mutex); | 590 | mutex_unlock(&mem_ctls_mutex); |
594 | 591 | ||
595 | /* flush workq processes and remove sysfs */ | 592 | /* flush workq processes */ |
596 | edac_mc_workq_teardown(mci); | 593 | edac_mc_workq_teardown(mci); |
594 | |||
595 | /* marking MCI offline */ | ||
596 | mci->op_state = OP_OFFLINE; | ||
597 | |||
598 | /* remove from sysfs */ | ||
597 | edac_remove_sysfs_mci_device(mci); | 599 | edac_remove_sysfs_mci_device(mci); |
598 | 600 | ||
599 | edac_printk(KERN_INFO, EDAC_MC, | 601 | edac_printk(KERN_INFO, EDAC_MC, |
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 84eb607d6c03..e3c8b60bd86b 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -242,6 +242,7 @@ static inline struct fw_ohci *fw_ohci(struct fw_card *card) | |||
242 | 242 | ||
243 | static char ohci_driver_name[] = KBUILD_MODNAME; | 243 | static char ohci_driver_name[] = KBUILD_MODNAME; |
244 | 244 | ||
245 | #define PCI_DEVICE_ID_AGERE_FW643 0x5901 | ||
245 | #define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380 | 246 | #define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380 |
246 | #define PCI_DEVICE_ID_TI_TSB12LV22 0x8009 | 247 | #define PCI_DEVICE_ID_TI_TSB12LV22 0x8009 |
247 | 248 | ||
@@ -253,18 +254,34 @@ static char ohci_driver_name[] = KBUILD_MODNAME; | |||
253 | 254 | ||
254 | /* In case of multiple matches in ohci_quirks[], only the first one is used. */ | 255 | /* In case of multiple matches in ohci_quirks[], only the first one is used. */ |
255 | static const struct { | 256 | static const struct { |
256 | unsigned short vendor, device, flags; | 257 | unsigned short vendor, device, revision, flags; |
257 | } ohci_quirks[] = { | 258 | } ohci_quirks[] = { |
258 | {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, QUIRK_CYCLE_TIMER | | 259 | {PCI_VENDOR_ID_AL, PCI_ANY_ID, PCI_ANY_ID, |
259 | QUIRK_RESET_PACKET | | 260 | QUIRK_CYCLE_TIMER}, |
260 | QUIRK_NO_1394A}, | 261 | |
261 | {PCI_VENDOR_ID_TI, PCI_ANY_ID, QUIRK_RESET_PACKET}, | 262 | {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, PCI_ANY_ID, |
262 | {PCI_VENDOR_ID_AL, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | 263 | QUIRK_BE_HEADERS}, |
263 | {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, QUIRK_NO_MSI}, | 264 | |
264 | {PCI_VENDOR_ID_NEC, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | 265 | {PCI_VENDOR_ID_ATT, PCI_DEVICE_ID_AGERE_FW643, 6, |
265 | {PCI_VENDOR_ID_VIA, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | 266 | QUIRK_NO_MSI}, |
266 | {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, QUIRK_CYCLE_TIMER}, | 267 | |
267 | {PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_FW, QUIRK_BE_HEADERS}, | 268 | {PCI_VENDOR_ID_JMICRON, PCI_DEVICE_ID_JMICRON_JMB38X_FW, PCI_ANY_ID, |
269 | QUIRK_NO_MSI}, | ||
270 | |||
271 | {PCI_VENDOR_ID_NEC, PCI_ANY_ID, PCI_ANY_ID, | ||
272 | QUIRK_CYCLE_TIMER}, | ||
273 | |||
274 | {PCI_VENDOR_ID_RICOH, PCI_ANY_ID, PCI_ANY_ID, | ||
275 | QUIRK_CYCLE_TIMER}, | ||
276 | |||
277 | {PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TSB12LV22, PCI_ANY_ID, | ||
278 | QUIRK_CYCLE_TIMER | QUIRK_RESET_PACKET | QUIRK_NO_1394A}, | ||
279 | |||
280 | {PCI_VENDOR_ID_TI, PCI_ANY_ID, PCI_ANY_ID, | ||
281 | QUIRK_RESET_PACKET}, | ||
282 | |||
283 | {PCI_VENDOR_ID_VIA, PCI_ANY_ID, PCI_ANY_ID, | ||
284 | QUIRK_CYCLE_TIMER | QUIRK_NO_MSI}, | ||
268 | }; | 285 | }; |
269 | 286 | ||
270 | /* This overrides anything that was found in ohci_quirks[]. */ | 287 | /* This overrides anything that was found in ohci_quirks[]. */ |
@@ -2927,9 +2944,11 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
2927 | } | 2944 | } |
2928 | 2945 | ||
2929 | for (i = 0; i < ARRAY_SIZE(ohci_quirks); i++) | 2946 | for (i = 0; i < ARRAY_SIZE(ohci_quirks); i++) |
2930 | if (ohci_quirks[i].vendor == dev->vendor && | 2947 | if ((ohci_quirks[i].vendor == dev->vendor) && |
2931 | (ohci_quirks[i].device == dev->device || | 2948 | (ohci_quirks[i].device == (unsigned short)PCI_ANY_ID || |
2932 | ohci_quirks[i].device == (unsigned short)PCI_ANY_ID)) { | 2949 | ohci_quirks[i].device == dev->device) && |
2950 | (ohci_quirks[i].revision == (unsigned short)PCI_ANY_ID || | ||
2951 | ohci_quirks[i].revision >= dev->revision)) { | ||
2933 | ohci->quirks = ohci_quirks[i].flags; | 2952 | ohci->quirks = ohci_quirks[i].flags; |
2934 | break; | 2953 | break; |
2935 | } | 2954 | } |
diff --git a/drivers/gpio/cs5535-gpio.c b/drivers/gpio/cs5535-gpio.c index 599f6c9e0fbf..d3e55a0ae92b 100644 --- a/drivers/gpio/cs5535-gpio.c +++ b/drivers/gpio/cs5535-gpio.c | |||
@@ -56,15 +56,26 @@ static struct cs5535_gpio_chip { | |||
56 | * registers, see include/linux/cs5535.h. | 56 | * registers, see include/linux/cs5535.h. |
57 | */ | 57 | */ |
58 | 58 | ||
59 | static void errata_outl(u32 val, unsigned long addr) | 59 | static void errata_outl(struct cs5535_gpio_chip *chip, u32 val, |
60 | unsigned int reg) | ||
60 | { | 61 | { |
62 | unsigned long addr = chip->base + 0x80 + reg; | ||
63 | |||
61 | /* | 64 | /* |
62 | * According to the CS5536 errata (#36), after suspend | 65 | * According to the CS5536 errata (#36), after suspend |
63 | * a write to the high bank GPIO register will clear all | 66 | * a write to the high bank GPIO register will clear all |
64 | * non-selected bits; the recommended workaround is a | 67 | * non-selected bits; the recommended workaround is a |
65 | * read-modify-write operation. | 68 | * read-modify-write operation. |
69 | * | ||
70 | * Don't apply this errata to the edge status GPIOs, as writing | ||
71 | * to their lower bits will clear them. | ||
66 | */ | 72 | */ |
67 | val |= inl(addr); | 73 | if (reg != GPIO_POSITIVE_EDGE_STS && reg != GPIO_NEGATIVE_EDGE_STS) { |
74 | if (val & 0xffff) | ||
75 | val |= (inl(addr) & 0xffff); /* ignore the high bits */ | ||
76 | else | ||
77 | val |= (inl(addr) ^ (val >> 16)); | ||
78 | } | ||
68 | outl(val, addr); | 79 | outl(val, addr); |
69 | } | 80 | } |
70 | 81 | ||
@@ -76,7 +87,7 @@ static void __cs5535_gpio_set(struct cs5535_gpio_chip *chip, unsigned offset, | |||
76 | outl(1 << offset, chip->base + reg); | 87 | outl(1 << offset, chip->base + reg); |
77 | else | 88 | else |
78 | /* high bank register */ | 89 | /* high bank register */ |
79 | errata_outl(1 << (offset - 16), chip->base + 0x80 + reg); | 90 | errata_outl(chip, 1 << (offset - 16), reg); |
80 | } | 91 | } |
81 | 92 | ||
82 | void cs5535_gpio_set(unsigned offset, unsigned int reg) | 93 | void cs5535_gpio_set(unsigned offset, unsigned int reg) |
@@ -98,7 +109,7 @@ static void __cs5535_gpio_clear(struct cs5535_gpio_chip *chip, unsigned offset, | |||
98 | outl(1 << (offset + 16), chip->base + reg); | 109 | outl(1 << (offset + 16), chip->base + reg); |
99 | else | 110 | else |
100 | /* high bank register */ | 111 | /* high bank register */ |
101 | errata_outl(1 << offset, chip->base + 0x80 + reg); | 112 | errata_outl(chip, 1 << offset, reg); |
102 | } | 113 | } |
103 | 114 | ||
104 | void cs5535_gpio_clear(unsigned offset, unsigned int reg) | 115 | void cs5535_gpio_clear(unsigned offset, unsigned int reg) |
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index 21da9c19a0cb..649550e2cae9 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c | |||
@@ -1281,6 +1281,9 @@ int gpio_request_one(unsigned gpio, unsigned long flags, const char *label) | |||
1281 | err = gpio_direction_output(gpio, | 1281 | err = gpio_direction_output(gpio, |
1282 | (flags & GPIOF_INIT_HIGH) ? 1 : 0); | 1282 | (flags & GPIOF_INIT_HIGH) ? 1 : 0); |
1283 | 1283 | ||
1284 | if (err) | ||
1285 | gpio_free(gpio); | ||
1286 | |||
1284 | return err; | 1287 | return err; |
1285 | } | 1288 | } |
1286 | EXPORT_SYMBOL_GPL(gpio_request_one); | 1289 | EXPORT_SYMBOL_GPL(gpio_request_one); |
diff --git a/drivers/gpio/rdc321x-gpio.c b/drivers/gpio/rdc321x-gpio.c index 2762698e0204..897e0577e65e 100644 --- a/drivers/gpio/rdc321x-gpio.c +++ b/drivers/gpio/rdc321x-gpio.c | |||
@@ -135,7 +135,7 @@ static int __devinit rdc321x_gpio_probe(struct platform_device *pdev) | |||
135 | struct rdc321x_gpio *rdc321x_gpio_dev; | 135 | struct rdc321x_gpio *rdc321x_gpio_dev; |
136 | struct rdc321x_gpio_pdata *pdata; | 136 | struct rdc321x_gpio_pdata *pdata; |
137 | 137 | ||
138 | pdata = pdev->dev.platform_data; | 138 | pdata = platform_get_drvdata(pdev); |
139 | if (!pdata) { | 139 | if (!pdata) { |
140 | dev_err(&pdev->dev, "no platform data supplied\n"); | 140 | dev_err(&pdev->dev, "no platform data supplied\n"); |
141 | return -ENODEV; | 141 | return -ENODEV; |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 6985cb1da72c..2baa6708e44c 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -156,12 +156,12 @@ static struct drm_conn_prop_enum_list drm_connector_enum_list[] = | |||
156 | { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 }, | 156 | { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 }, |
157 | { DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 }, | 157 | { DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 }, |
158 | { DRM_MODE_CONNECTOR_Component, "Component", 0 }, | 158 | { DRM_MODE_CONNECTOR_Component, "Component", 0 }, |
159 | { DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN", 0 }, | 159 | { DRM_MODE_CONNECTOR_9PinDIN, "DIN", 0 }, |
160 | { DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort", 0 }, | 160 | { DRM_MODE_CONNECTOR_DisplayPort, "DP", 0 }, |
161 | { DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 }, | 161 | { DRM_MODE_CONNECTOR_HDMIA, "HDMI-A", 0 }, |
162 | { DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 }, | 162 | { DRM_MODE_CONNECTOR_HDMIB, "HDMI-B", 0 }, |
163 | { DRM_MODE_CONNECTOR_TV, "TV", 0 }, | 163 | { DRM_MODE_CONNECTOR_TV, "TV", 0 }, |
164 | { DRM_MODE_CONNECTOR_eDP, "Embedded DisplayPort", 0 }, | 164 | { DRM_MODE_CONNECTOR_eDP, "eDP", 0 }, |
165 | }; | 165 | }; |
166 | 166 | ||
167 | static struct drm_prop_enum_list drm_encoder_enum_list[] = | 167 | static struct drm_prop_enum_list drm_encoder_enum_list[] = |
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 7ca59359fee2..2d4e17a004db 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -874,7 +874,10 @@ static void output_poll_execute(struct work_struct *work) | |||
874 | continue; | 874 | continue; |
875 | 875 | ||
876 | connector->status = connector->funcs->detect(connector, false); | 876 | connector->status = connector->funcs->detect(connector, false); |
877 | DRM_DEBUG_KMS("connector status updated to %d\n", connector->status); | 877 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n", |
878 | connector->base.id, | ||
879 | drm_get_connector_name(connector), | ||
880 | old_status, connector->status); | ||
878 | if (old_status != connector->status) | 881 | if (old_status != connector->status) |
879 | changed = true; | 882 | changed = true; |
880 | } | 883 | } |
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 9d3a5030b6e1..16d5155edad1 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c | |||
@@ -585,10 +585,13 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, | |||
585 | struct timeval now; | 585 | struct timeval now; |
586 | unsigned long flags; | 586 | unsigned long flags; |
587 | unsigned int seq; | 587 | unsigned int seq; |
588 | int ret; | ||
588 | 589 | ||
589 | e = kzalloc(sizeof *e, GFP_KERNEL); | 590 | e = kzalloc(sizeof *e, GFP_KERNEL); |
590 | if (e == NULL) | 591 | if (e == NULL) { |
591 | return -ENOMEM; | 592 | ret = -ENOMEM; |
593 | goto err_put; | ||
594 | } | ||
592 | 595 | ||
593 | e->pipe = pipe; | 596 | e->pipe = pipe; |
594 | e->base.pid = current->pid; | 597 | e->base.pid = current->pid; |
@@ -603,9 +606,8 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, | |||
603 | spin_lock_irqsave(&dev->event_lock, flags); | 606 | spin_lock_irqsave(&dev->event_lock, flags); |
604 | 607 | ||
605 | if (file_priv->event_space < sizeof e->event) { | 608 | if (file_priv->event_space < sizeof e->event) { |
606 | spin_unlock_irqrestore(&dev->event_lock, flags); | 609 | ret = -EBUSY; |
607 | kfree(e); | 610 | goto err_unlock; |
608 | return -ENOMEM; | ||
609 | } | 611 | } |
610 | 612 | ||
611 | file_priv->event_space -= sizeof e->event; | 613 | file_priv->event_space -= sizeof e->event; |
@@ -626,7 +628,7 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, | |||
626 | if ((seq - vblwait->request.sequence) <= (1 << 23)) { | 628 | if ((seq - vblwait->request.sequence) <= (1 << 23)) { |
627 | e->event.tv_sec = now.tv_sec; | 629 | e->event.tv_sec = now.tv_sec; |
628 | e->event.tv_usec = now.tv_usec; | 630 | e->event.tv_usec = now.tv_usec; |
629 | drm_vblank_put(dev, e->pipe); | 631 | drm_vblank_put(dev, pipe); |
630 | list_add_tail(&e->base.link, &e->base.file_priv->event_list); | 632 | list_add_tail(&e->base.link, &e->base.file_priv->event_list); |
631 | wake_up_interruptible(&e->base.file_priv->event_wait); | 633 | wake_up_interruptible(&e->base.file_priv->event_wait); |
632 | trace_drm_vblank_event_delivered(current->pid, pipe, | 634 | trace_drm_vblank_event_delivered(current->pid, pipe, |
@@ -638,6 +640,13 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, | |||
638 | spin_unlock_irqrestore(&dev->event_lock, flags); | 640 | spin_unlock_irqrestore(&dev->event_lock, flags); |
639 | 641 | ||
640 | return 0; | 642 | return 0; |
643 | |||
644 | err_unlock: | ||
645 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
646 | kfree(e); | ||
647 | err_put: | ||
648 | drm_vblank_put(dev, pipe); | ||
649 | return ret; | ||
641 | } | 650 | } |
642 | 651 | ||
643 | /** | 652 | /** |
diff --git a/drivers/gpu/drm/i915/dvo_ch7017.c b/drivers/gpu/drm/i915/dvo_ch7017.c index af70337567ce..d3e8c540f778 100644 --- a/drivers/gpu/drm/i915/dvo_ch7017.c +++ b/drivers/gpu/drm/i915/dvo_ch7017.c | |||
@@ -242,7 +242,7 @@ fail: | |||
242 | 242 | ||
243 | static enum drm_connector_status ch7017_detect(struct intel_dvo_device *dvo) | 243 | static enum drm_connector_status ch7017_detect(struct intel_dvo_device *dvo) |
244 | { | 244 | { |
245 | return connector_status_unknown; | 245 | return connector_status_connected; |
246 | } | 246 | } |
247 | 247 | ||
248 | static enum drm_mode_status ch7017_mode_valid(struct intel_dvo_device *dvo, | 248 | static enum drm_mode_status ch7017_mode_valid(struct intel_dvo_device *dvo, |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 7a26f4dd21ae..cb900dc83d95 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include "i915_drm.h" | 34 | #include "i915_drm.h" |
35 | #include "i915_drv.h" | 35 | #include "i915_drv.h" |
36 | #include "i915_trace.h" | 36 | #include "i915_trace.h" |
37 | #include "../../../platform/x86/intel_ips.h" | ||
37 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
38 | #include <linux/vgaarb.h> | 39 | #include <linux/vgaarb.h> |
39 | #include <linux/acpi.h> | 40 | #include <linux/acpi.h> |
@@ -767,6 +768,9 @@ static int i915_getparam(struct drm_device *dev, void *data, | |||
767 | case I915_PARAM_HAS_BLT: | 768 | case I915_PARAM_HAS_BLT: |
768 | value = HAS_BLT(dev); | 769 | value = HAS_BLT(dev); |
769 | break; | 770 | break; |
771 | case I915_PARAM_HAS_COHERENT_RINGS: | ||
772 | value = 1; | ||
773 | break; | ||
770 | default: | 774 | default: |
771 | DRM_DEBUG_DRIVER("Unknown parameter %d\n", | 775 | DRM_DEBUG_DRIVER("Unknown parameter %d\n", |
772 | param->param); | 776 | param->param); |
@@ -1868,6 +1872,26 @@ out_unlock: | |||
1868 | EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable); | 1872 | EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable); |
1869 | 1873 | ||
1870 | /** | 1874 | /** |
1875 | * Tells the intel_ips driver that the i915 driver is now loaded, if | ||
1876 | * IPS got loaded first. | ||
1877 | * | ||
1878 | * This awkward dance is so that neither module has to depend on the | ||
1879 | * other in order for IPS to do the appropriate communication of | ||
1880 | * GPU turbo limits to i915. | ||
1881 | */ | ||
1882 | static void | ||
1883 | ips_ping_for_i915_load(void) | ||
1884 | { | ||
1885 | void (*link)(void); | ||
1886 | |||
1887 | link = symbol_get(ips_link_to_i915_driver); | ||
1888 | if (link) { | ||
1889 | link(); | ||
1890 | symbol_put(ips_link_to_i915_driver); | ||
1891 | } | ||
1892 | } | ||
1893 | |||
1894 | /** | ||
1871 | * i915_driver_load - setup chip and create an initial config | 1895 | * i915_driver_load - setup chip and create an initial config |
1872 | * @dev: DRM device | 1896 | * @dev: DRM device |
1873 | * @flags: startup flags | 1897 | * @flags: startup flags |
@@ -2072,6 +2096,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2072 | dev_priv->mchdev_lock = &mchdev_lock; | 2096 | dev_priv->mchdev_lock = &mchdev_lock; |
2073 | spin_unlock(&mchdev_lock); | 2097 | spin_unlock(&mchdev_lock); |
2074 | 2098 | ||
2099 | ips_ping_for_i915_load(); | ||
2100 | |||
2075 | return 0; | 2101 | return 0; |
2076 | 2102 | ||
2077 | out_workqueue_free: | 2103 | out_workqueue_free: |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5e54821af996..275ec6ed43ae 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -4374,10 +4374,20 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
4374 | * use this buffer rather sooner than later, so issuing the required | 4374 | * use this buffer rather sooner than later, so issuing the required |
4375 | * flush earlier is beneficial. | 4375 | * flush earlier is beneficial. |
4376 | */ | 4376 | */ |
4377 | if (obj->write_domain & I915_GEM_GPU_DOMAINS) | 4377 | if (obj->write_domain & I915_GEM_GPU_DOMAINS) { |
4378 | i915_gem_flush_ring(dev, file_priv, | 4378 | i915_gem_flush_ring(dev, file_priv, |
4379 | obj_priv->ring, | 4379 | obj_priv->ring, |
4380 | 0, obj->write_domain); | 4380 | 0, obj->write_domain); |
4381 | } else if (obj_priv->ring->outstanding_lazy_request) { | ||
4382 | /* This ring is not being cleared by active usage, | ||
4383 | * so emit a request to do so. | ||
4384 | */ | ||
4385 | u32 seqno = i915_add_request(dev, | ||
4386 | NULL, NULL, | ||
4387 | obj_priv->ring); | ||
4388 | if (seqno == 0) | ||
4389 | ret = -ENOMEM; | ||
4390 | } | ||
4381 | 4391 | ||
4382 | /* Update the active list for the hardware's current position. | 4392 | /* Update the active list for the hardware's current position. |
4383 | * Otherwise this only updates on a delayed timer or when irqs | 4393 | * Otherwise this only updates on a delayed timer or when irqs |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 25ed911a3112..cb8f43429279 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -2471,6 +2471,9 @@ | |||
2471 | # define MARIUNIT_CLOCK_GATE_DISABLE (1 << 18) | 2471 | # define MARIUNIT_CLOCK_GATE_DISABLE (1 << 18) |
2472 | # define SVSMUNIT_CLOCK_GATE_DISABLE (1 << 1) | 2472 | # define SVSMUNIT_CLOCK_GATE_DISABLE (1 << 1) |
2473 | 2473 | ||
2474 | #define PCH_3DCGDIS1 0x46024 | ||
2475 | # define VFMUNIT_CLOCK_GATE_DISABLE (1 << 11) | ||
2476 | |||
2474 | #define FDI_PLL_FREQ_CTL 0x46030 | 2477 | #define FDI_PLL_FREQ_CTL 0x46030 |
2475 | #define FDI_PLL_FREQ_CHANGE_REQUEST (1<<24) | 2478 | #define FDI_PLL_FREQ_CHANGE_REQUEST (1<<24) |
2476 | #define FDI_PLL_FREQ_LOCK_LIMIT_MASK 0xfff00 | 2479 | #define FDI_PLL_FREQ_LOCK_LIMIT_MASK 0xfff00 |
@@ -2588,6 +2591,13 @@ | |||
2588 | #define ILK_DISPLAY_CHICKEN2 0x42004 | 2591 | #define ILK_DISPLAY_CHICKEN2 0x42004 |
2589 | #define ILK_DPARB_GATE (1<<22) | 2592 | #define ILK_DPARB_GATE (1<<22) |
2590 | #define ILK_VSDPFD_FULL (1<<21) | 2593 | #define ILK_VSDPFD_FULL (1<<21) |
2594 | #define ILK_DISPLAY_CHICKEN_FUSES 0x42014 | ||
2595 | #define ILK_INTERNAL_GRAPHICS_DISABLE (1<<31) | ||
2596 | #define ILK_INTERNAL_DISPLAY_DISABLE (1<<30) | ||
2597 | #define ILK_DISPLAY_DEBUG_DISABLE (1<<29) | ||
2598 | #define ILK_HDCP_DISABLE (1<<25) | ||
2599 | #define ILK_eDP_A_DISABLE (1<<24) | ||
2600 | #define ILK_DESKTOP (1<<23) | ||
2591 | #define ILK_DSPCLK_GATE 0x42020 | 2601 | #define ILK_DSPCLK_GATE 0x42020 |
2592 | #define ILK_DPARB_CLK_GATE (1<<5) | 2602 | #define ILK_DPARB_CLK_GATE (1<<5) |
2593 | /* According to spec this bit 7/8/9 of 0x42020 should be set to enable FBC */ | 2603 | /* According to spec this bit 7/8/9 of 0x42020 should be set to enable FBC */ |
@@ -3033,6 +3043,7 @@ | |||
3033 | #define TRANS_DP_10BPC (1<<9) | 3043 | #define TRANS_DP_10BPC (1<<9) |
3034 | #define TRANS_DP_6BPC (2<<9) | 3044 | #define TRANS_DP_6BPC (2<<9) |
3035 | #define TRANS_DP_12BPC (3<<9) | 3045 | #define TRANS_DP_12BPC (3<<9) |
3046 | #define TRANS_DP_BPC_MASK (3<<9) | ||
3036 | #define TRANS_DP_VSYNC_ACTIVE_HIGH (1<<4) | 3047 | #define TRANS_DP_VSYNC_ACTIVE_HIGH (1<<4) |
3037 | #define TRANS_DP_VSYNC_ACTIVE_LOW 0 | 3048 | #define TRANS_DP_VSYNC_ACTIVE_LOW 0 |
3038 | #define TRANS_DP_HSYNC_ACTIVE_HIGH (1<<3) | 3049 | #define TRANS_DP_HSYNC_ACTIVE_HIGH (1<<3) |
diff --git a/drivers/gpu/drm/i915/intel_acpi.c b/drivers/gpu/drm/i915/intel_acpi.c index 65c88f9ba12c..2cb8e0b9f1ee 100644 --- a/drivers/gpu/drm/i915/intel_acpi.c +++ b/drivers/gpu/drm/i915/intel_acpi.c | |||
@@ -190,37 +190,6 @@ out: | |||
190 | kfree(output.pointer); | 190 | kfree(output.pointer); |
191 | } | 191 | } |
192 | 192 | ||
193 | static int intel_dsm_switchto(enum vga_switcheroo_client_id id) | ||
194 | { | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static int intel_dsm_power_state(enum vga_switcheroo_client_id id, | ||
199 | enum vga_switcheroo_state state) | ||
200 | { | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static int intel_dsm_init(void) | ||
205 | { | ||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | static int intel_dsm_get_client_id(struct pci_dev *pdev) | ||
210 | { | ||
211 | if (intel_dsm_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev)) | ||
212 | return VGA_SWITCHEROO_IGD; | ||
213 | else | ||
214 | return VGA_SWITCHEROO_DIS; | ||
215 | } | ||
216 | |||
217 | static struct vga_switcheroo_handler intel_dsm_handler = { | ||
218 | .switchto = intel_dsm_switchto, | ||
219 | .power_state = intel_dsm_power_state, | ||
220 | .init = intel_dsm_init, | ||
221 | .get_client_id = intel_dsm_get_client_id, | ||
222 | }; | ||
223 | |||
224 | static bool intel_dsm_pci_probe(struct pci_dev *pdev) | 193 | static bool intel_dsm_pci_probe(struct pci_dev *pdev) |
225 | { | 194 | { |
226 | acpi_handle dhandle, intel_handle; | 195 | acpi_handle dhandle, intel_handle; |
@@ -276,11 +245,8 @@ void intel_register_dsm_handler(void) | |||
276 | { | 245 | { |
277 | if (!intel_dsm_detect()) | 246 | if (!intel_dsm_detect()) |
278 | return; | 247 | return; |
279 | |||
280 | vga_switcheroo_register_handler(&intel_dsm_handler); | ||
281 | } | 248 | } |
282 | 249 | ||
283 | void intel_unregister_dsm_handler(void) | 250 | void intel_unregister_dsm_handler(void) |
284 | { | 251 | { |
285 | vga_switcheroo_unregister_handler(); | ||
286 | } | 252 | } |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 255b52ee0091..fca523288aca 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -2120,9 +2120,11 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc) | |||
2120 | reg = TRANS_DP_CTL(pipe); | 2120 | reg = TRANS_DP_CTL(pipe); |
2121 | temp = I915_READ(reg); | 2121 | temp = I915_READ(reg); |
2122 | temp &= ~(TRANS_DP_PORT_SEL_MASK | | 2122 | temp &= ~(TRANS_DP_PORT_SEL_MASK | |
2123 | TRANS_DP_SYNC_MASK); | 2123 | TRANS_DP_SYNC_MASK | |
2124 | TRANS_DP_BPC_MASK); | ||
2124 | temp |= (TRANS_DP_OUTPUT_ENABLE | | 2125 | temp |= (TRANS_DP_OUTPUT_ENABLE | |
2125 | TRANS_DP_ENH_FRAMING); | 2126 | TRANS_DP_ENH_FRAMING); |
2127 | temp |= TRANS_DP_8BPC; | ||
2126 | 2128 | ||
2127 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) | 2129 | if (crtc->mode.flags & DRM_MODE_FLAG_PHSYNC) |
2128 | temp |= TRANS_DP_HSYNC_ACTIVE_HIGH; | 2130 | temp |= TRANS_DP_HSYNC_ACTIVE_HIGH; |
@@ -2712,27 +2714,19 @@ fdi_reduce_ratio(u32 *num, u32 *den) | |||
2712 | } | 2714 | } |
2713 | } | 2715 | } |
2714 | 2716 | ||
2715 | #define DATA_N 0x800000 | ||
2716 | #define LINK_N 0x80000 | ||
2717 | |||
2718 | static void | 2717 | static void |
2719 | ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock, | 2718 | ironlake_compute_m_n(int bits_per_pixel, int nlanes, int pixel_clock, |
2720 | int link_clock, struct fdi_m_n *m_n) | 2719 | int link_clock, struct fdi_m_n *m_n) |
2721 | { | 2720 | { |
2722 | u64 temp; | ||
2723 | |||
2724 | m_n->tu = 64; /* default size */ | 2721 | m_n->tu = 64; /* default size */ |
2725 | 2722 | ||
2726 | temp = (u64) DATA_N * pixel_clock; | 2723 | /* BUG_ON(pixel_clock > INT_MAX / 36); */ |
2727 | temp = div_u64(temp, link_clock); | 2724 | m_n->gmch_m = bits_per_pixel * pixel_clock; |
2728 | m_n->gmch_m = div_u64(temp * bits_per_pixel, nlanes); | 2725 | m_n->gmch_n = link_clock * nlanes * 8; |
2729 | m_n->gmch_m >>= 3; /* convert to bytes_per_pixel */ | ||
2730 | m_n->gmch_n = DATA_N; | ||
2731 | fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); | 2726 | fdi_reduce_ratio(&m_n->gmch_m, &m_n->gmch_n); |
2732 | 2727 | ||
2733 | temp = (u64) LINK_N * pixel_clock; | 2728 | m_n->link_m = pixel_clock; |
2734 | m_n->link_m = div_u64(temp, link_clock); | 2729 | m_n->link_n = link_clock; |
2735 | m_n->link_n = LINK_N; | ||
2736 | fdi_reduce_ratio(&m_n->link_m, &m_n->link_n); | 2730 | fdi_reduce_ratio(&m_n->link_m, &m_n->link_n); |
2737 | } | 2731 | } |
2738 | 2732 | ||
@@ -3716,6 +3710,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3716 | 3710 | ||
3717 | /* FDI link */ | 3711 | /* FDI link */ |
3718 | if (HAS_PCH_SPLIT(dev)) { | 3712 | if (HAS_PCH_SPLIT(dev)) { |
3713 | int pixel_multiplier = intel_mode_get_pixel_multiplier(adjusted_mode); | ||
3719 | int lane = 0, link_bw, bpp; | 3714 | int lane = 0, link_bw, bpp; |
3720 | /* CPU eDP doesn't require FDI link, so just set DP M/N | 3715 | /* CPU eDP doesn't require FDI link, so just set DP M/N |
3721 | according to current link config */ | 3716 | according to current link config */ |
@@ -3799,6 +3794,8 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, | |||
3799 | 3794 | ||
3800 | intel_crtc->fdi_lanes = lane; | 3795 | intel_crtc->fdi_lanes = lane; |
3801 | 3796 | ||
3797 | if (pixel_multiplier > 1) | ||
3798 | link_bw *= pixel_multiplier; | ||
3802 | ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n); | 3799 | ironlake_compute_m_n(bpp, lane, target_clock, link_bw, &m_n); |
3803 | } | 3800 | } |
3804 | 3801 | ||
@@ -5236,6 +5233,55 @@ static const struct drm_crtc_funcs intel_crtc_funcs = { | |||
5236 | .page_flip = intel_crtc_page_flip, | 5233 | .page_flip = intel_crtc_page_flip, |
5237 | }; | 5234 | }; |
5238 | 5235 | ||
5236 | static void intel_sanitize_modesetting(struct drm_device *dev, | ||
5237 | int pipe, int plane) | ||
5238 | { | ||
5239 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5240 | u32 reg, val; | ||
5241 | |||
5242 | if (HAS_PCH_SPLIT(dev)) | ||
5243 | return; | ||
5244 | |||
5245 | /* Who knows what state these registers were left in by the BIOS or | ||
5246 | * grub? | ||
5247 | * | ||
5248 | * If we leave the registers in a conflicting state (e.g. with the | ||
5249 | * display plane reading from the other pipe than the one we intend | ||
5250 | * to use) then when we attempt to teardown the active mode, we will | ||
5251 | * not disable the pipes and planes in the correct order -- leaving | ||
5252 | * a plane reading from a disabled pipe and possibly leading to | ||
5253 | * undefined behaviour. | ||
5254 | */ | ||
5255 | |||
5256 | reg = DSPCNTR(plane); | ||
5257 | val = I915_READ(reg); | ||
5258 | |||
5259 | if ((val & DISPLAY_PLANE_ENABLE) == 0) | ||
5260 | return; | ||
5261 | if (!!(val & DISPPLANE_SEL_PIPE_MASK) == pipe) | ||
5262 | return; | ||
5263 | |||
5264 | /* This display plane is active and attached to the other CPU pipe. */ | ||
5265 | pipe = !pipe; | ||
5266 | |||
5267 | /* Disable the plane and wait for it to stop reading from the pipe. */ | ||
5268 | I915_WRITE(reg, val & ~DISPLAY_PLANE_ENABLE); | ||
5269 | intel_flush_display_plane(dev, plane); | ||
5270 | |||
5271 | if (IS_GEN2(dev)) | ||
5272 | intel_wait_for_vblank(dev, pipe); | ||
5273 | |||
5274 | if (pipe == 0 && (dev_priv->quirks & QUIRK_PIPEA_FORCE)) | ||
5275 | return; | ||
5276 | |||
5277 | /* Switch off the pipe. */ | ||
5278 | reg = PIPECONF(pipe); | ||
5279 | val = I915_READ(reg); | ||
5280 | if (val & PIPECONF_ENABLE) { | ||
5281 | I915_WRITE(reg, val & ~PIPECONF_ENABLE); | ||
5282 | intel_wait_for_pipe_off(dev, pipe); | ||
5283 | } | ||
5284 | } | ||
5239 | 5285 | ||
5240 | static void intel_crtc_init(struct drm_device *dev, int pipe) | 5286 | static void intel_crtc_init(struct drm_device *dev, int pipe) |
5241 | { | 5287 | { |
@@ -5287,6 +5333,8 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) | |||
5287 | 5333 | ||
5288 | setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, | 5334 | setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, |
5289 | (unsigned long)intel_crtc); | 5335 | (unsigned long)intel_crtc); |
5336 | |||
5337 | intel_sanitize_modesetting(dev, intel_crtc->pipe, intel_crtc->plane); | ||
5290 | } | 5338 | } |
5291 | 5339 | ||
5292 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | 5340 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
@@ -5331,6 +5379,23 @@ static int intel_encoder_clones(struct drm_device *dev, int type_mask) | |||
5331 | return index_mask; | 5379 | return index_mask; |
5332 | } | 5380 | } |
5333 | 5381 | ||
5382 | static bool has_edp_a(struct drm_device *dev) | ||
5383 | { | ||
5384 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
5385 | |||
5386 | if (!IS_MOBILE(dev)) | ||
5387 | return false; | ||
5388 | |||
5389 | if ((I915_READ(DP_A) & DP_DETECTED) == 0) | ||
5390 | return false; | ||
5391 | |||
5392 | if (IS_GEN5(dev) && | ||
5393 | (I915_READ(ILK_DISPLAY_CHICKEN_FUSES) & ILK_eDP_A_DISABLE)) | ||
5394 | return false; | ||
5395 | |||
5396 | return true; | ||
5397 | } | ||
5398 | |||
5334 | static void intel_setup_outputs(struct drm_device *dev) | 5399 | static void intel_setup_outputs(struct drm_device *dev) |
5335 | { | 5400 | { |
5336 | struct drm_i915_private *dev_priv = dev->dev_private; | 5401 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -5348,7 +5413,7 @@ static void intel_setup_outputs(struct drm_device *dev) | |||
5348 | if (HAS_PCH_SPLIT(dev)) { | 5413 | if (HAS_PCH_SPLIT(dev)) { |
5349 | dpd_is_edp = intel_dpd_is_edp(dev); | 5414 | dpd_is_edp = intel_dpd_is_edp(dev); |
5350 | 5415 | ||
5351 | if (IS_MOBILE(dev) && (I915_READ(DP_A) & DP_DETECTED)) | 5416 | if (has_edp_a(dev)) |
5352 | intel_dp_init(dev, DP_A); | 5417 | intel_dp_init(dev, DP_A); |
5353 | 5418 | ||
5354 | if (dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED)) | 5419 | if (dpd_is_edp && (I915_READ(PCH_DP_D) & DP_DETECTED)) |
@@ -5777,6 +5842,8 @@ void intel_init_clock_gating(struct drm_device *dev) | |||
5777 | I915_WRITE(PCH_3DCGDIS0, | 5842 | I915_WRITE(PCH_3DCGDIS0, |
5778 | MARIUNIT_CLOCK_GATE_DISABLE | | 5843 | MARIUNIT_CLOCK_GATE_DISABLE | |
5779 | SVSMUNIT_CLOCK_GATE_DISABLE); | 5844 | SVSMUNIT_CLOCK_GATE_DISABLE); |
5845 | I915_WRITE(PCH_3DCGDIS1, | ||
5846 | VFMUNIT_CLOCK_GATE_DISABLE); | ||
5780 | } | 5847 | } |
5781 | 5848 | ||
5782 | I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); | 5849 | I915_WRITE(PCH_DSPCLK_GATE_D, dspclk_gate); |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 300f64b4238b..864417cffe9a 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -479,6 +479,7 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
479 | uint16_t address = algo_data->address; | 479 | uint16_t address = algo_data->address; |
480 | uint8_t msg[5]; | 480 | uint8_t msg[5]; |
481 | uint8_t reply[2]; | 481 | uint8_t reply[2]; |
482 | unsigned retry; | ||
482 | int msg_bytes; | 483 | int msg_bytes; |
483 | int reply_bytes; | 484 | int reply_bytes; |
484 | int ret; | 485 | int ret; |
@@ -513,14 +514,33 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
513 | break; | 514 | break; |
514 | } | 515 | } |
515 | 516 | ||
516 | for (;;) { | 517 | for (retry = 0; retry < 5; retry++) { |
517 | ret = intel_dp_aux_ch(intel_dp, | 518 | ret = intel_dp_aux_ch(intel_dp, |
518 | msg, msg_bytes, | 519 | msg, msg_bytes, |
519 | reply, reply_bytes); | 520 | reply, reply_bytes); |
520 | if (ret < 0) { | 521 | if (ret < 0) { |
521 | DRM_DEBUG_KMS("aux_ch failed %d\n", ret); | 522 | DRM_DEBUG_KMS("aux_ch failed %d\n", ret); |
522 | return ret; | 523 | return ret; |
523 | } | 524 | } |
525 | |||
526 | switch (reply[0] & AUX_NATIVE_REPLY_MASK) { | ||
527 | case AUX_NATIVE_REPLY_ACK: | ||
528 | /* I2C-over-AUX Reply field is only valid | ||
529 | * when paired with AUX ACK. | ||
530 | */ | ||
531 | break; | ||
532 | case AUX_NATIVE_REPLY_NACK: | ||
533 | DRM_DEBUG_KMS("aux_ch native nack\n"); | ||
534 | return -EREMOTEIO; | ||
535 | case AUX_NATIVE_REPLY_DEFER: | ||
536 | udelay(100); | ||
537 | continue; | ||
538 | default: | ||
539 | DRM_ERROR("aux_ch invalid native reply 0x%02x\n", | ||
540 | reply[0]); | ||
541 | return -EREMOTEIO; | ||
542 | } | ||
543 | |||
524 | switch (reply[0] & AUX_I2C_REPLY_MASK) { | 544 | switch (reply[0] & AUX_I2C_REPLY_MASK) { |
525 | case AUX_I2C_REPLY_ACK: | 545 | case AUX_I2C_REPLY_ACK: |
526 | if (mode == MODE_I2C_READ) { | 546 | if (mode == MODE_I2C_READ) { |
@@ -528,17 +548,20 @@ intel_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode, | |||
528 | } | 548 | } |
529 | return reply_bytes - 1; | 549 | return reply_bytes - 1; |
530 | case AUX_I2C_REPLY_NACK: | 550 | case AUX_I2C_REPLY_NACK: |
531 | DRM_DEBUG_KMS("aux_ch nack\n"); | 551 | DRM_DEBUG_KMS("aux_i2c nack\n"); |
532 | return -EREMOTEIO; | 552 | return -EREMOTEIO; |
533 | case AUX_I2C_REPLY_DEFER: | 553 | case AUX_I2C_REPLY_DEFER: |
534 | DRM_DEBUG_KMS("aux_ch defer\n"); | 554 | DRM_DEBUG_KMS("aux_i2c defer\n"); |
535 | udelay(100); | 555 | udelay(100); |
536 | break; | 556 | break; |
537 | default: | 557 | default: |
538 | DRM_ERROR("aux_ch invalid reply 0x%02x\n", reply[0]); | 558 | DRM_ERROR("aux_i2c invalid reply 0x%02x\n", reply[0]); |
539 | return -EREMOTEIO; | 559 | return -EREMOTEIO; |
540 | } | 560 | } |
541 | } | 561 | } |
562 | |||
563 | DRM_ERROR("too many retries, giving up\n"); | ||
564 | return -EREMOTEIO; | ||
542 | } | 565 | } |
543 | 566 | ||
544 | static int | 567 | static int |
@@ -1376,6 +1399,9 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1376 | struct drm_i915_private *dev_priv = dev->dev_private; | 1399 | struct drm_i915_private *dev_priv = dev->dev_private; |
1377 | uint32_t DP = intel_dp->DP; | 1400 | uint32_t DP = intel_dp->DP; |
1378 | 1401 | ||
1402 | if ((I915_READ(intel_dp->output_reg) & DP_PORT_EN) == 0) | ||
1403 | return; | ||
1404 | |||
1379 | DRM_DEBUG_KMS("\n"); | 1405 | DRM_DEBUG_KMS("\n"); |
1380 | 1406 | ||
1381 | if (is_edp(intel_dp)) { | 1407 | if (is_edp(intel_dp)) { |
@@ -1398,6 +1424,28 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1398 | 1424 | ||
1399 | if (is_edp(intel_dp)) | 1425 | if (is_edp(intel_dp)) |
1400 | DP |= DP_LINK_TRAIN_OFF; | 1426 | DP |= DP_LINK_TRAIN_OFF; |
1427 | |||
1428 | if (!HAS_PCH_CPT(dev) && | ||
1429 | I915_READ(intel_dp->output_reg) & DP_PIPEB_SELECT) { | ||
1430 | struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc); | ||
1431 | /* Hardware workaround: leaving our transcoder select | ||
1432 | * set to transcoder B while it's off will prevent the | ||
1433 | * corresponding HDMI output on transcoder A. | ||
1434 | * | ||
1435 | * Combine this with another hardware workaround: | ||
1436 | * transcoder select bit can only be cleared while the | ||
1437 | * port is enabled. | ||
1438 | */ | ||
1439 | DP &= ~DP_PIPEB_SELECT; | ||
1440 | I915_WRITE(intel_dp->output_reg, DP); | ||
1441 | |||
1442 | /* Changes to enable or select take place the vblank | ||
1443 | * after being written. | ||
1444 | */ | ||
1445 | intel_wait_for_vblank(intel_dp->base.base.dev, | ||
1446 | intel_crtc->pipe); | ||
1447 | } | ||
1448 | |||
1401 | I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); | 1449 | I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); |
1402 | POSTING_READ(intel_dp->output_reg); | 1450 | POSTING_READ(intel_dp->output_reg); |
1403 | } | 1451 | } |
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index f79327fc6653..25bcedf386fd 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c | |||
@@ -68,7 +68,7 @@ static struct intel_lvds *intel_attached_lvds(struct drm_connector *connector) | |||
68 | /** | 68 | /** |
69 | * Sets the power state for the panel. | 69 | * Sets the power state for the panel. |
70 | */ | 70 | */ |
71 | static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on) | 71 | static void intel_lvds_enable(struct intel_lvds *intel_lvds) |
72 | { | 72 | { |
73 | struct drm_device *dev = intel_lvds->base.base.dev; | 73 | struct drm_device *dev = intel_lvds->base.base.dev; |
74 | struct drm_i915_private *dev_priv = dev->dev_private; | 74 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -82,26 +82,61 @@ static void intel_lvds_set_power(struct intel_lvds *intel_lvds, bool on) | |||
82 | lvds_reg = LVDS; | 82 | lvds_reg = LVDS; |
83 | } | 83 | } |
84 | 84 | ||
85 | if (on) { | 85 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN); |
86 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) | LVDS_PORT_EN); | ||
87 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); | ||
88 | intel_panel_set_backlight(dev, dev_priv->backlight_level); | ||
89 | } else { | ||
90 | dev_priv->backlight_level = intel_panel_get_backlight(dev); | ||
91 | |||
92 | intel_panel_set_backlight(dev, 0); | ||
93 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); | ||
94 | 86 | ||
95 | if (intel_lvds->pfit_control) { | 87 | if (intel_lvds->pfit_dirty) { |
96 | if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) | 88 | /* |
97 | DRM_ERROR("timed out waiting for panel to power off\n"); | 89 | * Enable automatic panel scaling so that non-native modes |
98 | I915_WRITE(PFIT_CONTROL, 0); | 90 | * fill the screen. The panel fitter should only be |
99 | intel_lvds->pfit_control = 0; | 91 | * adjusted whilst the pipe is disabled, according to |
92 | * register description and PRM. | ||
93 | */ | ||
94 | DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n", | ||
95 | intel_lvds->pfit_control, | ||
96 | intel_lvds->pfit_pgm_ratios); | ||
97 | if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) { | ||
98 | DRM_ERROR("timed out waiting for panel to power off\n"); | ||
99 | } else { | ||
100 | I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios); | ||
101 | I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control); | ||
100 | intel_lvds->pfit_dirty = false; | 102 | intel_lvds->pfit_dirty = false; |
101 | } | 103 | } |
104 | } | ||
105 | |||
106 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) | POWER_TARGET_ON); | ||
107 | POSTING_READ(lvds_reg); | ||
108 | |||
109 | intel_panel_set_backlight(dev, dev_priv->backlight_level); | ||
110 | } | ||
102 | 111 | ||
103 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); | 112 | static void intel_lvds_disable(struct intel_lvds *intel_lvds) |
113 | { | ||
114 | struct drm_device *dev = intel_lvds->base.base.dev; | ||
115 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
116 | u32 ctl_reg, lvds_reg; | ||
117 | |||
118 | if (HAS_PCH_SPLIT(dev)) { | ||
119 | ctl_reg = PCH_PP_CONTROL; | ||
120 | lvds_reg = PCH_LVDS; | ||
121 | } else { | ||
122 | ctl_reg = PP_CONTROL; | ||
123 | lvds_reg = LVDS; | ||
124 | } | ||
125 | |||
126 | dev_priv->backlight_level = intel_panel_get_backlight(dev); | ||
127 | intel_panel_set_backlight(dev, 0); | ||
128 | |||
129 | I915_WRITE(ctl_reg, I915_READ(ctl_reg) & ~POWER_TARGET_ON); | ||
130 | |||
131 | if (intel_lvds->pfit_control) { | ||
132 | if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) | ||
133 | DRM_ERROR("timed out waiting for panel to power off\n"); | ||
134 | |||
135 | I915_WRITE(PFIT_CONTROL, 0); | ||
136 | intel_lvds->pfit_dirty = true; | ||
104 | } | 137 | } |
138 | |||
139 | I915_WRITE(lvds_reg, I915_READ(lvds_reg) & ~LVDS_PORT_EN); | ||
105 | POSTING_READ(lvds_reg); | 140 | POSTING_READ(lvds_reg); |
106 | } | 141 | } |
107 | 142 | ||
@@ -110,9 +145,9 @@ static void intel_lvds_dpms(struct drm_encoder *encoder, int mode) | |||
110 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); | 145 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); |
111 | 146 | ||
112 | if (mode == DRM_MODE_DPMS_ON) | 147 | if (mode == DRM_MODE_DPMS_ON) |
113 | intel_lvds_set_power(intel_lvds, true); | 148 | intel_lvds_enable(intel_lvds); |
114 | else | 149 | else |
115 | intel_lvds_set_power(intel_lvds, false); | 150 | intel_lvds_disable(intel_lvds); |
116 | 151 | ||
117 | /* XXX: We never power down the LVDS pairs. */ | 152 | /* XXX: We never power down the LVDS pairs. */ |
118 | } | 153 | } |
@@ -411,43 +446,18 @@ static void intel_lvds_commit(struct drm_encoder *encoder) | |||
411 | /* Always do a full power on as we do not know what state | 446 | /* Always do a full power on as we do not know what state |
412 | * we were left in. | 447 | * we were left in. |
413 | */ | 448 | */ |
414 | intel_lvds_set_power(intel_lvds, true); | 449 | intel_lvds_enable(intel_lvds); |
415 | } | 450 | } |
416 | 451 | ||
417 | static void intel_lvds_mode_set(struct drm_encoder *encoder, | 452 | static void intel_lvds_mode_set(struct drm_encoder *encoder, |
418 | struct drm_display_mode *mode, | 453 | struct drm_display_mode *mode, |
419 | struct drm_display_mode *adjusted_mode) | 454 | struct drm_display_mode *adjusted_mode) |
420 | { | 455 | { |
421 | struct drm_device *dev = encoder->dev; | ||
422 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
423 | struct intel_lvds *intel_lvds = to_intel_lvds(encoder); | ||
424 | |||
425 | /* | 456 | /* |
426 | * The LVDS pin pair will already have been turned on in the | 457 | * The LVDS pin pair will already have been turned on in the |
427 | * intel_crtc_mode_set since it has a large impact on the DPLL | 458 | * intel_crtc_mode_set since it has a large impact on the DPLL |
428 | * settings. | 459 | * settings. |
429 | */ | 460 | */ |
430 | |||
431 | if (HAS_PCH_SPLIT(dev)) | ||
432 | return; | ||
433 | |||
434 | if (!intel_lvds->pfit_dirty) | ||
435 | return; | ||
436 | |||
437 | /* | ||
438 | * Enable automatic panel scaling so that non-native modes fill the | ||
439 | * screen. Should be enabled before the pipe is enabled, according to | ||
440 | * register description and PRM. | ||
441 | */ | ||
442 | DRM_DEBUG_KMS("applying panel-fitter: %x, %x\n", | ||
443 | intel_lvds->pfit_control, | ||
444 | intel_lvds->pfit_pgm_ratios); | ||
445 | if (wait_for((I915_READ(PP_STATUS) & PP_ON) == 0, 1000)) | ||
446 | DRM_ERROR("timed out waiting for panel to power off\n"); | ||
447 | |||
448 | I915_WRITE(PFIT_PGM_RATIOS, intel_lvds->pfit_pgm_ratios); | ||
449 | I915_WRITE(PFIT_CONTROL, intel_lvds->pfit_control); | ||
450 | intel_lvds->pfit_dirty = false; | ||
451 | } | 461 | } |
452 | 462 | ||
453 | /** | 463 | /** |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index b83306f9244b..31cd7e33e820 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -156,23 +156,25 @@ static int init_ring_common(struct drm_device *dev, | |||
156 | 156 | ||
157 | /* G45 ring initialization fails to reset head to zero */ | 157 | /* G45 ring initialization fails to reset head to zero */ |
158 | if (head != 0) { | 158 | if (head != 0) { |
159 | DRM_ERROR("%s head not reset to zero " | 159 | DRM_DEBUG_KMS("%s head not reset to zero " |
160 | "ctl %08x head %08x tail %08x start %08x\n", | 160 | "ctl %08x head %08x tail %08x start %08x\n", |
161 | ring->name, | 161 | ring->name, |
162 | I915_READ_CTL(ring), | 162 | I915_READ_CTL(ring), |
163 | I915_READ_HEAD(ring), | 163 | I915_READ_HEAD(ring), |
164 | I915_READ_TAIL(ring), | 164 | I915_READ_TAIL(ring), |
165 | I915_READ_START(ring)); | 165 | I915_READ_START(ring)); |
166 | 166 | ||
167 | I915_WRITE_HEAD(ring, 0); | 167 | I915_WRITE_HEAD(ring, 0); |
168 | 168 | ||
169 | DRM_ERROR("%s head forced to zero " | 169 | if (I915_READ_HEAD(ring) & HEAD_ADDR) { |
170 | "ctl %08x head %08x tail %08x start %08x\n", | 170 | DRM_ERROR("failed to set %s head to zero " |
171 | ring->name, | 171 | "ctl %08x head %08x tail %08x start %08x\n", |
172 | I915_READ_CTL(ring), | 172 | ring->name, |
173 | I915_READ_HEAD(ring), | 173 | I915_READ_CTL(ring), |
174 | I915_READ_TAIL(ring), | 174 | I915_READ_HEAD(ring), |
175 | I915_READ_START(ring)); | 175 | I915_READ_TAIL(ring), |
176 | I915_READ_START(ring)); | ||
177 | } | ||
176 | } | 178 | } |
177 | 179 | ||
178 | I915_WRITE_CTL(ring, | 180 | I915_WRITE_CTL(ring, |
@@ -694,20 +696,17 @@ int intel_wait_ring_buffer(struct drm_device *dev, | |||
694 | drm_i915_private_t *dev_priv = dev->dev_private; | 696 | drm_i915_private_t *dev_priv = dev->dev_private; |
695 | u32 head; | 697 | u32 head; |
696 | 698 | ||
697 | head = intel_read_status_page(ring, 4); | ||
698 | if (head) { | ||
699 | ring->head = head & HEAD_ADDR; | ||
700 | ring->space = ring->head - (ring->tail + 8); | ||
701 | if (ring->space < 0) | ||
702 | ring->space += ring->size; | ||
703 | if (ring->space >= n) | ||
704 | return 0; | ||
705 | } | ||
706 | |||
707 | trace_i915_ring_wait_begin (dev); | 699 | trace_i915_ring_wait_begin (dev); |
708 | end = jiffies + 3 * HZ; | 700 | end = jiffies + 3 * HZ; |
709 | do { | 701 | do { |
710 | ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; | 702 | /* If the reported head position has wrapped or hasn't advanced, |
703 | * fallback to the slow and accurate path. | ||
704 | */ | ||
705 | head = intel_read_status_page(ring, 4); | ||
706 | if (head < ring->actual_head) | ||
707 | head = I915_READ_HEAD(ring); | ||
708 | ring->actual_head = head; | ||
709 | ring->head = head & HEAD_ADDR; | ||
711 | ring->space = ring->head - (ring->tail + 8); | 710 | ring->space = ring->head - (ring->tail + 8); |
712 | if (ring->space < 0) | 711 | if (ring->space < 0) |
713 | ring->space += ring->size; | 712 | ring->space += ring->size; |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 3126c2681983..d2cd0f1efeed 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -30,8 +30,9 @@ struct intel_ring_buffer { | |||
30 | struct drm_device *dev; | 30 | struct drm_device *dev; |
31 | struct drm_gem_object *gem_object; | 31 | struct drm_gem_object *gem_object; |
32 | 32 | ||
33 | unsigned int head; | 33 | u32 actual_head; |
34 | unsigned int tail; | 34 | u32 head; |
35 | u32 tail; | ||
35 | int space; | 36 | int space; |
36 | struct intel_hw_status_page status_page; | 37 | struct intel_hw_status_page status_page; |
37 | 38 | ||
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index d97e6cb52d34..6bc42fa2a6ec 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1908,9 +1908,12 @@ intel_sdvo_select_i2c_bus(struct drm_i915_private *dev_priv, | |||
1908 | speed = mapping->i2c_speed; | 1908 | speed = mapping->i2c_speed; |
1909 | } | 1909 | } |
1910 | 1910 | ||
1911 | sdvo->i2c = &dev_priv->gmbus[pin].adapter; | 1911 | if (pin < GMBUS_NUM_PORTS) { |
1912 | intel_gmbus_set_speed(sdvo->i2c, speed); | 1912 | sdvo->i2c = &dev_priv->gmbus[pin].adapter; |
1913 | intel_gmbus_force_bit(sdvo->i2c, true); | 1913 | intel_gmbus_set_speed(sdvo->i2c, speed); |
1914 | intel_gmbus_force_bit(sdvo->i2c, true); | ||
1915 | } else | ||
1916 | sdvo->i2c = &dev_priv->gmbus[GMBUS_PORT_DPB].adapter; | ||
1914 | } | 1917 | } |
1915 | 1918 | ||
1916 | static bool | 1919 | static bool |
@@ -2037,13 +2040,14 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device) | |||
2037 | SDVO_COLORIMETRY_RGB256); | 2040 | SDVO_COLORIMETRY_RGB256); |
2038 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; | 2041 | connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; |
2039 | 2042 | ||
2040 | intel_sdvo_add_hdmi_properties(intel_sdvo_connector); | ||
2041 | intel_sdvo->is_hdmi = true; | 2043 | intel_sdvo->is_hdmi = true; |
2042 | } | 2044 | } |
2043 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | | 2045 | intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | |
2044 | (1 << INTEL_ANALOG_CLONE_BIT)); | 2046 | (1 << INTEL_ANALOG_CLONE_BIT)); |
2045 | 2047 | ||
2046 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); | 2048 | intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); |
2049 | if (intel_sdvo->is_hdmi) | ||
2050 | intel_sdvo_add_hdmi_properties(intel_sdvo_connector); | ||
2047 | 2051 | ||
2048 | return true; | 2052 | return true; |
2049 | } | 2053 | } |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index df2b6f2b35f8..9fbabaa6ee44 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -253,7 +253,8 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
253 | case DRM_MODE_DPMS_SUSPEND: | 253 | case DRM_MODE_DPMS_SUSPEND: |
254 | case DRM_MODE_DPMS_OFF: | 254 | case DRM_MODE_DPMS_OFF: |
255 | drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); | 255 | drm_vblank_pre_modeset(dev, radeon_crtc->crtc_id); |
256 | atombios_blank_crtc(crtc, ATOM_ENABLE); | 256 | if (radeon_crtc->enabled) |
257 | atombios_blank_crtc(crtc, ATOM_ENABLE); | ||
257 | if (ASIC_IS_DCE3(rdev)) | 258 | if (ASIC_IS_DCE3(rdev)) |
258 | atombios_enable_crtc_memreq(crtc, ATOM_DISABLE); | 259 | atombios_enable_crtc_memreq(crtc, ATOM_DISABLE); |
259 | atombios_enable_crtc(crtc, ATOM_DISABLE); | 260 | atombios_enable_crtc(crtc, ATOM_DISABLE); |
@@ -530,7 +531,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
530 | dp_clock = dig_connector->dp_clock; | 531 | dp_clock = dig_connector->dp_clock; |
531 | } | 532 | } |
532 | } | 533 | } |
533 | 534 | #if 0 /* doesn't work properly on some laptops */ | |
534 | /* use recommended ref_div for ss */ | 535 | /* use recommended ref_div for ss */ |
535 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { | 536 | if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) { |
536 | if (ss_enabled) { | 537 | if (ss_enabled) { |
@@ -540,7 +541,7 @@ static u32 atombios_adjust_pll(struct drm_crtc *crtc, | |||
540 | } | 541 | } |
541 | } | 542 | } |
542 | } | 543 | } |
543 | 544 | #endif | |
544 | if (ASIC_IS_AVIVO(rdev)) { | 545 | if (ASIC_IS_AVIVO(rdev)) { |
545 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ | 546 | /* DVO wants 2x pixel clock if the DVO chip is in 12 bit mode */ |
546 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) | 547 | if (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1) |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 4dc5b4714c5a..7b337c361a12 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -748,6 +748,8 @@ void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev) | |||
748 | unsigned i; | 748 | unsigned i; |
749 | u32 tmp; | 749 | u32 tmp; |
750 | 750 | ||
751 | WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); | ||
752 | |||
751 | WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1)); | 753 | WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1)); |
752 | for (i = 0; i < rdev->usec_timeout; i++) { | 754 | for (i = 0; i < rdev->usec_timeout; i++) { |
753 | /* read MC_STATUS */ | 755 | /* read MC_STATUS */ |
@@ -1922,7 +1924,6 @@ bool evergreen_gpu_is_lockup(struct radeon_device *rdev) | |||
1922 | static int evergreen_gpu_soft_reset(struct radeon_device *rdev) | 1924 | static int evergreen_gpu_soft_reset(struct radeon_device *rdev) |
1923 | { | 1925 | { |
1924 | struct evergreen_mc_save save; | 1926 | struct evergreen_mc_save save; |
1925 | u32 srbm_reset = 0; | ||
1926 | u32 grbm_reset = 0; | 1927 | u32 grbm_reset = 0; |
1927 | 1928 | ||
1928 | dev_info(rdev->dev, "GPU softreset \n"); | 1929 | dev_info(rdev->dev, "GPU softreset \n"); |
@@ -1961,16 +1962,6 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev) | |||
1961 | udelay(50); | 1962 | udelay(50); |
1962 | WREG32(GRBM_SOFT_RESET, 0); | 1963 | WREG32(GRBM_SOFT_RESET, 0); |
1963 | (void)RREG32(GRBM_SOFT_RESET); | 1964 | (void)RREG32(GRBM_SOFT_RESET); |
1964 | |||
1965 | /* reset all the system blocks */ | ||
1966 | srbm_reset = SRBM_SOFT_RESET_ALL_MASK; | ||
1967 | |||
1968 | dev_info(rdev->dev, " SRBM_SOFT_RESET=0x%08X\n", srbm_reset); | ||
1969 | WREG32(SRBM_SOFT_RESET, srbm_reset); | ||
1970 | (void)RREG32(SRBM_SOFT_RESET); | ||
1971 | udelay(50); | ||
1972 | WREG32(SRBM_SOFT_RESET, 0); | ||
1973 | (void)RREG32(SRBM_SOFT_RESET); | ||
1974 | /* Wait a little for things to settle down */ | 1965 | /* Wait a little for things to settle down */ |
1975 | udelay(50); | 1966 | udelay(50); |
1976 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", | 1967 | dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", |
@@ -1981,10 +1972,6 @@ static int evergreen_gpu_soft_reset(struct radeon_device *rdev) | |||
1981 | RREG32(GRBM_STATUS_SE1)); | 1972 | RREG32(GRBM_STATUS_SE1)); |
1982 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", | 1973 | dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", |
1983 | RREG32(SRBM_STATUS)); | 1974 | RREG32(SRBM_STATUS)); |
1984 | /* After reset we need to reinit the asic as GPU often endup in an | ||
1985 | * incoherent state. | ||
1986 | */ | ||
1987 | atom_asic_init(rdev->mode_info.atom_context); | ||
1988 | evergreen_mc_resume(rdev, &save); | 1975 | evergreen_mc_resume(rdev, &save); |
1989 | return 0; | 1976 | return 0; |
1990 | } | 1977 | } |
@@ -2596,6 +2583,11 @@ int evergreen_resume(struct radeon_device *rdev) | |||
2596 | { | 2583 | { |
2597 | int r; | 2584 | int r; |
2598 | 2585 | ||
2586 | /* reset the asic, the gfx blocks are often in a bad state | ||
2587 | * after the driver is unloaded or after a resume | ||
2588 | */ | ||
2589 | if (radeon_asic_reset(rdev)) | ||
2590 | dev_warn(rdev->dev, "GPU reset failed !\n"); | ||
2599 | /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw, | 2591 | /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw, |
2600 | * posting will perform necessary task to bring back GPU into good | 2592 | * posting will perform necessary task to bring back GPU into good |
2601 | * shape. | 2593 | * shape. |
@@ -2712,6 +2704,11 @@ int evergreen_init(struct radeon_device *rdev) | |||
2712 | r = radeon_atombios_init(rdev); | 2704 | r = radeon_atombios_init(rdev); |
2713 | if (r) | 2705 | if (r) |
2714 | return r; | 2706 | return r; |
2707 | /* reset the asic, the gfx blocks are often in a bad state | ||
2708 | * after the driver is unloaded or after a resume | ||
2709 | */ | ||
2710 | if (radeon_asic_reset(rdev)) | ||
2711 | dev_warn(rdev->dev, "GPU reset failed !\n"); | ||
2715 | /* Post card if necessary */ | 2712 | /* Post card if necessary */ |
2716 | if (!evergreen_card_posted(rdev)) { | 2713 | if (!evergreen_card_posted(rdev)) { |
2717 | if (!rdev->bios) { | 2714 | if (!rdev->bios) { |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 113c70cc8b39..a73b53c44359 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -174,6 +174,7 @@ | |||
174 | #define HDP_NONSURFACE_BASE 0x2C04 | 174 | #define HDP_NONSURFACE_BASE 0x2C04 |
175 | #define HDP_NONSURFACE_INFO 0x2C08 | 175 | #define HDP_NONSURFACE_INFO 0x2C08 |
176 | #define HDP_NONSURFACE_SIZE 0x2C0C | 176 | #define HDP_NONSURFACE_SIZE 0x2C0C |
177 | #define HDP_MEM_COHERENCY_FLUSH_CNTL 0x5480 | ||
177 | #define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 | 178 | #define HDP_REG_COHERENCY_FLUSH_CNTL 0x54A0 |
178 | #define HDP_TILING_CONFIG 0x2F3C | 179 | #define HDP_TILING_CONFIG 0x2F3C |
179 | 180 | ||
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index a3552594ccc4..9c92db7c896b 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -878,12 +878,15 @@ void r600_pcie_gart_tlb_flush(struct radeon_device *rdev) | |||
878 | u32 tmp; | 878 | u32 tmp; |
879 | 879 | ||
880 | /* flush hdp cache so updates hit vram */ | 880 | /* flush hdp cache so updates hit vram */ |
881 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740)) { | 881 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && |
882 | !(rdev->flags & RADEON_IS_AGP)) { | ||
882 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; | 883 | void __iomem *ptr = (void *)rdev->gart.table.vram.ptr; |
883 | u32 tmp; | 884 | u32 tmp; |
884 | 885 | ||
885 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read | 886 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read |
886 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL | 887 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL |
888 | * This seems to cause problems on some AGP cards. Just use the old | ||
889 | * method for them. | ||
887 | */ | 890 | */ |
888 | WREG32(HDP_DEBUG1, 0); | 891 | WREG32(HDP_DEBUG1, 0); |
889 | tmp = readl((void __iomem *)ptr); | 892 | tmp = readl((void __iomem *)ptr); |
@@ -1195,8 +1198,10 @@ void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | |||
1195 | mc->vram_end, mc->real_vram_size >> 20); | 1198 | mc->vram_end, mc->real_vram_size >> 20); |
1196 | } else { | 1199 | } else { |
1197 | u64 base = 0; | 1200 | u64 base = 0; |
1198 | if (rdev->flags & RADEON_IS_IGP) | 1201 | if (rdev->flags & RADEON_IS_IGP) { |
1199 | base = (RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24; | 1202 | base = RREG32(MC_VM_FB_LOCATION) & 0xFFFF; |
1203 | base <<= 24; | ||
1204 | } | ||
1200 | radeon_vram_location(rdev, &rdev->mc, base); | 1205 | radeon_vram_location(rdev, &rdev->mc, base); |
1201 | rdev->mc.gtt_base_align = 0; | 1206 | rdev->mc.gtt_base_align = 0; |
1202 | radeon_gtt_location(rdev, mc); | 1207 | radeon_gtt_location(rdev, mc); |
@@ -1337,13 +1342,19 @@ bool r600_gpu_is_lockup(struct radeon_device *rdev) | |||
1337 | u32 srbm_status; | 1342 | u32 srbm_status; |
1338 | u32 grbm_status; | 1343 | u32 grbm_status; |
1339 | u32 grbm_status2; | 1344 | u32 grbm_status2; |
1345 | struct r100_gpu_lockup *lockup; | ||
1340 | int r; | 1346 | int r; |
1341 | 1347 | ||
1348 | if (rdev->family >= CHIP_RV770) | ||
1349 | lockup = &rdev->config.rv770.lockup; | ||
1350 | else | ||
1351 | lockup = &rdev->config.r600.lockup; | ||
1352 | |||
1342 | srbm_status = RREG32(R_000E50_SRBM_STATUS); | 1353 | srbm_status = RREG32(R_000E50_SRBM_STATUS); |
1343 | grbm_status = RREG32(R_008010_GRBM_STATUS); | 1354 | grbm_status = RREG32(R_008010_GRBM_STATUS); |
1344 | grbm_status2 = RREG32(R_008014_GRBM_STATUS2); | 1355 | grbm_status2 = RREG32(R_008014_GRBM_STATUS2); |
1345 | if (!G_008010_GUI_ACTIVE(grbm_status)) { | 1356 | if (!G_008010_GUI_ACTIVE(grbm_status)) { |
1346 | r100_gpu_lockup_update(&rdev->config.r300.lockup, &rdev->cp); | 1357 | r100_gpu_lockup_update(lockup, &rdev->cp); |
1347 | return false; | 1358 | return false; |
1348 | } | 1359 | } |
1349 | /* force CP activities */ | 1360 | /* force CP activities */ |
@@ -1355,7 +1366,7 @@ bool r600_gpu_is_lockup(struct radeon_device *rdev) | |||
1355 | radeon_ring_unlock_commit(rdev); | 1366 | radeon_ring_unlock_commit(rdev); |
1356 | } | 1367 | } |
1357 | rdev->cp.rptr = RREG32(R600_CP_RB_RPTR); | 1368 | rdev->cp.rptr = RREG32(R600_CP_RB_RPTR); |
1358 | return r100_gpu_cp_is_lockup(rdev, &rdev->config.r300.lockup, &rdev->cp); | 1369 | return r100_gpu_cp_is_lockup(rdev, lockup, &rdev->cp); |
1359 | } | 1370 | } |
1360 | 1371 | ||
1361 | int r600_asic_reset(struct radeon_device *rdev) | 1372 | int r600_asic_reset(struct radeon_device *rdev) |
@@ -3483,10 +3494,12 @@ int r600_debugfs_mc_info_init(struct radeon_device *rdev) | |||
3483 | void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) | 3494 | void r600_ioctl_wait_idle(struct radeon_device *rdev, struct radeon_bo *bo) |
3484 | { | 3495 | { |
3485 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read | 3496 | /* r7xx hw bug. write to HDP_DEBUG1 followed by fb read |
3486 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL | 3497 | * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL. |
3498 | * This seems to cause problems on some AGP cards. Just use the old | ||
3499 | * method for them. | ||
3487 | */ | 3500 | */ |
3488 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && | 3501 | if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) && |
3489 | rdev->vram_scratch.ptr) { | 3502 | rdev->vram_scratch.ptr && !(rdev->flags & RADEON_IS_AGP)) { |
3490 | void __iomem *ptr = (void *)rdev->vram_scratch.ptr; | 3503 | void __iomem *ptr = (void *)rdev->vram_scratch.ptr; |
3491 | u32 tmp; | 3504 | u32 tmp; |
3492 | 3505 | ||
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 0f90fc3482ce..7831e0890210 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -315,11 +315,10 @@ static inline int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
315 | if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) { | 315 | if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) { |
316 | /* the initial DDX does bad things with the CB size occasionally */ | 316 | /* the initial DDX does bad things with the CB size occasionally */ |
317 | /* it rounds up height too far for slice tile max but the BO is smaller */ | 317 | /* it rounds up height too far for slice tile max but the BO is smaller */ |
318 | tmp = (height - 7) * 8 * bpe; | 318 | /* r600c,g also seem to flush at bad times in some apps resulting in |
319 | if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { | 319 | * bogus values here. So for linear just allow anything to avoid breaking |
320 | dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i])); | 320 | * broken userspace. |
321 | return -EINVAL; | 321 | */ |
322 | } | ||
323 | } else { | 322 | } else { |
324 | dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i])); | 323 | dev_warn(p->dev, "%s offset[%d] %d %d %lu too big\n", __func__, i, track->cb_color_bo_offset[i], tmp, radeon_bo_size(track->cb_color_bo[i])); |
325 | return -EINVAL; | 324 | return -EINVAL; |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index d8ac1849180d..501966a13f48 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -286,7 +286,7 @@ void radeon_vram_location(struct radeon_device *rdev, struct radeon_mc *mc, u64 | |||
286 | mc->mc_vram_size = mc->aper_size; | 286 | mc->mc_vram_size = mc->aper_size; |
287 | } | 287 | } |
288 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; | 288 | mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; |
289 | dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", | 289 | dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n", |
290 | mc->mc_vram_size >> 20, mc->vram_start, | 290 | mc->mc_vram_size >> 20, mc->vram_start, |
291 | mc->vram_end, mc->real_vram_size >> 20); | 291 | mc->vram_end, mc->real_vram_size >> 20); |
292 | } | 292 | } |
@@ -323,7 +323,7 @@ void radeon_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) | |||
323 | mc->gtt_start = (mc->vram_end + 1 + mc->gtt_base_align) & ~mc->gtt_base_align; | 323 | mc->gtt_start = (mc->vram_end + 1 + mc->gtt_base_align) & ~mc->gtt_base_align; |
324 | } | 324 | } |
325 | mc->gtt_end = mc->gtt_start + mc->gtt_size - 1; | 325 | mc->gtt_end = mc->gtt_start + mc->gtt_size - 1; |
326 | dev_info(rdev->dev, "GTT: %lluM 0x%08llX - 0x%08llX\n", | 326 | dev_info(rdev->dev, "GTT: %lluM 0x%016llX - 0x%016llX\n", |
327 | mc->gtt_size >> 20, mc->gtt_start, mc->gtt_end); | 327 | mc->gtt_size >> 20, mc->gtt_start, mc->gtt_end); |
328 | } | 328 | } |
329 | 329 | ||
@@ -910,11 +910,6 @@ int radeon_resume_kms(struct drm_device *dev) | |||
910 | radeon_pm_resume(rdev); | 910 | radeon_pm_resume(rdev); |
911 | radeon_restore_bios_scratch_regs(rdev); | 911 | radeon_restore_bios_scratch_regs(rdev); |
912 | 912 | ||
913 | /* turn on display hw */ | ||
914 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
915 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); | ||
916 | } | ||
917 | |||
918 | radeon_fbdev_set_suspend(rdev, 0); | 913 | radeon_fbdev_set_suspend(rdev, 0); |
919 | release_console_sem(); | 914 | release_console_sem(); |
920 | 915 | ||
@@ -922,6 +917,10 @@ int radeon_resume_kms(struct drm_device *dev) | |||
922 | radeon_hpd_init(rdev); | 917 | radeon_hpd_init(rdev); |
923 | /* blat the mode back in */ | 918 | /* blat the mode back in */ |
924 | drm_helper_resume_force_mode(dev); | 919 | drm_helper_resume_force_mode(dev); |
920 | /* turn on display hw */ | ||
921 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | ||
922 | drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); | ||
923 | } | ||
925 | return 0; | 924 | return 0; |
926 | } | 925 | } |
927 | 926 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 88e4ea925900..60e689f2d048 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -232,9 +232,28 @@ static struct drm_driver driver_old = { | |||
232 | 232 | ||
233 | static struct drm_driver kms_driver; | 233 | static struct drm_driver kms_driver; |
234 | 234 | ||
235 | static void radeon_kick_out_firmware_fb(struct pci_dev *pdev) | ||
236 | { | ||
237 | struct apertures_struct *ap; | ||
238 | bool primary = false; | ||
239 | |||
240 | ap = alloc_apertures(1); | ||
241 | ap->ranges[0].base = pci_resource_start(pdev, 0); | ||
242 | ap->ranges[0].size = pci_resource_len(pdev, 0); | ||
243 | |||
244 | #ifdef CONFIG_X86 | ||
245 | primary = pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW; | ||
246 | #endif | ||
247 | remove_conflicting_framebuffers(ap, "radeondrmfb", primary); | ||
248 | kfree(ap); | ||
249 | } | ||
250 | |||
235 | static int __devinit | 251 | static int __devinit |
236 | radeon_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 252 | radeon_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
237 | { | 253 | { |
254 | /* Get rid of things like offb */ | ||
255 | radeon_kick_out_firmware_fb(pdev); | ||
256 | |||
238 | return drm_get_pci_dev(pdev, ent, &kms_driver); | 257 | return drm_get_pci_dev(pdev, ent, &kms_driver); |
239 | } | 258 | } |
240 | 259 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index efa211898fe6..6abea32be5e8 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -245,7 +245,7 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev, | |||
245 | goto out_unref; | 245 | goto out_unref; |
246 | } | 246 | } |
247 | info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base; | 247 | info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base; |
248 | info->apertures->ranges[0].size = rdev->mc.real_vram_size; | 248 | info->apertures->ranges[0].size = rdev->mc.aper_size; |
249 | 249 | ||
250 | info->fix.mmio_start = 0; | 250 | info->fix.mmio_start = 0; |
251 | info->fix.mmio_len = 0; | 251 | info->fix.mmio_len = 0; |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 1d067743fee0..a598d0049aa5 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -69,7 +69,7 @@ void radeon_ttm_placement_from_domain(struct radeon_bo *rbo, u32 domain) | |||
69 | u32 c = 0; | 69 | u32 c = 0; |
70 | 70 | ||
71 | rbo->placement.fpfn = 0; | 71 | rbo->placement.fpfn = 0; |
72 | rbo->placement.lpfn = rbo->rdev->mc.active_vram_size >> PAGE_SHIFT; | 72 | rbo->placement.lpfn = 0; |
73 | rbo->placement.placement = rbo->placements; | 73 | rbo->placement.placement = rbo->placements; |
74 | rbo->placement.busy_placement = rbo->placements; | 74 | rbo->placement.busy_placement = rbo->placements; |
75 | if (domain & RADEON_GEM_DOMAIN_VRAM) | 75 | if (domain & RADEON_GEM_DOMAIN_VRAM) |
@@ -91,7 +91,8 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, | |||
91 | { | 91 | { |
92 | struct radeon_bo *bo; | 92 | struct radeon_bo *bo; |
93 | enum ttm_bo_type type; | 93 | enum ttm_bo_type type; |
94 | int page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; | 94 | unsigned long page_align = roundup(byte_align, PAGE_SIZE) >> PAGE_SHIFT; |
95 | unsigned long max_size = 0; | ||
95 | int r; | 96 | int r; |
96 | 97 | ||
97 | if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { | 98 | if (unlikely(rdev->mman.bdev.dev_mapping == NULL)) { |
@@ -104,6 +105,14 @@ int radeon_bo_create(struct radeon_device *rdev, struct drm_gem_object *gobj, | |||
104 | } | 105 | } |
105 | *bo_ptr = NULL; | 106 | *bo_ptr = NULL; |
106 | 107 | ||
108 | /* maximun bo size is the minimun btw visible vram and gtt size */ | ||
109 | max_size = min(rdev->mc.visible_vram_size, rdev->mc.gtt_size); | ||
110 | if ((page_align << PAGE_SHIFT) >= max_size) { | ||
111 | printk(KERN_WARNING "%s:%d alloc size %ldM bigger than %ldMb limit\n", | ||
112 | __func__, __LINE__, page_align >> (20 - PAGE_SHIFT), max_size >> 20); | ||
113 | return -ENOMEM; | ||
114 | } | ||
115 | |||
107 | retry: | 116 | retry: |
108 | bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); | 117 | bo = kzalloc(sizeof(struct radeon_bo), GFP_KERNEL); |
109 | if (bo == NULL) | 118 | if (bo == NULL) |
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 4bf969c0a32b..be0fdd58aa29 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c | |||
@@ -916,27 +916,27 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr, | |||
916 | int nr = sensor_attr->index; | 916 | int nr = sensor_attr->index; |
917 | struct i2c_client *client = to_i2c_client(dev); | 917 | struct i2c_client *client = to_i2c_client(dev); |
918 | struct adm1026_data *data = i2c_get_clientdata(client); | 918 | struct adm1026_data *data = i2c_get_clientdata(client); |
919 | int val, orig_div, new_div, shift; | 919 | int val, orig_div, new_div; |
920 | 920 | ||
921 | val = simple_strtol(buf, NULL, 10); | 921 | val = simple_strtol(buf, NULL, 10); |
922 | new_div = DIV_TO_REG(val); | 922 | new_div = DIV_TO_REG(val); |
923 | if (new_div == 0) { | 923 | |
924 | return -EINVAL; | ||
925 | } | ||
926 | mutex_lock(&data->update_lock); | 924 | mutex_lock(&data->update_lock); |
927 | orig_div = data->fan_div[nr]; | 925 | orig_div = data->fan_div[nr]; |
928 | data->fan_div[nr] = DIV_FROM_REG(new_div); | 926 | data->fan_div[nr] = DIV_FROM_REG(new_div); |
929 | 927 | ||
930 | if (nr < 4) { /* 0 <= nr < 4 */ | 928 | if (nr < 4) { /* 0 <= nr < 4 */ |
931 | shift = 2 * nr; | ||
932 | adm1026_write_value(client, ADM1026_REG_FAN_DIV_0_3, | 929 | adm1026_write_value(client, ADM1026_REG_FAN_DIV_0_3, |
933 | ((DIV_TO_REG(orig_div) & (~(0x03 << shift))) | | 930 | (DIV_TO_REG(data->fan_div[0]) << 0) | |
934 | (new_div << shift))); | 931 | (DIV_TO_REG(data->fan_div[1]) << 2) | |
932 | (DIV_TO_REG(data->fan_div[2]) << 4) | | ||
933 | (DIV_TO_REG(data->fan_div[3]) << 6)); | ||
935 | } else { /* 3 < nr < 8 */ | 934 | } else { /* 3 < nr < 8 */ |
936 | shift = 2 * (nr - 4); | ||
937 | adm1026_write_value(client, ADM1026_REG_FAN_DIV_4_7, | 935 | adm1026_write_value(client, ADM1026_REG_FAN_DIV_4_7, |
938 | ((DIV_TO_REG(orig_div) & (~(0x03 << (2 * shift)))) | | 936 | (DIV_TO_REG(data->fan_div[4]) << 0) | |
939 | (new_div << shift))); | 937 | (DIV_TO_REG(data->fan_div[5]) << 2) | |
938 | (DIV_TO_REG(data->fan_div[6]) << 4) | | ||
939 | (DIV_TO_REG(data->fan_div[7]) << 6)); | ||
940 | } | 940 | } |
941 | 941 | ||
942 | if (data->fan_div[nr] != orig_div) { | 942 | if (data->fan_div[nr] != orig_div) { |
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index 14a5d981be7d..a428a9264195 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -187,6 +187,7 @@ static const u8 IT87_REG_FANX_MIN[] = { 0x1b, 0x1c, 0x1d, 0x85, 0x87 }; | |||
187 | #define IT87_REG_FAN_MAIN_CTRL 0x13 | 187 | #define IT87_REG_FAN_MAIN_CTRL 0x13 |
188 | #define IT87_REG_FAN_CTL 0x14 | 188 | #define IT87_REG_FAN_CTL 0x14 |
189 | #define IT87_REG_PWM(nr) (0x15 + (nr)) | 189 | #define IT87_REG_PWM(nr) (0x15 + (nr)) |
190 | #define IT87_REG_PWM_DUTY(nr) (0x63 + (nr) * 8) | ||
190 | 191 | ||
191 | #define IT87_REG_VIN(nr) (0x20 + (nr)) | 192 | #define IT87_REG_VIN(nr) (0x20 + (nr)) |
192 | #define IT87_REG_TEMP(nr) (0x29 + (nr)) | 193 | #define IT87_REG_TEMP(nr) (0x29 + (nr)) |
@@ -251,12 +252,16 @@ struct it87_data { | |||
251 | u8 fan_main_ctrl; /* Register value */ | 252 | u8 fan_main_ctrl; /* Register value */ |
252 | u8 fan_ctl; /* Register value */ | 253 | u8 fan_ctl; /* Register value */ |
253 | 254 | ||
254 | /* The following 3 arrays correspond to the same registers. The | 255 | /* The following 3 arrays correspond to the same registers up to |
255 | * meaning of bits 6-0 depends on the value of bit 7, and we want | 256 | * the IT8720F. The meaning of bits 6-0 depends on the value of bit |
256 | * to preserve settings on mode changes, so we have to track all | 257 | * 7, and we want to preserve settings on mode changes, so we have |
257 | * values separately. */ | 258 | * to track all values separately. |
259 | * Starting with the IT8721F, the manual PWM duty cycles are stored | ||
260 | * in separate registers (8-bit values), so the separate tracking | ||
261 | * is no longer needed, but it is still done to keep the driver | ||
262 | * simple. */ | ||
258 | u8 pwm_ctrl[3]; /* Register value */ | 263 | u8 pwm_ctrl[3]; /* Register value */ |
259 | u8 pwm_duty[3]; /* Manual PWM value set by user (bit 6-0) */ | 264 | u8 pwm_duty[3]; /* Manual PWM value set by user */ |
260 | u8 pwm_temp_map[3]; /* PWM to temp. chan. mapping (bits 1-0) */ | 265 | u8 pwm_temp_map[3]; /* PWM to temp. chan. mapping (bits 1-0) */ |
261 | 266 | ||
262 | /* Automatic fan speed control registers */ | 267 | /* Automatic fan speed control registers */ |
@@ -832,7 +837,9 @@ static ssize_t set_pwm_enable(struct device *dev, | |||
832 | data->fan_main_ctrl); | 837 | data->fan_main_ctrl); |
833 | } else { | 838 | } else { |
834 | if (val == 1) /* Manual mode */ | 839 | if (val == 1) /* Manual mode */ |
835 | data->pwm_ctrl[nr] = data->pwm_duty[nr]; | 840 | data->pwm_ctrl[nr] = data->type == it8721 ? |
841 | data->pwm_temp_map[nr] : | ||
842 | data->pwm_duty[nr]; | ||
836 | else /* Automatic mode */ | 843 | else /* Automatic mode */ |
837 | data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr]; | 844 | data->pwm_ctrl[nr] = 0x80 | data->pwm_temp_map[nr]; |
838 | it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]); | 845 | it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]); |
@@ -858,12 +865,25 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr, | |||
858 | return -EINVAL; | 865 | return -EINVAL; |
859 | 866 | ||
860 | mutex_lock(&data->update_lock); | 867 | mutex_lock(&data->update_lock); |
861 | data->pwm_duty[nr] = pwm_to_reg(data, val); | 868 | if (data->type == it8721) { |
862 | /* If we are in manual mode, write the duty cycle immediately; | 869 | /* If we are in automatic mode, the PWM duty cycle register |
863 | * otherwise, just store it for later use. */ | 870 | * is read-only so we can't write the value */ |
864 | if (!(data->pwm_ctrl[nr] & 0x80)) { | 871 | if (data->pwm_ctrl[nr] & 0x80) { |
865 | data->pwm_ctrl[nr] = data->pwm_duty[nr]; | 872 | mutex_unlock(&data->update_lock); |
866 | it87_write_value(data, IT87_REG_PWM(nr), data->pwm_ctrl[nr]); | 873 | return -EBUSY; |
874 | } | ||
875 | data->pwm_duty[nr] = pwm_to_reg(data, val); | ||
876 | it87_write_value(data, IT87_REG_PWM_DUTY(nr), | ||
877 | data->pwm_duty[nr]); | ||
878 | } else { | ||
879 | data->pwm_duty[nr] = pwm_to_reg(data, val); | ||
880 | /* If we are in manual mode, write the duty cycle immediately; | ||
881 | * otherwise, just store it for later use. */ | ||
882 | if (!(data->pwm_ctrl[nr] & 0x80)) { | ||
883 | data->pwm_ctrl[nr] = data->pwm_duty[nr]; | ||
884 | it87_write_value(data, IT87_REG_PWM(nr), | ||
885 | data->pwm_ctrl[nr]); | ||
886 | } | ||
867 | } | 887 | } |
868 | mutex_unlock(&data->update_lock); | 888 | mutex_unlock(&data->update_lock); |
869 | return count; | 889 | return count; |
@@ -1958,7 +1978,10 @@ static void __devinit it87_init_device(struct platform_device *pdev) | |||
1958 | * channels to use when later setting to automatic mode later. | 1978 | * channels to use when later setting to automatic mode later. |
1959 | * Use a 1:1 mapping by default (we are clueless.) | 1979 | * Use a 1:1 mapping by default (we are clueless.) |
1960 | * In both cases, the value can (and should) be changed by the user | 1980 | * In both cases, the value can (and should) be changed by the user |
1961 | * prior to switching to a different mode. */ | 1981 | * prior to switching to a different mode. |
1982 | * Note that this is no longer needed for the IT8721F and later, as | ||
1983 | * these have separate registers for the temperature mapping and the | ||
1984 | * manual duty cycle. */ | ||
1962 | for (i = 0; i < 3; i++) { | 1985 | for (i = 0; i < 3; i++) { |
1963 | data->pwm_temp_map[i] = i; | 1986 | data->pwm_temp_map[i] = i; |
1964 | data->pwm_duty[i] = 0x7f; /* Full speed */ | 1987 | data->pwm_duty[i] = 0x7f; /* Full speed */ |
@@ -2034,10 +2057,16 @@ static void __devinit it87_init_device(struct platform_device *pdev) | |||
2034 | static void it87_update_pwm_ctrl(struct it87_data *data, int nr) | 2057 | static void it87_update_pwm_ctrl(struct it87_data *data, int nr) |
2035 | { | 2058 | { |
2036 | data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr)); | 2059 | data->pwm_ctrl[nr] = it87_read_value(data, IT87_REG_PWM(nr)); |
2037 | if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */ | 2060 | if (data->type == it8721) { |
2038 | data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; | 2061 | data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; |
2039 | else /* Manual mode */ | 2062 | data->pwm_duty[nr] = it87_read_value(data, |
2040 | data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f; | 2063 | IT87_REG_PWM_DUTY(nr)); |
2064 | } else { | ||
2065 | if (data->pwm_ctrl[nr] & 0x80) /* Automatic mode */ | ||
2066 | data->pwm_temp_map[nr] = data->pwm_ctrl[nr] & 0x03; | ||
2067 | else /* Manual mode */ | ||
2068 | data->pwm_duty[nr] = data->pwm_ctrl[nr] & 0x7f; | ||
2069 | } | ||
2041 | 2070 | ||
2042 | if (has_old_autopwm(data)) { | 2071 | if (has_old_autopwm(data)) { |
2043 | int i; | 2072 | int i; |
diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c index 00d975eb5b83..c7e6d8e81656 100644 --- a/drivers/hwmon/ltc4215.c +++ b/drivers/hwmon/ltc4215.c | |||
@@ -205,7 +205,6 @@ LTC4215_ALARM(curr1_max_alarm, (1 << 2), LTC4215_STATUS); | |||
205 | 205 | ||
206 | /* Power (virtual) */ | 206 | /* Power (virtual) */ |
207 | LTC4215_POWER(power1_input); | 207 | LTC4215_POWER(power1_input); |
208 | LTC4215_ALARM(power1_alarm, (1 << 3), LTC4215_STATUS); | ||
209 | 208 | ||
210 | /* Input Voltage */ | 209 | /* Input Voltage */ |
211 | LTC4215_VOLTAGE(in1_input, LTC4215_ADIN); | 210 | LTC4215_VOLTAGE(in1_input, LTC4215_ADIN); |
@@ -214,6 +213,7 @@ LTC4215_ALARM(in1_min_alarm, (1 << 1), LTC4215_STATUS); | |||
214 | 213 | ||
215 | /* Output Voltage */ | 214 | /* Output Voltage */ |
216 | LTC4215_VOLTAGE(in2_input, LTC4215_SOURCE); | 215 | LTC4215_VOLTAGE(in2_input, LTC4215_SOURCE); |
216 | LTC4215_ALARM(in2_min_alarm, (1 << 3), LTC4215_STATUS); | ||
217 | 217 | ||
218 | /* Finally, construct an array of pointers to members of the above objects, | 218 | /* Finally, construct an array of pointers to members of the above objects, |
219 | * as required for sysfs_create_group() | 219 | * as required for sysfs_create_group() |
@@ -223,13 +223,13 @@ static struct attribute *ltc4215_attributes[] = { | |||
223 | &sensor_dev_attr_curr1_max_alarm.dev_attr.attr, | 223 | &sensor_dev_attr_curr1_max_alarm.dev_attr.attr, |
224 | 224 | ||
225 | &sensor_dev_attr_power1_input.dev_attr.attr, | 225 | &sensor_dev_attr_power1_input.dev_attr.attr, |
226 | &sensor_dev_attr_power1_alarm.dev_attr.attr, | ||
227 | 226 | ||
228 | &sensor_dev_attr_in1_input.dev_attr.attr, | 227 | &sensor_dev_attr_in1_input.dev_attr.attr, |
229 | &sensor_dev_attr_in1_max_alarm.dev_attr.attr, | 228 | &sensor_dev_attr_in1_max_alarm.dev_attr.attr, |
230 | &sensor_dev_attr_in1_min_alarm.dev_attr.attr, | 229 | &sensor_dev_attr_in1_min_alarm.dev_attr.attr, |
231 | 230 | ||
232 | &sensor_dev_attr_in2_input.dev_attr.attr, | 231 | &sensor_dev_attr_in2_input.dev_attr.attr, |
232 | &sensor_dev_attr_in2_min_alarm.dev_attr.attr, | ||
233 | 233 | ||
234 | NULL, | 234 | NULL, |
235 | }; | 235 | }; |
diff --git a/drivers/hwmon/s3c-hwmon.c b/drivers/hwmon/s3c-hwmon.c index 05248f2d7581..92b42db43bcf 100644 --- a/drivers/hwmon/s3c-hwmon.c +++ b/drivers/hwmon/s3c-hwmon.c | |||
@@ -234,7 +234,6 @@ static int s3c_hwmon_create_attr(struct device *dev, | |||
234 | attr->index = channel; | 234 | attr->index = channel; |
235 | attr->dev_attr.attr.name = attrs->in_name; | 235 | attr->dev_attr.attr.name = attrs->in_name; |
236 | attr->dev_attr.attr.mode = S_IRUGO; | 236 | attr->dev_attr.attr.mode = S_IRUGO; |
237 | attr->dev_attr.attr.owner = THIS_MODULE; | ||
238 | attr->dev_attr.show = s3c_hwmon_ch_show; | 237 | attr->dev_attr.show = s3c_hwmon_ch_show; |
239 | 238 | ||
240 | ret = device_create_file(dev, &attr->dev_attr); | 239 | ret = device_create_file(dev, &attr->dev_attr); |
@@ -252,7 +251,6 @@ static int s3c_hwmon_create_attr(struct device *dev, | |||
252 | attr->index = channel; | 251 | attr->index = channel; |
253 | attr->dev_attr.attr.name = attrs->label_name; | 252 | attr->dev_attr.attr.name = attrs->label_name; |
254 | attr->dev_attr.attr.mode = S_IRUGO; | 253 | attr->dev_attr.attr.mode = S_IRUGO; |
255 | attr->dev_attr.attr.owner = THIS_MODULE; | ||
256 | attr->dev_attr.show = s3c_hwmon_label_show; | 254 | attr->dev_attr.show = s3c_hwmon_label_show; |
257 | 255 | ||
258 | ret = device_create_file(dev, &attr->dev_attr); | 256 | ret = device_create_file(dev, &attr->dev_attr); |
diff --git a/drivers/i2c/busses/i2c-intel-mid.c b/drivers/i2c/busses/i2c-intel-mid.c index 80f70d3a744d..c71492782bbd 100644 --- a/drivers/i2c/busses/i2c-intel-mid.c +++ b/drivers/i2c/busses/i2c-intel-mid.c | |||
@@ -999,7 +999,7 @@ static int __devinit intel_mid_i2c_probe(struct pci_dev *dev, | |||
999 | 999 | ||
1000 | /* Initialize struct members */ | 1000 | /* Initialize struct members */ |
1001 | snprintf(mrst->adap.name, sizeof(mrst->adap.name), | 1001 | snprintf(mrst->adap.name, sizeof(mrst->adap.name), |
1002 | "MRST/Medfield I2C at %lx", start); | 1002 | "Intel MID I2C at %lx", start); |
1003 | mrst->adap.owner = THIS_MODULE; | 1003 | mrst->adap.owner = THIS_MODULE; |
1004 | mrst->adap.algo = &intel_mid_i2c_algorithm; | 1004 | mrst->adap.algo = &intel_mid_i2c_algorithm; |
1005 | mrst->adap.dev.parent = &dev->dev; | 1005 | mrst->adap.dev.parent = &dev->dev; |
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index 41665d2f9f93..c131d58bcb50 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
@@ -273,8 +273,6 @@ static int intel_idle_probe(void) | |||
273 | 273 | ||
274 | pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates); | 274 | pr_debug(PREFIX "MWAIT substates: 0x%x\n", mwait_substates); |
275 | 275 | ||
276 | if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */ | ||
277 | lapic_timer_reliable_states = 0xFFFFFFFF; | ||
278 | 276 | ||
279 | if (boot_cpu_data.x86 != 6) /* family 6 */ | 277 | if (boot_cpu_data.x86 != 6) /* family 6 */ |
280 | return -ENODEV; | 278 | return -ENODEV; |
@@ -286,8 +284,6 @@ static int intel_idle_probe(void) | |||
286 | case 0x1F: /* Core i7 and i5 Processor - Nehalem */ | 284 | case 0x1F: /* Core i7 and i5 Processor - Nehalem */ |
287 | case 0x2E: /* Nehalem-EX Xeon */ | 285 | case 0x2E: /* Nehalem-EX Xeon */ |
288 | case 0x2F: /* Westmere-EX Xeon */ | 286 | case 0x2F: /* Westmere-EX Xeon */ |
289 | lapic_timer_reliable_states = (1 << 1); /* C1 */ | ||
290 | |||
291 | case 0x25: /* Westmere */ | 287 | case 0x25: /* Westmere */ |
292 | case 0x2C: /* Westmere */ | 288 | case 0x2C: /* Westmere */ |
293 | cpuidle_state_table = nehalem_cstates; | 289 | cpuidle_state_table = nehalem_cstates; |
@@ -295,7 +291,6 @@ static int intel_idle_probe(void) | |||
295 | 291 | ||
296 | case 0x1C: /* 28 - Atom Processor */ | 292 | case 0x1C: /* 28 - Atom Processor */ |
297 | case 0x26: /* 38 - Lincroft Atom Processor */ | 293 | case 0x26: /* 38 - Lincroft Atom Processor */ |
298 | lapic_timer_reliable_states = (1 << 1); /* C1 */ | ||
299 | cpuidle_state_table = atom_cstates; | 294 | cpuidle_state_table = atom_cstates; |
300 | break; | 295 | break; |
301 | 296 | ||
@@ -303,10 +298,6 @@ static int intel_idle_probe(void) | |||
303 | case 0x2D: /* SNB Xeon */ | 298 | case 0x2D: /* SNB Xeon */ |
304 | cpuidle_state_table = snb_cstates; | 299 | cpuidle_state_table = snb_cstates; |
305 | break; | 300 | break; |
306 | #ifdef FUTURE_USE | ||
307 | case 0x17: /* 23 - Core 2 Duo */ | ||
308 | lapic_timer_reliable_states = (1 << 2) | (1 << 1); /* C2, C1 */ | ||
309 | #endif | ||
310 | 301 | ||
311 | default: | 302 | default: |
312 | pr_debug(PREFIX "does not run on family %d model %d\n", | 303 | pr_debug(PREFIX "does not run on family %d model %d\n", |
@@ -314,6 +305,9 @@ static int intel_idle_probe(void) | |||
314 | return -ENODEV; | 305 | return -ENODEV; |
315 | } | 306 | } |
316 | 307 | ||
308 | if (boot_cpu_has(X86_FEATURE_ARAT)) /* Always Reliable APIC Timer */ | ||
309 | lapic_timer_reliable_states = 0xFFFFFFFF; | ||
310 | |||
317 | pr_debug(PREFIX "v" INTEL_IDLE_VERSION | 311 | pr_debug(PREFIX "v" INTEL_IDLE_VERSION |
318 | " model 0x%X\n", boot_cpu_data.x86_model); | 312 | " model 0x%X\n", boot_cpu_data.x86_model); |
319 | 313 | ||
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index b342248aec05..c42699285f8e 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -893,68 +893,81 @@ out: | |||
893 | return ret ? ret : in_len; | 893 | return ret ? ret : in_len; |
894 | } | 894 | } |
895 | 895 | ||
896 | static int copy_wc_to_user(void __user *dest, struct ib_wc *wc) | ||
897 | { | ||
898 | struct ib_uverbs_wc tmp; | ||
899 | |||
900 | tmp.wr_id = wc->wr_id; | ||
901 | tmp.status = wc->status; | ||
902 | tmp.opcode = wc->opcode; | ||
903 | tmp.vendor_err = wc->vendor_err; | ||
904 | tmp.byte_len = wc->byte_len; | ||
905 | tmp.ex.imm_data = (__u32 __force) wc->ex.imm_data; | ||
906 | tmp.qp_num = wc->qp->qp_num; | ||
907 | tmp.src_qp = wc->src_qp; | ||
908 | tmp.wc_flags = wc->wc_flags; | ||
909 | tmp.pkey_index = wc->pkey_index; | ||
910 | tmp.slid = wc->slid; | ||
911 | tmp.sl = wc->sl; | ||
912 | tmp.dlid_path_bits = wc->dlid_path_bits; | ||
913 | tmp.port_num = wc->port_num; | ||
914 | tmp.reserved = 0; | ||
915 | |||
916 | if (copy_to_user(dest, &tmp, sizeof tmp)) | ||
917 | return -EFAULT; | ||
918 | |||
919 | return 0; | ||
920 | } | ||
921 | |||
896 | ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file, | 922 | ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file, |
897 | const char __user *buf, int in_len, | 923 | const char __user *buf, int in_len, |
898 | int out_len) | 924 | int out_len) |
899 | { | 925 | { |
900 | struct ib_uverbs_poll_cq cmd; | 926 | struct ib_uverbs_poll_cq cmd; |
901 | struct ib_uverbs_poll_cq_resp *resp; | 927 | struct ib_uverbs_poll_cq_resp resp; |
928 | u8 __user *header_ptr; | ||
929 | u8 __user *data_ptr; | ||
902 | struct ib_cq *cq; | 930 | struct ib_cq *cq; |
903 | struct ib_wc *wc; | 931 | struct ib_wc wc; |
904 | int ret = 0; | 932 | int ret; |
905 | int i; | ||
906 | int rsize; | ||
907 | 933 | ||
908 | if (copy_from_user(&cmd, buf, sizeof cmd)) | 934 | if (copy_from_user(&cmd, buf, sizeof cmd)) |
909 | return -EFAULT; | 935 | return -EFAULT; |
910 | 936 | ||
911 | wc = kmalloc(cmd.ne * sizeof *wc, GFP_KERNEL); | ||
912 | if (!wc) | ||
913 | return -ENOMEM; | ||
914 | |||
915 | rsize = sizeof *resp + cmd.ne * sizeof(struct ib_uverbs_wc); | ||
916 | resp = kmalloc(rsize, GFP_KERNEL); | ||
917 | if (!resp) { | ||
918 | ret = -ENOMEM; | ||
919 | goto out_wc; | ||
920 | } | ||
921 | |||
922 | cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0); | 937 | cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0); |
923 | if (!cq) { | 938 | if (!cq) |
924 | ret = -EINVAL; | 939 | return -EINVAL; |
925 | goto out; | ||
926 | } | ||
927 | 940 | ||
928 | resp->count = ib_poll_cq(cq, cmd.ne, wc); | 941 | /* we copy a struct ib_uverbs_poll_cq_resp to user space */ |
942 | header_ptr = (void __user *)(unsigned long) cmd.response; | ||
943 | data_ptr = header_ptr + sizeof resp; | ||
929 | 944 | ||
930 | put_cq_read(cq); | 945 | memset(&resp, 0, sizeof resp); |
946 | while (resp.count < cmd.ne) { | ||
947 | ret = ib_poll_cq(cq, 1, &wc); | ||
948 | if (ret < 0) | ||
949 | goto out_put; | ||
950 | if (!ret) | ||
951 | break; | ||
952 | |||
953 | ret = copy_wc_to_user(data_ptr, &wc); | ||
954 | if (ret) | ||
955 | goto out_put; | ||
931 | 956 | ||
932 | for (i = 0; i < resp->count; i++) { | 957 | data_ptr += sizeof(struct ib_uverbs_wc); |
933 | resp->wc[i].wr_id = wc[i].wr_id; | 958 | ++resp.count; |
934 | resp->wc[i].status = wc[i].status; | ||
935 | resp->wc[i].opcode = wc[i].opcode; | ||
936 | resp->wc[i].vendor_err = wc[i].vendor_err; | ||
937 | resp->wc[i].byte_len = wc[i].byte_len; | ||
938 | resp->wc[i].ex.imm_data = (__u32 __force) wc[i].ex.imm_data; | ||
939 | resp->wc[i].qp_num = wc[i].qp->qp_num; | ||
940 | resp->wc[i].src_qp = wc[i].src_qp; | ||
941 | resp->wc[i].wc_flags = wc[i].wc_flags; | ||
942 | resp->wc[i].pkey_index = wc[i].pkey_index; | ||
943 | resp->wc[i].slid = wc[i].slid; | ||
944 | resp->wc[i].sl = wc[i].sl; | ||
945 | resp->wc[i].dlid_path_bits = wc[i].dlid_path_bits; | ||
946 | resp->wc[i].port_num = wc[i].port_num; | ||
947 | } | 959 | } |
948 | 960 | ||
949 | if (copy_to_user((void __user *) (unsigned long) cmd.response, resp, rsize)) | 961 | if (copy_to_user(header_ptr, &resp, sizeof resp)) { |
950 | ret = -EFAULT; | 962 | ret = -EFAULT; |
963 | goto out_put; | ||
964 | } | ||
951 | 965 | ||
952 | out: | 966 | ret = in_len; |
953 | kfree(resp); | ||
954 | 967 | ||
955 | out_wc: | 968 | out_put: |
956 | kfree(wc); | 969 | put_cq_read(cq); |
957 | return ret ? ret : in_len; | 970 | return ret; |
958 | } | 971 | } |
959 | 972 | ||
960 | ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file, | 973 | ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file, |
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index e3f7fc6f9565..68f09a868434 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -534,76 +534,73 @@ static int handle_eviocgbit(struct input_dev *dev, | |||
534 | } | 534 | } |
535 | #undef OLD_KEY_MAX | 535 | #undef OLD_KEY_MAX |
536 | 536 | ||
537 | static int evdev_handle_get_keycode(struct input_dev *dev, | 537 | static int evdev_handle_get_keycode(struct input_dev *dev, void __user *p) |
538 | void __user *p, size_t size) | ||
539 | { | 538 | { |
540 | struct input_keymap_entry ke; | 539 | struct input_keymap_entry ke = { |
540 | .len = sizeof(unsigned int), | ||
541 | .flags = 0, | ||
542 | }; | ||
543 | int __user *ip = (int __user *)p; | ||
541 | int error; | 544 | int error; |
542 | 545 | ||
543 | memset(&ke, 0, sizeof(ke)); | 546 | /* legacy case */ |
544 | 547 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) | |
545 | if (size == sizeof(unsigned int[2])) { | 548 | return -EFAULT; |
546 | /* legacy case */ | ||
547 | int __user *ip = (int __user *)p; | ||
548 | 549 | ||
549 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) | 550 | error = input_get_keycode(dev, &ke); |
550 | return -EFAULT; | 551 | if (error) |
552 | return error; | ||
551 | 553 | ||
552 | ke.len = sizeof(unsigned int); | 554 | if (put_user(ke.keycode, ip + 1)) |
553 | ke.flags = 0; | 555 | return -EFAULT; |
554 | 556 | ||
555 | error = input_get_keycode(dev, &ke); | 557 | return 0; |
556 | if (error) | 558 | } |
557 | return error; | ||
558 | 559 | ||
559 | if (put_user(ke.keycode, ip + 1)) | 560 | static int evdev_handle_get_keycode_v2(struct input_dev *dev, void __user *p) |
560 | return -EFAULT; | 561 | { |
562 | struct input_keymap_entry ke; | ||
563 | int error; | ||
561 | 564 | ||
562 | } else { | 565 | if (copy_from_user(&ke, p, sizeof(ke))) |
563 | size = min(size, sizeof(ke)); | 566 | return -EFAULT; |
564 | 567 | ||
565 | if (copy_from_user(&ke, p, size)) | 568 | error = input_get_keycode(dev, &ke); |
566 | return -EFAULT; | 569 | if (error) |
570 | return error; | ||
567 | 571 | ||
568 | error = input_get_keycode(dev, &ke); | 572 | if (copy_to_user(p, &ke, sizeof(ke))) |
569 | if (error) | 573 | return -EFAULT; |
570 | return error; | ||
571 | 574 | ||
572 | if (copy_to_user(p, &ke, size)) | ||
573 | return -EFAULT; | ||
574 | } | ||
575 | return 0; | 575 | return 0; |
576 | } | 576 | } |
577 | 577 | ||
578 | static int evdev_handle_set_keycode(struct input_dev *dev, | 578 | static int evdev_handle_set_keycode(struct input_dev *dev, void __user *p) |
579 | void __user *p, size_t size) | ||
580 | { | 579 | { |
581 | struct input_keymap_entry ke; | 580 | struct input_keymap_entry ke = { |
582 | 581 | .len = sizeof(unsigned int), | |
583 | memset(&ke, 0, sizeof(ke)); | 582 | .flags = 0, |
583 | }; | ||
584 | int __user *ip = (int __user *)p; | ||
584 | 585 | ||
585 | if (size == sizeof(unsigned int[2])) { | 586 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) |
586 | /* legacy case */ | 587 | return -EFAULT; |
587 | int __user *ip = (int __user *)p; | ||
588 | 588 | ||
589 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) | 589 | if (get_user(ke.keycode, ip + 1)) |
590 | return -EFAULT; | 590 | return -EFAULT; |
591 | 591 | ||
592 | if (get_user(ke.keycode, ip + 1)) | 592 | return input_set_keycode(dev, &ke); |
593 | return -EFAULT; | 593 | } |
594 | 594 | ||
595 | ke.len = sizeof(unsigned int); | 595 | static int evdev_handle_set_keycode_v2(struct input_dev *dev, void __user *p) |
596 | ke.flags = 0; | 596 | { |
597 | struct input_keymap_entry ke; | ||
597 | 598 | ||
598 | } else { | 599 | if (copy_from_user(&ke, p, sizeof(ke))) |
599 | size = min(size, sizeof(ke)); | 600 | return -EFAULT; |
600 | 601 | ||
601 | if (copy_from_user(&ke, p, size)) | 602 | if (ke.len > sizeof(ke.scancode)) |
602 | return -EFAULT; | 603 | return -EINVAL; |
603 | |||
604 | if (ke.len > sizeof(ke.scancode)) | ||
605 | return -EINVAL; | ||
606 | } | ||
607 | 604 | ||
608 | return input_set_keycode(dev, &ke); | 605 | return input_set_keycode(dev, &ke); |
609 | } | 606 | } |
@@ -669,6 +666,18 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
669 | return evdev_grab(evdev, client); | 666 | return evdev_grab(evdev, client); |
670 | else | 667 | else |
671 | return evdev_ungrab(evdev, client); | 668 | return evdev_ungrab(evdev, client); |
669 | |||
670 | case EVIOCGKEYCODE: | ||
671 | return evdev_handle_get_keycode(dev, p); | ||
672 | |||
673 | case EVIOCSKEYCODE: | ||
674 | return evdev_handle_set_keycode(dev, p); | ||
675 | |||
676 | case EVIOCGKEYCODE_V2: | ||
677 | return evdev_handle_get_keycode_v2(dev, p); | ||
678 | |||
679 | case EVIOCSKEYCODE_V2: | ||
680 | return evdev_handle_set_keycode_v2(dev, p); | ||
672 | } | 681 | } |
673 | 682 | ||
674 | size = _IOC_SIZE(cmd); | 683 | size = _IOC_SIZE(cmd); |
@@ -708,12 +717,6 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
708 | return -EFAULT; | 717 | return -EFAULT; |
709 | 718 | ||
710 | return error; | 719 | return error; |
711 | |||
712 | case EVIOC_MASK_SIZE(EVIOCGKEYCODE): | ||
713 | return evdev_handle_get_keycode(dev, p, size); | ||
714 | |||
715 | case EVIOC_MASK_SIZE(EVIOCSKEYCODE): | ||
716 | return evdev_handle_set_keycode(dev, p, size); | ||
717 | } | 720 | } |
718 | 721 | ||
719 | /* Multi-number variable-length handlers */ | 722 | /* Multi-number variable-length handlers */ |
diff --git a/drivers/input/joystick/turbografx.c b/drivers/input/joystick/turbografx.c index d53b9e900234..27b6a3ce18ca 100644 --- a/drivers/input/joystick/turbografx.c +++ b/drivers/input/joystick/turbografx.c | |||
@@ -245,6 +245,7 @@ static struct tgfx __init *tgfx_probe(int parport, int *n_buttons, int n_devs) | |||
245 | goto err_free_tgfx; | 245 | goto err_free_tgfx; |
246 | } | 246 | } |
247 | 247 | ||
248 | parport_put_port(pp); | ||
248 | return tgfx; | 249 | return tgfx; |
249 | 250 | ||
250 | err_free_dev: | 251 | err_free_dev: |
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index b8c51b9781db..3a87f3ba5f75 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig | |||
@@ -179,6 +179,22 @@ config KEYBOARD_GPIO | |||
179 | To compile this driver as a module, choose M here: the | 179 | To compile this driver as a module, choose M here: the |
180 | module will be called gpio_keys. | 180 | module will be called gpio_keys. |
181 | 181 | ||
182 | config KEYBOARD_GPIO_POLLED | ||
183 | tristate "Polled GPIO buttons" | ||
184 | depends on GENERIC_GPIO | ||
185 | select INPUT_POLLDEV | ||
186 | help | ||
187 | This driver implements support for buttons connected | ||
188 | to GPIO pins that are not capable of generating interrupts. | ||
189 | |||
190 | Say Y here if your device has buttons connected | ||
191 | directly to such GPIO pins. Your board-specific | ||
192 | setup logic must also provide a platform device, | ||
193 | with configuration data saying which GPIOs are used. | ||
194 | |||
195 | To compile this driver as a module, choose M here: the | ||
196 | module will be called gpio_keys_polled. | ||
197 | |||
182 | config KEYBOARD_TCA6416 | 198 | config KEYBOARD_TCA6416 |
183 | tristate "TCA6416 Keypad Support" | 199 | tristate "TCA6416 Keypad Support" |
184 | depends on I2C | 200 | depends on I2C |
diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index a34452e8ebe2..622de73a445d 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile | |||
@@ -14,6 +14,7 @@ obj-$(CONFIG_KEYBOARD_BFIN) += bf54x-keys.o | |||
14 | obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o | 14 | obj-$(CONFIG_KEYBOARD_DAVINCI) += davinci_keyscan.o |
15 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o | 15 | obj-$(CONFIG_KEYBOARD_EP93XX) += ep93xx_keypad.o |
16 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o | 16 | obj-$(CONFIG_KEYBOARD_GPIO) += gpio_keys.o |
17 | obj-$(CONFIG_KEYBOARD_GPIO_POLLED) += gpio_keys_polled.o | ||
17 | obj-$(CONFIG_KEYBOARD_TCA6416) += tca6416-keypad.o | 18 | obj-$(CONFIG_KEYBOARD_TCA6416) += tca6416-keypad.o |
18 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o | 19 | obj-$(CONFIG_KEYBOARD_HIL) += hil_kbd.o |
19 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o | 20 | obj-$(CONFIG_KEYBOARD_HIL_OLD) += hilkbd.o |
diff --git a/drivers/input/keyboard/gpio_keys_polled.c b/drivers/input/keyboard/gpio_keys_polled.c new file mode 100644 index 000000000000..4c17aff20657 --- /dev/null +++ b/drivers/input/keyboard/gpio_keys_polled.c | |||
@@ -0,0 +1,261 @@ | |||
1 | /* | ||
2 | * Driver for buttons on GPIO lines not capable of generating interrupts | ||
3 | * | ||
4 | * Copyright (C) 2007-2010 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2010 Nuno Goncalves <nunojpg@gmail.com> | ||
6 | * | ||
7 | * This file was based on: /drivers/input/misc/cobalt_btns.c | ||
8 | * Copyright (C) 2007 Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | ||
9 | * | ||
10 | * also was based on: /drivers/input/keyboard/gpio_keys.c | ||
11 | * Copyright 2005 Phil Blundell | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify | ||
14 | * it under the terms of the GNU General Public License version 2 as | ||
15 | * published by the Free Software Foundation. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/input.h> | ||
23 | #include <linux/input-polldev.h> | ||
24 | #include <linux/ioport.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <linux/gpio.h> | ||
27 | #include <linux/gpio_keys.h> | ||
28 | |||
29 | #define DRV_NAME "gpio-keys-polled" | ||
30 | |||
31 | struct gpio_keys_button_data { | ||
32 | int last_state; | ||
33 | int count; | ||
34 | int threshold; | ||
35 | int can_sleep; | ||
36 | }; | ||
37 | |||
38 | struct gpio_keys_polled_dev { | ||
39 | struct input_polled_dev *poll_dev; | ||
40 | struct device *dev; | ||
41 | struct gpio_keys_platform_data *pdata; | ||
42 | struct gpio_keys_button_data data[0]; | ||
43 | }; | ||
44 | |||
45 | static void gpio_keys_polled_check_state(struct input_dev *input, | ||
46 | struct gpio_keys_button *button, | ||
47 | struct gpio_keys_button_data *bdata) | ||
48 | { | ||
49 | int state; | ||
50 | |||
51 | if (bdata->can_sleep) | ||
52 | state = !!gpio_get_value_cansleep(button->gpio); | ||
53 | else | ||
54 | state = !!gpio_get_value(button->gpio); | ||
55 | |||
56 | if (state != bdata->last_state) { | ||
57 | unsigned int type = button->type ?: EV_KEY; | ||
58 | |||
59 | input_event(input, type, button->code, | ||
60 | !!(state ^ button->active_low)); | ||
61 | input_sync(input); | ||
62 | bdata->count = 0; | ||
63 | bdata->last_state = state; | ||
64 | } | ||
65 | } | ||
66 | |||
67 | static void gpio_keys_polled_poll(struct input_polled_dev *dev) | ||
68 | { | ||
69 | struct gpio_keys_polled_dev *bdev = dev->private; | ||
70 | struct gpio_keys_platform_data *pdata = bdev->pdata; | ||
71 | struct input_dev *input = dev->input; | ||
72 | int i; | ||
73 | |||
74 | for (i = 0; i < bdev->pdata->nbuttons; i++) { | ||
75 | struct gpio_keys_button_data *bdata = &bdev->data[i]; | ||
76 | |||
77 | if (bdata->count < bdata->threshold) | ||
78 | bdata->count++; | ||
79 | else | ||
80 | gpio_keys_polled_check_state(input, &pdata->buttons[i], | ||
81 | bdata); | ||
82 | } | ||
83 | } | ||
84 | |||
85 | static void gpio_keys_polled_open(struct input_polled_dev *dev) | ||
86 | { | ||
87 | struct gpio_keys_polled_dev *bdev = dev->private; | ||
88 | struct gpio_keys_platform_data *pdata = bdev->pdata; | ||
89 | |||
90 | if (pdata->enable) | ||
91 | pdata->enable(bdev->dev); | ||
92 | } | ||
93 | |||
94 | static void gpio_keys_polled_close(struct input_polled_dev *dev) | ||
95 | { | ||
96 | struct gpio_keys_polled_dev *bdev = dev->private; | ||
97 | struct gpio_keys_platform_data *pdata = bdev->pdata; | ||
98 | |||
99 | if (pdata->disable) | ||
100 | pdata->disable(bdev->dev); | ||
101 | } | ||
102 | |||
103 | static int __devinit gpio_keys_polled_probe(struct platform_device *pdev) | ||
104 | { | ||
105 | struct gpio_keys_platform_data *pdata = pdev->dev.platform_data; | ||
106 | struct device *dev = &pdev->dev; | ||
107 | struct gpio_keys_polled_dev *bdev; | ||
108 | struct input_polled_dev *poll_dev; | ||
109 | struct input_dev *input; | ||
110 | int error; | ||
111 | int i; | ||
112 | |||
113 | if (!pdata || !pdata->poll_interval) | ||
114 | return -EINVAL; | ||
115 | |||
116 | bdev = kzalloc(sizeof(struct gpio_keys_polled_dev) + | ||
117 | pdata->nbuttons * sizeof(struct gpio_keys_button_data), | ||
118 | GFP_KERNEL); | ||
119 | if (!bdev) { | ||
120 | dev_err(dev, "no memory for private data\n"); | ||
121 | return -ENOMEM; | ||
122 | } | ||
123 | |||
124 | poll_dev = input_allocate_polled_device(); | ||
125 | if (!poll_dev) { | ||
126 | dev_err(dev, "no memory for polled device\n"); | ||
127 | error = -ENOMEM; | ||
128 | goto err_free_bdev; | ||
129 | } | ||
130 | |||
131 | poll_dev->private = bdev; | ||
132 | poll_dev->poll = gpio_keys_polled_poll; | ||
133 | poll_dev->poll_interval = pdata->poll_interval; | ||
134 | poll_dev->open = gpio_keys_polled_open; | ||
135 | poll_dev->close = gpio_keys_polled_close; | ||
136 | |||
137 | input = poll_dev->input; | ||
138 | |||
139 | input->evbit[0] = BIT(EV_KEY); | ||
140 | input->name = pdev->name; | ||
141 | input->phys = DRV_NAME"/input0"; | ||
142 | input->dev.parent = &pdev->dev; | ||
143 | |||
144 | input->id.bustype = BUS_HOST; | ||
145 | input->id.vendor = 0x0001; | ||
146 | input->id.product = 0x0001; | ||
147 | input->id.version = 0x0100; | ||
148 | |||
149 | for (i = 0; i < pdata->nbuttons; i++) { | ||
150 | struct gpio_keys_button *button = &pdata->buttons[i]; | ||
151 | struct gpio_keys_button_data *bdata = &bdev->data[i]; | ||
152 | unsigned int gpio = button->gpio; | ||
153 | unsigned int type = button->type ?: EV_KEY; | ||
154 | |||
155 | if (button->wakeup) { | ||
156 | dev_err(dev, DRV_NAME " does not support wakeup\n"); | ||
157 | error = -EINVAL; | ||
158 | goto err_free_gpio; | ||
159 | } | ||
160 | |||
161 | error = gpio_request(gpio, | ||
162 | button->desc ? button->desc : DRV_NAME); | ||
163 | if (error) { | ||
164 | dev_err(dev, "unable to claim gpio %u, err=%d\n", | ||
165 | gpio, error); | ||
166 | goto err_free_gpio; | ||
167 | } | ||
168 | |||
169 | error = gpio_direction_input(gpio); | ||
170 | if (error) { | ||
171 | dev_err(dev, | ||
172 | "unable to set direction on gpio %u, err=%d\n", | ||
173 | gpio, error); | ||
174 | goto err_free_gpio; | ||
175 | } | ||
176 | |||
177 | bdata->can_sleep = gpio_cansleep(gpio); | ||
178 | bdata->last_state = -1; | ||
179 | bdata->threshold = DIV_ROUND_UP(button->debounce_interval, | ||
180 | pdata->poll_interval); | ||
181 | |||
182 | input_set_capability(input, type, button->code); | ||
183 | } | ||
184 | |||
185 | bdev->poll_dev = poll_dev; | ||
186 | bdev->dev = dev; | ||
187 | bdev->pdata = pdata; | ||
188 | platform_set_drvdata(pdev, bdev); | ||
189 | |||
190 | error = input_register_polled_device(poll_dev); | ||
191 | if (error) { | ||
192 | dev_err(dev, "unable to register polled device, err=%d\n", | ||
193 | error); | ||
194 | goto err_free_gpio; | ||
195 | } | ||
196 | |||
197 | /* report initial state of the buttons */ | ||
198 | for (i = 0; i < pdata->nbuttons; i++) | ||
199 | gpio_keys_polled_check_state(input, &pdata->buttons[i], | ||
200 | &bdev->data[i]); | ||
201 | |||
202 | return 0; | ||
203 | |||
204 | err_free_gpio: | ||
205 | while (--i >= 0) | ||
206 | gpio_free(pdata->buttons[i].gpio); | ||
207 | |||
208 | input_free_polled_device(poll_dev); | ||
209 | |||
210 | err_free_bdev: | ||
211 | kfree(bdev); | ||
212 | |||
213 | platform_set_drvdata(pdev, NULL); | ||
214 | return error; | ||
215 | } | ||
216 | |||
217 | static int __devexit gpio_keys_polled_remove(struct platform_device *pdev) | ||
218 | { | ||
219 | struct gpio_keys_polled_dev *bdev = platform_get_drvdata(pdev); | ||
220 | struct gpio_keys_platform_data *pdata = bdev->pdata; | ||
221 | int i; | ||
222 | |||
223 | input_unregister_polled_device(bdev->poll_dev); | ||
224 | |||
225 | for (i = 0; i < pdata->nbuttons; i++) | ||
226 | gpio_free(pdata->buttons[i].gpio); | ||
227 | |||
228 | input_free_polled_device(bdev->poll_dev); | ||
229 | |||
230 | kfree(bdev); | ||
231 | platform_set_drvdata(pdev, NULL); | ||
232 | |||
233 | return 0; | ||
234 | } | ||
235 | |||
236 | static struct platform_driver gpio_keys_polled_driver = { | ||
237 | .probe = gpio_keys_polled_probe, | ||
238 | .remove = __devexit_p(gpio_keys_polled_remove), | ||
239 | .driver = { | ||
240 | .name = DRV_NAME, | ||
241 | .owner = THIS_MODULE, | ||
242 | }, | ||
243 | }; | ||
244 | |||
245 | static int __init gpio_keys_polled_init(void) | ||
246 | { | ||
247 | return platform_driver_register(&gpio_keys_polled_driver); | ||
248 | } | ||
249 | |||
250 | static void __exit gpio_keys_polled_exit(void) | ||
251 | { | ||
252 | platform_driver_unregister(&gpio_keys_polled_driver); | ||
253 | } | ||
254 | |||
255 | module_init(gpio_keys_polled_init); | ||
256 | module_exit(gpio_keys_polled_exit); | ||
257 | |||
258 | MODULE_LICENSE("GPL v2"); | ||
259 | MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>"); | ||
260 | MODULE_DESCRIPTION("Polled GPIO Buttons driver"); | ||
261 | MODULE_ALIAS("platform:" DRV_NAME); | ||
diff --git a/drivers/input/mouse/synaptics.h b/drivers/input/mouse/synaptics.h index 613a3652f98f..0aefaa885871 100644 --- a/drivers/input/mouse/synaptics.h +++ b/drivers/input/mouse/synaptics.h | |||
@@ -51,7 +51,8 @@ | |||
51 | #define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20) | 51 | #define SYN_EXT_CAP_REQUESTS(c) (((c) & 0x700000) >> 20) |
52 | #define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12) | 52 | #define SYN_CAP_MULTI_BUTTON_NO(ec) (((ec) & 0x00f000) >> 12) |
53 | #define SYN_CAP_PRODUCT_ID(ec) (((ec) & 0xff0000) >> 16) | 53 | #define SYN_CAP_PRODUCT_ID(ec) (((ec) & 0xff0000) >> 16) |
54 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100100) | 54 | #define SYN_CAP_CLICKPAD(ex0c) ((ex0c) & 0x100000) /* 1-button ClickPad */ |
55 | #define SYN_CAP_CLICKPAD2BTN(ex0c) ((ex0c) & 0x000100) /* 2-button ClickPad */ | ||
55 | #define SYN_CAP_MAX_DIMENSIONS(ex0c) ((ex0c) & 0x020000) | 56 | #define SYN_CAP_MAX_DIMENSIONS(ex0c) ((ex0c) & 0x020000) |
56 | 57 | ||
57 | /* synaptics modes query bits */ | 58 | /* synaptics modes query bits */ |
diff --git a/drivers/input/tablet/wacom_wac.c b/drivers/input/tablet/wacom_wac.c index b3252ef1e279..435b0af401e4 100644 --- a/drivers/input/tablet/wacom_wac.c +++ b/drivers/input/tablet/wacom_wac.c | |||
@@ -1436,6 +1436,14 @@ static struct wacom_features wacom_features_0xD2 = | |||
1436 | { "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; | 1436 | { "Wacom Bamboo Craft", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; |
1437 | static struct wacom_features wacom_features_0xD3 = | 1437 | static struct wacom_features wacom_features_0xD3 = |
1438 | { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; | 1438 | { "Wacom Bamboo 2FG 6x8", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; |
1439 | static const struct wacom_features wacom_features_0xD4 = | ||
1440 | { "Wacom Bamboo Pen", WACOM_PKGLEN_BBFUN, 14720, 9200, 255, 63, BAMBOO_PT }; | ||
1441 | static struct wacom_features wacom_features_0xD8 = | ||
1442 | { "Wacom Bamboo Comic 2FG", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; | ||
1443 | static struct wacom_features wacom_features_0xDA = | ||
1444 | { "Wacom Bamboo 2FG 4x5 SE", WACOM_PKGLEN_BBFUN, 14720, 9200, 1023, 63, BAMBOO_PT }; | ||
1445 | static struct wacom_features wacom_features_0xDB = | ||
1446 | { "Wacom Bamboo 2FG 6x8 SE", WACOM_PKGLEN_BBFUN, 21648, 13530, 1023, 63, BAMBOO_PT }; | ||
1439 | 1447 | ||
1440 | #define USB_DEVICE_WACOM(prod) \ | 1448 | #define USB_DEVICE_WACOM(prod) \ |
1441 | USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ | 1449 | USB_DEVICE(USB_VENDOR_ID_WACOM, prod), \ |
@@ -1504,6 +1512,10 @@ const struct usb_device_id wacom_ids[] = { | |||
1504 | { USB_DEVICE_WACOM(0xD1) }, | 1512 | { USB_DEVICE_WACOM(0xD1) }, |
1505 | { USB_DEVICE_WACOM(0xD2) }, | 1513 | { USB_DEVICE_WACOM(0xD2) }, |
1506 | { USB_DEVICE_WACOM(0xD3) }, | 1514 | { USB_DEVICE_WACOM(0xD3) }, |
1515 | { USB_DEVICE_WACOM(0xD4) }, | ||
1516 | { USB_DEVICE_WACOM(0xD8) }, | ||
1517 | { USB_DEVICE_WACOM(0xDA) }, | ||
1518 | { USB_DEVICE_WACOM(0xDB) }, | ||
1507 | { USB_DEVICE_WACOM(0xF0) }, | 1519 | { USB_DEVICE_WACOM(0xF0) }, |
1508 | { USB_DEVICE_WACOM(0xCC) }, | 1520 | { USB_DEVICE_WACOM(0xCC) }, |
1509 | { USB_DEVICE_WACOM(0x90) }, | 1521 | { USB_DEVICE_WACOM(0x90) }, |
diff --git a/drivers/input/touchscreen/usbtouchscreen.c b/drivers/input/touchscreen/usbtouchscreen.c index f45f80f6d336..73fd6642b681 100644 --- a/drivers/input/touchscreen/usbtouchscreen.c +++ b/drivers/input/touchscreen/usbtouchscreen.c | |||
@@ -178,6 +178,7 @@ static const struct usb_device_id usbtouch_devices[] = { | |||
178 | 178 | ||
179 | #ifdef CONFIG_TOUCHSCREEN_USB_ITM | 179 | #ifdef CONFIG_TOUCHSCREEN_USB_ITM |
180 | {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM}, | 180 | {USB_DEVICE(0x0403, 0xf9e9), .driver_info = DEVTYPE_ITM}, |
181 | {USB_DEVICE(0x16e3, 0xf9e9), .driver_info = DEVTYPE_ITM}, | ||
181 | #endif | 182 | #endif |
182 | 183 | ||
183 | #ifdef CONFIG_TOUCHSCREEN_USB_ETURBO | 184 | #ifdef CONFIG_TOUCHSCREEN_USB_ETURBO |
diff --git a/drivers/isdn/gigaset/capi.c b/drivers/isdn/gigaset/capi.c index bcc174e4f3b1..658e75f18d05 100644 --- a/drivers/isdn/gigaset/capi.c +++ b/drivers/isdn/gigaset/capi.c | |||
@@ -1900,6 +1900,7 @@ static void do_disconnect_req(struct gigaset_capi_ctr *iif, | |||
1900 | if (b3skb == NULL) { | 1900 | if (b3skb == NULL) { |
1901 | dev_err(cs->dev, "%s: out of memory\n", __func__); | 1901 | dev_err(cs->dev, "%s: out of memory\n", __func__); |
1902 | send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR); | 1902 | send_conf(iif, ap, skb, CAPI_MSGOSRESOURCEERR); |
1903 | kfree(b3cmsg); | ||
1903 | return; | 1904 | return; |
1904 | } | 1905 | } |
1905 | capi_cmsg2message(b3cmsg, | 1906 | capi_cmsg2message(b3cmsg, |
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 211e21f34bd5..d5a4ade88991 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c | |||
@@ -267,7 +267,7 @@ void led_blink_set(struct led_classdev *led_cdev, | |||
267 | unsigned long *delay_off) | 267 | unsigned long *delay_off) |
268 | { | 268 | { |
269 | if (led_cdev->blink_set && | 269 | if (led_cdev->blink_set && |
270 | led_cdev->blink_set(led_cdev, delay_on, delay_off)) | 270 | !led_cdev->blink_set(led_cdev, delay_on, delay_off)) |
271 | return; | 271 | return; |
272 | 272 | ||
273 | /* blink with 1 Hz as default if nothing specified */ | 273 | /* blink with 1 Hz as default if nothing specified */ |
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 90267f8d64ee..4d705cea0f8c 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -517,9 +517,8 @@ int dm_set_device_limits(struct dm_target *ti, struct dm_dev *dev, | |||
517 | */ | 517 | */ |
518 | 518 | ||
519 | if (q->merge_bvec_fn && !ti->type->merge) | 519 | if (q->merge_bvec_fn && !ti->type->merge) |
520 | limits->max_sectors = | 520 | blk_limits_max_hw_sectors(limits, |
521 | min_not_zero(limits->max_sectors, | 521 | (unsigned int) (PAGE_SIZE >> 9)); |
522 | (unsigned int) (PAGE_SIZE >> 9)); | ||
523 | return 0; | 522 | return 0; |
524 | } | 523 | } |
525 | EXPORT_SYMBOL_GPL(dm_set_device_limits); | 524 | EXPORT_SYMBOL_GPL(dm_set_device_limits); |
@@ -1131,11 +1130,6 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q, | |||
1131 | */ | 1130 | */ |
1132 | q->limits = *limits; | 1131 | q->limits = *limits; |
1133 | 1132 | ||
1134 | if (limits->no_cluster) | ||
1135 | queue_flag_clear_unlocked(QUEUE_FLAG_CLUSTER, q); | ||
1136 | else | ||
1137 | queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, q); | ||
1138 | |||
1139 | if (!dm_table_supports_discards(t)) | 1133 | if (!dm_table_supports_discards(t)) |
1140 | queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q); | 1134 | queue_flag_clear_unlocked(QUEUE_FLAG_DISCARD, q); |
1141 | else | 1135 | else |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 84c46a161927..175c424f201f 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -371,10 +371,15 @@ static void md_end_flush(struct bio *bio, int err) | |||
371 | bio_put(bio); | 371 | bio_put(bio); |
372 | } | 372 | } |
373 | 373 | ||
374 | static void submit_flushes(mddev_t *mddev) | 374 | static void md_submit_flush_data(struct work_struct *ws); |
375 | |||
376 | static void submit_flushes(struct work_struct *ws) | ||
375 | { | 377 | { |
378 | mddev_t *mddev = container_of(ws, mddev_t, flush_work); | ||
376 | mdk_rdev_t *rdev; | 379 | mdk_rdev_t *rdev; |
377 | 380 | ||
381 | INIT_WORK(&mddev->flush_work, md_submit_flush_data); | ||
382 | atomic_set(&mddev->flush_pending, 1); | ||
378 | rcu_read_lock(); | 383 | rcu_read_lock(); |
379 | list_for_each_entry_rcu(rdev, &mddev->disks, same_set) | 384 | list_for_each_entry_rcu(rdev, &mddev->disks, same_set) |
380 | if (rdev->raid_disk >= 0 && | 385 | if (rdev->raid_disk >= 0 && |
@@ -397,6 +402,8 @@ static void submit_flushes(mddev_t *mddev) | |||
397 | rdev_dec_pending(rdev, mddev); | 402 | rdev_dec_pending(rdev, mddev); |
398 | } | 403 | } |
399 | rcu_read_unlock(); | 404 | rcu_read_unlock(); |
405 | if (atomic_dec_and_test(&mddev->flush_pending)) | ||
406 | queue_work(md_wq, &mddev->flush_work); | ||
400 | } | 407 | } |
401 | 408 | ||
402 | static void md_submit_flush_data(struct work_struct *ws) | 409 | static void md_submit_flush_data(struct work_struct *ws) |
@@ -404,8 +411,6 @@ static void md_submit_flush_data(struct work_struct *ws) | |||
404 | mddev_t *mddev = container_of(ws, mddev_t, flush_work); | 411 | mddev_t *mddev = container_of(ws, mddev_t, flush_work); |
405 | struct bio *bio = mddev->flush_bio; | 412 | struct bio *bio = mddev->flush_bio; |
406 | 413 | ||
407 | atomic_set(&mddev->flush_pending, 1); | ||
408 | |||
409 | if (bio->bi_size == 0) | 414 | if (bio->bi_size == 0) |
410 | /* an empty barrier - all done */ | 415 | /* an empty barrier - all done */ |
411 | bio_endio(bio, 0); | 416 | bio_endio(bio, 0); |
@@ -414,10 +419,9 @@ static void md_submit_flush_data(struct work_struct *ws) | |||
414 | if (mddev->pers->make_request(mddev, bio)) | 419 | if (mddev->pers->make_request(mddev, bio)) |
415 | generic_make_request(bio); | 420 | generic_make_request(bio); |
416 | } | 421 | } |
417 | if (atomic_dec_and_test(&mddev->flush_pending)) { | 422 | |
418 | mddev->flush_bio = NULL; | 423 | mddev->flush_bio = NULL; |
419 | wake_up(&mddev->sb_wait); | 424 | wake_up(&mddev->sb_wait); |
420 | } | ||
421 | } | 425 | } |
422 | 426 | ||
423 | void md_flush_request(mddev_t *mddev, struct bio *bio) | 427 | void md_flush_request(mddev_t *mddev, struct bio *bio) |
@@ -429,13 +433,8 @@ void md_flush_request(mddev_t *mddev, struct bio *bio) | |||
429 | mddev->flush_bio = bio; | 433 | mddev->flush_bio = bio; |
430 | spin_unlock_irq(&mddev->write_lock); | 434 | spin_unlock_irq(&mddev->write_lock); |
431 | 435 | ||
432 | atomic_set(&mddev->flush_pending, 1); | 436 | INIT_WORK(&mddev->flush_work, submit_flushes); |
433 | INIT_WORK(&mddev->flush_work, md_submit_flush_data); | 437 | queue_work(md_wq, &mddev->flush_work); |
434 | |||
435 | submit_flushes(mddev); | ||
436 | |||
437 | if (atomic_dec_and_test(&mddev->flush_pending)) | ||
438 | queue_work(md_wq, &mddev->flush_work); | ||
439 | } | 438 | } |
440 | EXPORT_SYMBOL(md_flush_request); | 439 | EXPORT_SYMBOL(md_flush_request); |
441 | 440 | ||
@@ -4296,9 +4295,6 @@ static int md_alloc(dev_t dev, char *name) | |||
4296 | goto abort; | 4295 | goto abort; |
4297 | mddev->queue->queuedata = mddev; | 4296 | mddev->queue->queuedata = mddev; |
4298 | 4297 | ||
4299 | /* Can be unlocked because the queue is new: no concurrency */ | ||
4300 | queue_flag_set_unlocked(QUEUE_FLAG_CLUSTER, mddev->queue); | ||
4301 | |||
4302 | blk_queue_make_request(mddev->queue, md_make_request); | 4298 | blk_queue_make_request(mddev->queue, md_make_request); |
4303 | 4299 | ||
4304 | disk = alloc_disk(1 << shift); | 4300 | disk = alloc_disk(1 << shift); |
@@ -5160,7 +5156,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) | |||
5160 | PTR_ERR(rdev)); | 5156 | PTR_ERR(rdev)); |
5161 | return PTR_ERR(rdev); | 5157 | return PTR_ERR(rdev); |
5162 | } | 5158 | } |
5163 | /* set save_raid_disk if appropriate */ | 5159 | /* set saved_raid_disk if appropriate */ |
5164 | if (!mddev->persistent) { | 5160 | if (!mddev->persistent) { |
5165 | if (info->state & (1<<MD_DISK_SYNC) && | 5161 | if (info->state & (1<<MD_DISK_SYNC) && |
5166 | info->raid_disk < mddev->raid_disks) | 5162 | info->raid_disk < mddev->raid_disks) |
@@ -5170,7 +5166,10 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) | |||
5170 | } else | 5166 | } else |
5171 | super_types[mddev->major_version]. | 5167 | super_types[mddev->major_version]. |
5172 | validate_super(mddev, rdev); | 5168 | validate_super(mddev, rdev); |
5173 | rdev->saved_raid_disk = rdev->raid_disk; | 5169 | if (test_bit(In_sync, &rdev->flags)) |
5170 | rdev->saved_raid_disk = rdev->raid_disk; | ||
5171 | else | ||
5172 | rdev->saved_raid_disk = -1; | ||
5174 | 5173 | ||
5175 | clear_bit(In_sync, &rdev->flags); /* just to be sure */ | 5174 | clear_bit(In_sync, &rdev->flags); /* just to be sure */ |
5176 | if (info->state & (1<<MD_DISK_WRITEMOSTLY)) | 5175 | if (info->state & (1<<MD_DISK_WRITEMOSTLY)) |
@@ -6042,9 +6041,8 @@ static int md_thread(void * arg) | |||
6042 | || kthread_should_stop(), | 6041 | || kthread_should_stop(), |
6043 | thread->timeout); | 6042 | thread->timeout); |
6044 | 6043 | ||
6045 | clear_bit(THREAD_WAKEUP, &thread->flags); | 6044 | if (test_and_clear_bit(THREAD_WAKEUP, &thread->flags)) |
6046 | 6045 | thread->run(thread->mddev); | |
6047 | thread->run(thread->mddev); | ||
6048 | } | 6046 | } |
6049 | 6047 | ||
6050 | return 0; | 6048 | return 0; |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index c67aa54694ae..0641674827f0 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -2397,13 +2397,13 @@ static int run(mddev_t *mddev) | |||
2397 | return 0; | 2397 | return 0; |
2398 | 2398 | ||
2399 | out_free_conf: | 2399 | out_free_conf: |
2400 | md_unregister_thread(mddev->thread); | ||
2400 | if (conf->r10bio_pool) | 2401 | if (conf->r10bio_pool) |
2401 | mempool_destroy(conf->r10bio_pool); | 2402 | mempool_destroy(conf->r10bio_pool); |
2402 | safe_put_page(conf->tmppage); | 2403 | safe_put_page(conf->tmppage); |
2403 | kfree(conf->mirrors); | 2404 | kfree(conf->mirrors); |
2404 | kfree(conf); | 2405 | kfree(conf); |
2405 | mddev->private = NULL; | 2406 | mddev->private = NULL; |
2406 | md_unregister_thread(mddev->thread); | ||
2407 | out: | 2407 | out: |
2408 | return -EIO; | 2408 | return -EIO; |
2409 | } | 2409 | } |
diff --git a/drivers/media/IR/keymaps/rc-rc6-mce.c b/drivers/media/IR/keymaps/rc-rc6-mce.c index 1b7adabbcee9..6da955dfef48 100644 --- a/drivers/media/IR/keymaps/rc-rc6-mce.c +++ b/drivers/media/IR/keymaps/rc-rc6-mce.c | |||
@@ -26,8 +26,8 @@ static struct ir_scancode rc6_mce[] = { | |||
26 | 26 | ||
27 | { 0x800f040a, KEY_DELETE }, | 27 | { 0x800f040a, KEY_DELETE }, |
28 | { 0x800f040b, KEY_ENTER }, | 28 | { 0x800f040b, KEY_ENTER }, |
29 | { 0x800f040c, KEY_POWER }, | 29 | { 0x800f040c, KEY_POWER }, /* PC Power */ |
30 | { 0x800f040d, KEY_PROG1 }, /* Windows MCE button */ | 30 | { 0x800f040d, KEY_PROG1 }, /* Windows MCE button */ |
31 | { 0x800f040e, KEY_MUTE }, | 31 | { 0x800f040e, KEY_MUTE }, |
32 | { 0x800f040f, KEY_INFO }, | 32 | { 0x800f040f, KEY_INFO }, |
33 | 33 | ||
@@ -56,31 +56,32 @@ static struct ir_scancode rc6_mce[] = { | |||
56 | { 0x800f0422, KEY_OK }, | 56 | { 0x800f0422, KEY_OK }, |
57 | { 0x800f0423, KEY_EXIT }, | 57 | { 0x800f0423, KEY_EXIT }, |
58 | { 0x800f0424, KEY_DVD }, | 58 | { 0x800f0424, KEY_DVD }, |
59 | { 0x800f0425, KEY_TUNER }, /* LiveTV */ | 59 | { 0x800f0425, KEY_TUNER }, /* LiveTV */ |
60 | { 0x800f0426, KEY_EPG }, /* Guide */ | 60 | { 0x800f0426, KEY_EPG }, /* Guide */ |
61 | { 0x800f0427, KEY_ZOOM }, /* Aspect */ | 61 | { 0x800f0427, KEY_ZOOM }, /* Aspect */ |
62 | 62 | ||
63 | { 0x800f043a, KEY_BRIGHTNESSUP }, | 63 | { 0x800f043a, KEY_BRIGHTNESSUP }, |
64 | 64 | ||
65 | { 0x800f0446, KEY_TV }, | 65 | { 0x800f0446, KEY_TV }, |
66 | { 0x800f0447, KEY_AUDIO }, /* My Music */ | 66 | { 0x800f0447, KEY_AUDIO }, /* My Music */ |
67 | { 0x800f0448, KEY_PVR }, /* RecordedTV */ | 67 | { 0x800f0448, KEY_PVR }, /* RecordedTV */ |
68 | { 0x800f0449, KEY_CAMERA }, | 68 | { 0x800f0449, KEY_CAMERA }, |
69 | { 0x800f044a, KEY_VIDEO }, | 69 | { 0x800f044a, KEY_VIDEO }, |
70 | { 0x800f044c, KEY_LANGUAGE }, | 70 | { 0x800f044c, KEY_LANGUAGE }, |
71 | { 0x800f044d, KEY_TITLE }, | 71 | { 0x800f044d, KEY_TITLE }, |
72 | { 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */ | 72 | { 0x800f044e, KEY_PRINT }, /* Print - HP OEM version of remote */ |
73 | 73 | ||
74 | { 0x800f0450, KEY_RADIO }, | 74 | { 0x800f0450, KEY_RADIO }, |
75 | 75 | ||
76 | { 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */ | 76 | { 0x800f045a, KEY_SUBTITLE }, /* Caption/Teletext */ |
77 | { 0x800f045b, KEY_RED }, | 77 | { 0x800f045b, KEY_RED }, |
78 | { 0x800f045c, KEY_GREEN }, | 78 | { 0x800f045c, KEY_GREEN }, |
79 | { 0x800f045d, KEY_YELLOW }, | 79 | { 0x800f045d, KEY_YELLOW }, |
80 | { 0x800f045e, KEY_BLUE }, | 80 | { 0x800f045e, KEY_BLUE }, |
81 | 81 | ||
82 | { 0x800f0465, KEY_POWER2 }, /* TV Power */ | ||
82 | { 0x800f046e, KEY_PLAYPAUSE }, | 83 | { 0x800f046e, KEY_PLAYPAUSE }, |
83 | { 0x800f046f, KEY_MEDIA }, /* Start media application (NEW) */ | 84 | { 0x800f046f, KEY_MEDIA }, /* Start media application (NEW) */ |
84 | 85 | ||
85 | { 0x800f0480, KEY_BRIGHTNESSDOWN }, | 86 | { 0x800f0480, KEY_BRIGHTNESSDOWN }, |
86 | { 0x800f0481, KEY_PLAYPAUSE }, | 87 | { 0x800f0481, KEY_PLAYPAUSE }, |
diff --git a/drivers/media/IR/lirc_dev.c b/drivers/media/IR/lirc_dev.c index 8418b14ee4d2..756656e17bdd 100644 --- a/drivers/media/IR/lirc_dev.c +++ b/drivers/media/IR/lirc_dev.c | |||
@@ -522,10 +522,8 @@ unsigned int lirc_dev_fop_poll(struct file *file, poll_table *wait) | |||
522 | 522 | ||
523 | dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor); | 523 | dev_dbg(ir->d.dev, LOGHEAD "poll called\n", ir->d.name, ir->d.minor); |
524 | 524 | ||
525 | if (!ir->attached) { | 525 | if (!ir->attached) |
526 | mutex_unlock(&ir->irctl_lock); | ||
527 | return POLLERR; | 526 | return POLLERR; |
528 | } | ||
529 | 527 | ||
530 | poll_wait(file, &ir->buf->wait_poll, wait); | 528 | poll_wait(file, &ir->buf->wait_poll, wait); |
531 | 529 | ||
@@ -649,18 +647,18 @@ ssize_t lirc_dev_fop_read(struct file *file, | |||
649 | if (!buf) | 647 | if (!buf) |
650 | return -ENOMEM; | 648 | return -ENOMEM; |
651 | 649 | ||
652 | if (mutex_lock_interruptible(&ir->irctl_lock)) | 650 | if (mutex_lock_interruptible(&ir->irctl_lock)) { |
653 | return -ERESTARTSYS; | 651 | ret = -ERESTARTSYS; |
652 | goto out_unlocked; | ||
653 | } | ||
654 | if (!ir->attached) { | 654 | if (!ir->attached) { |
655 | mutex_unlock(&ir->irctl_lock); | 655 | ret = -ENODEV; |
656 | return -ENODEV; | 656 | goto out_locked; |
657 | } | 657 | } |
658 | 658 | ||
659 | if (length % ir->chunk_size) { | 659 | if (length % ir->chunk_size) { |
660 | dev_dbg(ir->d.dev, LOGHEAD "read result = -EINVAL\n", | 660 | ret = -EINVAL; |
661 | ir->d.name, ir->d.minor); | 661 | goto out_locked; |
662 | mutex_unlock(&ir->irctl_lock); | ||
663 | return -EINVAL; | ||
664 | } | 662 | } |
665 | 663 | ||
666 | /* | 664 | /* |
@@ -711,18 +709,23 @@ ssize_t lirc_dev_fop_read(struct file *file, | |||
711 | lirc_buffer_read(ir->buf, buf); | 709 | lirc_buffer_read(ir->buf, buf); |
712 | ret = copy_to_user((void *)buffer+written, buf, | 710 | ret = copy_to_user((void *)buffer+written, buf, |
713 | ir->buf->chunk_size); | 711 | ir->buf->chunk_size); |
714 | written += ir->buf->chunk_size; | 712 | if (!ret) |
713 | written += ir->buf->chunk_size; | ||
714 | else | ||
715 | ret = -EFAULT; | ||
715 | } | 716 | } |
716 | } | 717 | } |
717 | 718 | ||
718 | remove_wait_queue(&ir->buf->wait_poll, &wait); | 719 | remove_wait_queue(&ir->buf->wait_poll, &wait); |
719 | set_current_state(TASK_RUNNING); | 720 | set_current_state(TASK_RUNNING); |
721 | |||
722 | out_locked: | ||
720 | mutex_unlock(&ir->irctl_lock); | 723 | mutex_unlock(&ir->irctl_lock); |
721 | 724 | ||
722 | out_unlocked: | 725 | out_unlocked: |
723 | kfree(buf); | 726 | kfree(buf); |
724 | dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n", | 727 | dev_dbg(ir->d.dev, LOGHEAD "read result = %s (%d)\n", |
725 | ir->d.name, ir->d.minor, ret ? "-EFAULT" : "OK", ret); | 728 | ir->d.name, ir->d.minor, ret ? "<fail>" : "<ok>", ret); |
726 | 729 | ||
727 | return ret ? ret : written; | 730 | return ret ? ret : written; |
728 | } | 731 | } |
diff --git a/drivers/media/IR/mceusb.c b/drivers/media/IR/mceusb.c index 9dce684fd231..392ca24132da 100644 --- a/drivers/media/IR/mceusb.c +++ b/drivers/media/IR/mceusb.c | |||
@@ -35,10 +35,10 @@ | |||
35 | #include <linux/device.h> | 35 | #include <linux/device.h> |
36 | #include <linux/module.h> | 36 | #include <linux/module.h> |
37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
38 | #include <linux/usb.h> | ||
39 | #include <linux/input.h> | 38 | #include <linux/input.h> |
39 | #include <linux/usb.h> | ||
40 | #include <linux/usb/input.h> | ||
40 | #include <media/ir-core.h> | 41 | #include <media/ir-core.h> |
41 | #include <media/ir-common.h> | ||
42 | 42 | ||
43 | #define DRIVER_VERSION "1.91" | 43 | #define DRIVER_VERSION "1.91" |
44 | #define DRIVER_AUTHOR "Jarod Wilson <jarod@wilsonet.com>" | 44 | #define DRIVER_AUTHOR "Jarod Wilson <jarod@wilsonet.com>" |
@@ -49,6 +49,7 @@ | |||
49 | #define USB_BUFLEN 32 /* USB reception buffer length */ | 49 | #define USB_BUFLEN 32 /* USB reception buffer length */ |
50 | #define USB_CTRL_MSG_SZ 2 /* Size of usb ctrl msg on gen1 hw */ | 50 | #define USB_CTRL_MSG_SZ 2 /* Size of usb ctrl msg on gen1 hw */ |
51 | #define MCE_G1_INIT_MSGS 40 /* Init messages on gen1 hw to throw out */ | 51 | #define MCE_G1_INIT_MSGS 40 /* Init messages on gen1 hw to throw out */ |
52 | #define MS_TO_NS(msec) ((msec) * 1000) | ||
52 | 53 | ||
53 | /* MCE constants */ | 54 | /* MCE constants */ |
54 | #define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */ | 55 | #define MCE_CMDBUF_SIZE 384 /* MCE Command buffer length */ |
@@ -74,6 +75,7 @@ | |||
74 | #define MCE_PACKET_LENGTH_MASK 0x1f /* Packet length mask */ | 75 | #define MCE_PACKET_LENGTH_MASK 0x1f /* Packet length mask */ |
75 | 76 | ||
76 | /* Sub-commands, which follow MCE_COMMAND_HEADER or MCE_HW_CMD_HEADER */ | 77 | /* Sub-commands, which follow MCE_COMMAND_HEADER or MCE_HW_CMD_HEADER */ |
78 | #define MCE_CMD_SIG_END 0x01 /* End of signal */ | ||
77 | #define MCE_CMD_PING 0x03 /* Ping device */ | 79 | #define MCE_CMD_PING 0x03 /* Ping device */ |
78 | #define MCE_CMD_UNKNOWN 0x04 /* Unknown */ | 80 | #define MCE_CMD_UNKNOWN 0x04 /* Unknown */ |
79 | #define MCE_CMD_UNKNOWN2 0x05 /* Unknown */ | 81 | #define MCE_CMD_UNKNOWN2 0x05 /* Unknown */ |
@@ -91,6 +93,7 @@ | |||
91 | #define MCE_CMD_G_TXMASK 0x13 /* Set TX port bitmask */ | 93 | #define MCE_CMD_G_TXMASK 0x13 /* Set TX port bitmask */ |
92 | #define MCE_CMD_S_RXSENSOR 0x14 /* Set RX sensor (std/learning) */ | 94 | #define MCE_CMD_S_RXSENSOR 0x14 /* Set RX sensor (std/learning) */ |
93 | #define MCE_CMD_G_RXSENSOR 0x15 /* Get RX sensor (std/learning) */ | 95 | #define MCE_CMD_G_RXSENSOR 0x15 /* Get RX sensor (std/learning) */ |
96 | #define MCE_RSP_PULSE_COUNT 0x15 /* RX pulse count (only if learning) */ | ||
94 | #define MCE_CMD_TX_PORTS 0x16 /* Get number of TX ports */ | 97 | #define MCE_CMD_TX_PORTS 0x16 /* Get number of TX ports */ |
95 | #define MCE_CMD_G_WAKESRC 0x17 /* Get wake source */ | 98 | #define MCE_CMD_G_WAKESRC 0x17 /* Get wake source */ |
96 | #define MCE_CMD_UNKNOWN7 0x18 /* Unknown */ | 99 | #define MCE_CMD_UNKNOWN7 0x18 /* Unknown */ |
@@ -146,14 +149,16 @@ enum mceusb_model_type { | |||
146 | MCE_GEN3, | 149 | MCE_GEN3, |
147 | MCE_GEN2_TX_INV, | 150 | MCE_GEN2_TX_INV, |
148 | POLARIS_EVK, | 151 | POLARIS_EVK, |
152 | CX_HYBRID_TV, | ||
149 | }; | 153 | }; |
150 | 154 | ||
151 | struct mceusb_model { | 155 | struct mceusb_model { |
152 | u32 mce_gen1:1; | 156 | u32 mce_gen1:1; |
153 | u32 mce_gen2:1; | 157 | u32 mce_gen2:1; |
154 | u32 mce_gen3:1; | 158 | u32 mce_gen3:1; |
155 | u32 tx_mask_inverted:1; | 159 | u32 tx_mask_normal:1; |
156 | u32 is_polaris:1; | 160 | u32 is_polaris:1; |
161 | u32 no_tx:1; | ||
157 | 162 | ||
158 | const char *rc_map; /* Allow specify a per-board map */ | 163 | const char *rc_map; /* Allow specify a per-board map */ |
159 | const char *name; /* per-board name */ | 164 | const char *name; /* per-board name */ |
@@ -162,18 +167,18 @@ struct mceusb_model { | |||
162 | static const struct mceusb_model mceusb_model[] = { | 167 | static const struct mceusb_model mceusb_model[] = { |
163 | [MCE_GEN1] = { | 168 | [MCE_GEN1] = { |
164 | .mce_gen1 = 1, | 169 | .mce_gen1 = 1, |
165 | .tx_mask_inverted = 1, | 170 | .tx_mask_normal = 1, |
166 | }, | 171 | }, |
167 | [MCE_GEN2] = { | 172 | [MCE_GEN2] = { |
168 | .mce_gen2 = 1, | 173 | .mce_gen2 = 1, |
169 | }, | 174 | }, |
170 | [MCE_GEN2_TX_INV] = { | 175 | [MCE_GEN2_TX_INV] = { |
171 | .mce_gen2 = 1, | 176 | .mce_gen2 = 1, |
172 | .tx_mask_inverted = 1, | 177 | .tx_mask_normal = 1, |
173 | }, | 178 | }, |
174 | [MCE_GEN3] = { | 179 | [MCE_GEN3] = { |
175 | .mce_gen3 = 1, | 180 | .mce_gen3 = 1, |
176 | .tx_mask_inverted = 1, | 181 | .tx_mask_normal = 1, |
177 | }, | 182 | }, |
178 | [POLARIS_EVK] = { | 183 | [POLARIS_EVK] = { |
179 | .is_polaris = 1, | 184 | .is_polaris = 1, |
@@ -183,7 +188,12 @@ static const struct mceusb_model mceusb_model[] = { | |||
183 | * to allow testing it | 188 | * to allow testing it |
184 | */ | 189 | */ |
185 | .rc_map = RC_MAP_RC5_HAUPPAUGE_NEW, | 190 | .rc_map = RC_MAP_RC5_HAUPPAUGE_NEW, |
186 | .name = "cx231xx MCE IR", | 191 | .name = "Conexant Hybrid TV (cx231xx) MCE IR", |
192 | }, | ||
193 | [CX_HYBRID_TV] = { | ||
194 | .is_polaris = 1, | ||
195 | .no_tx = 1, /* tx isn't wired up at all */ | ||
196 | .name = "Conexant Hybrid TV (cx231xx) MCE IR", | ||
187 | }, | 197 | }, |
188 | }; | 198 | }; |
189 | 199 | ||
@@ -273,6 +283,8 @@ static struct usb_device_id mceusb_dev_table[] = { | |||
273 | { USB_DEVICE(VENDOR_FORMOSA, 0xe03c) }, | 283 | { USB_DEVICE(VENDOR_FORMOSA, 0xe03c) }, |
274 | /* Formosa Industrial Computing */ | 284 | /* Formosa Industrial Computing */ |
275 | { USB_DEVICE(VENDOR_FORMOSA, 0xe03e) }, | 285 | { USB_DEVICE(VENDOR_FORMOSA, 0xe03e) }, |
286 | /* Fintek eHome Infrared Transceiver (HP branded) */ | ||
287 | { USB_DEVICE(VENDOR_FINTEK, 0x5168) }, | ||
276 | /* Fintek eHome Infrared Transceiver */ | 288 | /* Fintek eHome Infrared Transceiver */ |
277 | { USB_DEVICE(VENDOR_FINTEK, 0x0602) }, | 289 | { USB_DEVICE(VENDOR_FINTEK, 0x0602) }, |
278 | /* Fintek eHome Infrared Transceiver (in the AOpen MP45) */ | 290 | /* Fintek eHome Infrared Transceiver (in the AOpen MP45) */ |
@@ -292,9 +304,12 @@ static struct usb_device_id mceusb_dev_table[] = { | |||
292 | { USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) }, | 304 | { USB_DEVICE(VENDOR_NORTHSTAR, 0xe004) }, |
293 | /* TiVo PC IR Receiver */ | 305 | /* TiVo PC IR Receiver */ |
294 | { USB_DEVICE(VENDOR_TIVO, 0x2000) }, | 306 | { USB_DEVICE(VENDOR_TIVO, 0x2000) }, |
295 | /* Conexant SDK */ | 307 | /* Conexant Hybrid TV "Shelby" Polaris SDK */ |
296 | { USB_DEVICE(VENDOR_CONEXANT, 0x58a1), | 308 | { USB_DEVICE(VENDOR_CONEXANT, 0x58a1), |
297 | .driver_info = POLARIS_EVK }, | 309 | .driver_info = POLARIS_EVK }, |
310 | /* Conexant Hybrid TV RDU253S Polaris */ | ||
311 | { USB_DEVICE(VENDOR_CONEXANT, 0x58a5), | ||
312 | .driver_info = CX_HYBRID_TV }, | ||
298 | /* Terminating entry */ | 313 | /* Terminating entry */ |
299 | { } | 314 | { } |
300 | }; | 315 | }; |
@@ -303,7 +318,10 @@ static struct usb_device_id mceusb_dev_table[] = { | |||
303 | struct mceusb_dev { | 318 | struct mceusb_dev { |
304 | /* ir-core bits */ | 319 | /* ir-core bits */ |
305 | struct ir_dev_props *props; | 320 | struct ir_dev_props *props; |
306 | struct ir_raw_event rawir; | 321 | |
322 | /* optional features we can enable */ | ||
323 | bool carrier_report_enabled; | ||
324 | bool learning_enabled; | ||
307 | 325 | ||
308 | /* core device bits */ | 326 | /* core device bits */ |
309 | struct device *dev; | 327 | struct device *dev; |
@@ -318,6 +336,8 @@ struct mceusb_dev { | |||
318 | /* buffers and dma */ | 336 | /* buffers and dma */ |
319 | unsigned char *buf_in; | 337 | unsigned char *buf_in; |
320 | unsigned int len_in; | 338 | unsigned int len_in; |
339 | dma_addr_t dma_in; | ||
340 | dma_addr_t dma_out; | ||
321 | 341 | ||
322 | enum { | 342 | enum { |
323 | CMD_HEADER = 0, | 343 | CMD_HEADER = 0, |
@@ -325,15 +345,14 @@ struct mceusb_dev { | |||
325 | CMD_DATA, | 345 | CMD_DATA, |
326 | PARSE_IRDATA, | 346 | PARSE_IRDATA, |
327 | } parser_state; | 347 | } parser_state; |
328 | u8 cmd, rem; /* Remaining IR data bytes in packet */ | ||
329 | 348 | ||
330 | dma_addr_t dma_in; | 349 | u8 cmd, rem; /* Remaining IR data bytes in packet */ |
331 | dma_addr_t dma_out; | ||
332 | 350 | ||
333 | struct { | 351 | struct { |
334 | u32 connected:1; | 352 | u32 connected:1; |
335 | u32 tx_mask_inverted:1; | 353 | u32 tx_mask_normal:1; |
336 | u32 microsoft_gen1:1; | 354 | u32 microsoft_gen1:1; |
355 | u32 no_tx:1; | ||
337 | } flags; | 356 | } flags; |
338 | 357 | ||
339 | /* transmit support */ | 358 | /* transmit support */ |
@@ -408,9 +427,10 @@ static int mceusb_cmdsize(u8 cmd, u8 subcmd) | |||
408 | case MCE_CMD_UNKNOWN: | 427 | case MCE_CMD_UNKNOWN: |
409 | case MCE_CMD_S_CARRIER: | 428 | case MCE_CMD_S_CARRIER: |
410 | case MCE_CMD_S_TIMEOUT: | 429 | case MCE_CMD_S_TIMEOUT: |
411 | case MCE_CMD_G_RXSENSOR: | 430 | case MCE_RSP_PULSE_COUNT: |
412 | datasize = 2; | 431 | datasize = 2; |
413 | break; | 432 | break; |
433 | case MCE_CMD_SIG_END: | ||
414 | case MCE_CMD_S_TXMASK: | 434 | case MCE_CMD_S_TXMASK: |
415 | case MCE_CMD_S_RXSENSOR: | 435 | case MCE_CMD_S_RXSENSOR: |
416 | datasize = 1; | 436 | datasize = 1; |
@@ -433,7 +453,7 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, | |||
433 | return; | 453 | return; |
434 | 454 | ||
435 | /* skip meaningless 0xb1 0x60 header bytes on orig receiver */ | 455 | /* skip meaningless 0xb1 0x60 header bytes on orig receiver */ |
436 | if (ir->flags.microsoft_gen1 && !out) | 456 | if (ir->flags.microsoft_gen1 && !out && !offset) |
437 | skip = 2; | 457 | skip = 2; |
438 | 458 | ||
439 | if (len <= skip) | 459 | if (len <= skip) |
@@ -491,6 +511,9 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, | |||
491 | break; | 511 | break; |
492 | case MCE_COMMAND_HEADER: | 512 | case MCE_COMMAND_HEADER: |
493 | switch (subcmd) { | 513 | switch (subcmd) { |
514 | case MCE_CMD_SIG_END: | ||
515 | dev_info(dev, "End of signal\n"); | ||
516 | break; | ||
494 | case MCE_CMD_PING: | 517 | case MCE_CMD_PING: |
495 | dev_info(dev, "Ping\n"); | 518 | dev_info(dev, "Ping\n"); |
496 | break; | 519 | break; |
@@ -525,10 +548,11 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, | |||
525 | inout, data1 == 0x02 ? "short" : "long"); | 548 | inout, data1 == 0x02 ? "short" : "long"); |
526 | break; | 549 | break; |
527 | case MCE_CMD_G_RXSENSOR: | 550 | case MCE_CMD_G_RXSENSOR: |
528 | if (len == 2) | 551 | /* aka MCE_RSP_PULSE_COUNT */ |
552 | if (out) | ||
529 | dev_info(dev, "Get receive sensor\n"); | 553 | dev_info(dev, "Get receive sensor\n"); |
530 | else | 554 | else if (ir->learning_enabled) |
531 | dev_info(dev, "Received pulse count is %d\n", | 555 | dev_info(dev, "RX pulse count: %d\n", |
532 | ((data1 << 8) | data2)); | 556 | ((data1 << 8) | data2)); |
533 | break; | 557 | break; |
534 | case MCE_RSP_CMD_INVALID: | 558 | case MCE_RSP_CMD_INVALID: |
@@ -724,16 +748,16 @@ out: | |||
724 | return ret ? ret : n; | 748 | return ret ? ret : n; |
725 | } | 749 | } |
726 | 750 | ||
727 | /* Sets active IR outputs -- mce devices typically (all?) have two */ | 751 | /* Sets active IR outputs -- mce devices typically have two */ |
728 | static int mceusb_set_tx_mask(void *priv, u32 mask) | 752 | static int mceusb_set_tx_mask(void *priv, u32 mask) |
729 | { | 753 | { |
730 | struct mceusb_dev *ir = priv; | 754 | struct mceusb_dev *ir = priv; |
731 | 755 | ||
732 | if (ir->flags.tx_mask_inverted) | 756 | if (ir->flags.tx_mask_normal) |
757 | ir->tx_mask = mask; | ||
758 | else | ||
733 | ir->tx_mask = (mask != MCE_DEFAULT_TX_MASK ? | 759 | ir->tx_mask = (mask != MCE_DEFAULT_TX_MASK ? |
734 | mask ^ MCE_DEFAULT_TX_MASK : mask) << 1; | 760 | mask ^ MCE_DEFAULT_TX_MASK : mask) << 1; |
735 | else | ||
736 | ir->tx_mask = mask; | ||
737 | 761 | ||
738 | return 0; | 762 | return 0; |
739 | } | 763 | } |
@@ -752,7 +776,7 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier) | |||
752 | 776 | ||
753 | if (carrier == 0) { | 777 | if (carrier == 0) { |
754 | ir->carrier = carrier; | 778 | ir->carrier = carrier; |
755 | cmdbuf[2] = 0x01; | 779 | cmdbuf[2] = MCE_CMD_SIG_END; |
756 | cmdbuf[3] = MCE_IRDATA_TRAILER; | 780 | cmdbuf[3] = MCE_IRDATA_TRAILER; |
757 | dev_dbg(ir->dev, "%s: disabling carrier " | 781 | dev_dbg(ir->dev, "%s: disabling carrier " |
758 | "modulation\n", __func__); | 782 | "modulation\n", __func__); |
@@ -782,6 +806,34 @@ static int mceusb_set_tx_carrier(void *priv, u32 carrier) | |||
782 | return carrier; | 806 | return carrier; |
783 | } | 807 | } |
784 | 808 | ||
809 | /* | ||
810 | * We don't do anything but print debug spew for many of the command bits | ||
811 | * we receive from the hardware, but some of them are useful information | ||
812 | * we want to store so that we can use them. | ||
813 | */ | ||
814 | static void mceusb_handle_command(struct mceusb_dev *ir, int index) | ||
815 | { | ||
816 | u8 hi = ir->buf_in[index + 1] & 0xff; | ||
817 | u8 lo = ir->buf_in[index + 2] & 0xff; | ||
818 | |||
819 | switch (ir->buf_in[index]) { | ||
820 | /* 2-byte return value commands */ | ||
821 | case MCE_CMD_S_TIMEOUT: | ||
822 | ir->props->timeout = MS_TO_NS((hi << 8 | lo) / 2); | ||
823 | break; | ||
824 | |||
825 | /* 1-byte return value commands */ | ||
826 | case MCE_CMD_S_TXMASK: | ||
827 | ir->tx_mask = hi; | ||
828 | break; | ||
829 | case MCE_CMD_S_RXSENSOR: | ||
830 | ir->learning_enabled = (hi == 0x02); | ||
831 | break; | ||
832 | default: | ||
833 | break; | ||
834 | } | ||
835 | } | ||
836 | |||
785 | static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) | 837 | static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) |
786 | { | 838 | { |
787 | DEFINE_IR_RAW_EVENT(rawir); | 839 | DEFINE_IR_RAW_EVENT(rawir); |
@@ -791,39 +843,30 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) | |||
791 | if (ir->flags.microsoft_gen1) | 843 | if (ir->flags.microsoft_gen1) |
792 | i = 2; | 844 | i = 2; |
793 | 845 | ||
846 | /* if there's no data, just return now */ | ||
847 | if (buf_len <= i) | ||
848 | return; | ||
849 | |||
794 | for (; i < buf_len; i++) { | 850 | for (; i < buf_len; i++) { |
795 | switch (ir->parser_state) { | 851 | switch (ir->parser_state) { |
796 | case SUBCMD: | 852 | case SUBCMD: |
797 | ir->rem = mceusb_cmdsize(ir->cmd, ir->buf_in[i]); | 853 | ir->rem = mceusb_cmdsize(ir->cmd, ir->buf_in[i]); |
798 | mceusb_dev_printdata(ir, ir->buf_in, i - 1, | 854 | mceusb_dev_printdata(ir, ir->buf_in, i - 1, |
799 | ir->rem + 2, false); | 855 | ir->rem + 2, false); |
856 | mceusb_handle_command(ir, i); | ||
800 | ir->parser_state = CMD_DATA; | 857 | ir->parser_state = CMD_DATA; |
801 | break; | 858 | break; |
802 | case PARSE_IRDATA: | 859 | case PARSE_IRDATA: |
803 | ir->rem--; | 860 | ir->rem--; |
804 | rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0); | 861 | rawir.pulse = ((ir->buf_in[i] & MCE_PULSE_BIT) != 0); |
805 | rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK) | 862 | rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK) |
806 | * MCE_TIME_UNIT * 1000; | 863 | * MS_TO_NS(MCE_TIME_UNIT); |
807 | |||
808 | if ((ir->buf_in[i] & MCE_PULSE_MASK) == 0x7f) { | ||
809 | if (ir->rawir.pulse == rawir.pulse) { | ||
810 | ir->rawir.duration += rawir.duration; | ||
811 | } else { | ||
812 | ir->rawir.duration = rawir.duration; | ||
813 | ir->rawir.pulse = rawir.pulse; | ||
814 | } | ||
815 | if (ir->rem) | ||
816 | break; | ||
817 | } | ||
818 | rawir.duration += ir->rawir.duration; | ||
819 | ir->rawir.duration = 0; | ||
820 | ir->rawir.pulse = rawir.pulse; | ||
821 | 864 | ||
822 | dev_dbg(ir->dev, "Storing %s with duration %d\n", | 865 | dev_dbg(ir->dev, "Storing %s with duration %d\n", |
823 | rawir.pulse ? "pulse" : "space", | 866 | rawir.pulse ? "pulse" : "space", |
824 | rawir.duration); | 867 | rawir.duration); |
825 | 868 | ||
826 | ir_raw_event_store(ir->idev, &rawir); | 869 | ir_raw_event_store_with_filter(ir->idev, &rawir); |
827 | break; | 870 | break; |
828 | case CMD_DATA: | 871 | case CMD_DATA: |
829 | ir->rem--; | 872 | ir->rem--; |
@@ -839,17 +882,10 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) | |||
839 | continue; | 882 | continue; |
840 | } | 883 | } |
841 | ir->rem = (ir->cmd & MCE_PACKET_LENGTH_MASK); | 884 | ir->rem = (ir->cmd & MCE_PACKET_LENGTH_MASK); |
842 | mceusb_dev_printdata(ir, ir->buf_in, i, ir->rem + 1, false); | 885 | mceusb_dev_printdata(ir, ir->buf_in, |
843 | if (ir->rem) { | 886 | i, ir->rem + 1, false); |
887 | if (ir->rem) | ||
844 | ir->parser_state = PARSE_IRDATA; | 888 | ir->parser_state = PARSE_IRDATA; |
845 | break; | ||
846 | } | ||
847 | /* | ||
848 | * a package with len=0 (e. g. 0x80) means end of | ||
849 | * data. We could use it to do the call to | ||
850 | * ir_raw_event_handle(). For now, we don't need to | ||
851 | * use it. | ||
852 | */ | ||
853 | break; | 889 | break; |
854 | } | 890 | } |
855 | 891 | ||
@@ -984,9 +1020,11 @@ static void mceusb_get_parameters(struct mceusb_dev *ir) | |||
984 | mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ)); | 1020 | mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ)); |
985 | mce_sync_in(ir, NULL, maxp); | 1021 | mce_sync_in(ir, NULL, maxp); |
986 | 1022 | ||
987 | /* get the transmitter bitmask */ | 1023 | if (!ir->flags.no_tx) { |
988 | mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK)); | 1024 | /* get the transmitter bitmask */ |
989 | mce_sync_in(ir, NULL, maxp); | 1025 | mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK)); |
1026 | mce_sync_in(ir, NULL, maxp); | ||
1027 | } | ||
990 | 1028 | ||
991 | /* get receiver timeout value */ | 1029 | /* get receiver timeout value */ |
992 | mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT)); | 1030 | mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT)); |
@@ -1035,12 +1073,18 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir) | |||
1035 | props->priv = ir; | 1073 | props->priv = ir; |
1036 | props->driver_type = RC_DRIVER_IR_RAW; | 1074 | props->driver_type = RC_DRIVER_IR_RAW; |
1037 | props->allowed_protos = IR_TYPE_ALL; | 1075 | props->allowed_protos = IR_TYPE_ALL; |
1038 | props->s_tx_mask = mceusb_set_tx_mask; | 1076 | props->timeout = MS_TO_NS(1000); |
1039 | props->s_tx_carrier = mceusb_set_tx_carrier; | 1077 | if (!ir->flags.no_tx) { |
1040 | props->tx_ir = mceusb_tx_ir; | 1078 | props->s_tx_mask = mceusb_set_tx_mask; |
1079 | props->s_tx_carrier = mceusb_set_tx_carrier; | ||
1080 | props->tx_ir = mceusb_tx_ir; | ||
1081 | } | ||
1041 | 1082 | ||
1042 | ir->props = props; | 1083 | ir->props = props; |
1043 | 1084 | ||
1085 | usb_to_input_id(ir->usbdev, &idev->id); | ||
1086 | idev->dev.parent = ir->dev; | ||
1087 | |||
1044 | if (mceusb_model[ir->model].rc_map) | 1088 | if (mceusb_model[ir->model].rc_map) |
1045 | rc_map = mceusb_model[ir->model].rc_map; | 1089 | rc_map = mceusb_model[ir->model].rc_map; |
1046 | 1090 | ||
@@ -1074,16 +1118,16 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, | |||
1074 | enum mceusb_model_type model = id->driver_info; | 1118 | enum mceusb_model_type model = id->driver_info; |
1075 | bool is_gen3; | 1119 | bool is_gen3; |
1076 | bool is_microsoft_gen1; | 1120 | bool is_microsoft_gen1; |
1077 | bool tx_mask_inverted; | 1121 | bool tx_mask_normal; |
1078 | bool is_polaris; | 1122 | bool is_polaris; |
1079 | 1123 | ||
1080 | dev_dbg(&intf->dev, ": %s called\n", __func__); | 1124 | dev_dbg(&intf->dev, "%s called\n", __func__); |
1081 | 1125 | ||
1082 | idesc = intf->cur_altsetting; | 1126 | idesc = intf->cur_altsetting; |
1083 | 1127 | ||
1084 | is_gen3 = mceusb_model[model].mce_gen3; | 1128 | is_gen3 = mceusb_model[model].mce_gen3; |
1085 | is_microsoft_gen1 = mceusb_model[model].mce_gen1; | 1129 | is_microsoft_gen1 = mceusb_model[model].mce_gen1; |
1086 | tx_mask_inverted = mceusb_model[model].tx_mask_inverted; | 1130 | tx_mask_normal = mceusb_model[model].tx_mask_normal; |
1087 | is_polaris = mceusb_model[model].is_polaris; | 1131 | is_polaris = mceusb_model[model].is_polaris; |
1088 | 1132 | ||
1089 | if (is_polaris) { | 1133 | if (is_polaris) { |
@@ -1107,7 +1151,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, | |||
1107 | ep_in = ep; | 1151 | ep_in = ep; |
1108 | ep_in->bmAttributes = USB_ENDPOINT_XFER_INT; | 1152 | ep_in->bmAttributes = USB_ENDPOINT_XFER_INT; |
1109 | ep_in->bInterval = 1; | 1153 | ep_in->bInterval = 1; |
1110 | dev_dbg(&intf->dev, ": acceptable inbound endpoint " | 1154 | dev_dbg(&intf->dev, "acceptable inbound endpoint " |
1111 | "found\n"); | 1155 | "found\n"); |
1112 | } | 1156 | } |
1113 | 1157 | ||
@@ -1122,12 +1166,12 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, | |||
1122 | ep_out = ep; | 1166 | ep_out = ep; |
1123 | ep_out->bmAttributes = USB_ENDPOINT_XFER_INT; | 1167 | ep_out->bmAttributes = USB_ENDPOINT_XFER_INT; |
1124 | ep_out->bInterval = 1; | 1168 | ep_out->bInterval = 1; |
1125 | dev_dbg(&intf->dev, ": acceptable outbound endpoint " | 1169 | dev_dbg(&intf->dev, "acceptable outbound endpoint " |
1126 | "found\n"); | 1170 | "found\n"); |
1127 | } | 1171 | } |
1128 | } | 1172 | } |
1129 | if (ep_in == NULL) { | 1173 | if (ep_in == NULL) { |
1130 | dev_dbg(&intf->dev, ": inbound and/or endpoint not found\n"); | 1174 | dev_dbg(&intf->dev, "inbound and/or endpoint not found\n"); |
1131 | return -ENODEV; | 1175 | return -ENODEV; |
1132 | } | 1176 | } |
1133 | 1177 | ||
@@ -1150,11 +1194,10 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, | |||
1150 | ir->dev = &intf->dev; | 1194 | ir->dev = &intf->dev; |
1151 | ir->len_in = maxp; | 1195 | ir->len_in = maxp; |
1152 | ir->flags.microsoft_gen1 = is_microsoft_gen1; | 1196 | ir->flags.microsoft_gen1 = is_microsoft_gen1; |
1153 | ir->flags.tx_mask_inverted = tx_mask_inverted; | 1197 | ir->flags.tx_mask_normal = tx_mask_normal; |
1198 | ir->flags.no_tx = mceusb_model[model].no_tx; | ||
1154 | ir->model = model; | 1199 | ir->model = model; |
1155 | 1200 | ||
1156 | init_ir_raw_event(&ir->rawir); | ||
1157 | |||
1158 | /* Saving usb interface data for use by the transmitter routine */ | 1201 | /* Saving usb interface data for use by the transmitter routine */ |
1159 | ir->usb_ep_in = ep_in; | 1202 | ir->usb_ep_in = ep_in; |
1160 | ir->usb_ep_out = ep_out; | 1203 | ir->usb_ep_out = ep_out; |
@@ -1191,7 +1234,8 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, | |||
1191 | 1234 | ||
1192 | mceusb_get_parameters(ir); | 1235 | mceusb_get_parameters(ir); |
1193 | 1236 | ||
1194 | mceusb_set_tx_mask(ir, MCE_DEFAULT_TX_MASK); | 1237 | if (!ir->flags.no_tx) |
1238 | mceusb_set_tx_mask(ir, MCE_DEFAULT_TX_MASK); | ||
1195 | 1239 | ||
1196 | usb_set_intfdata(intf, ir); | 1240 | usb_set_intfdata(intf, ir); |
1197 | 1241 | ||
diff --git a/drivers/media/IR/nuvoton-cir.c b/drivers/media/IR/nuvoton-cir.c index 301be53aee85..acc729c79cec 100644 --- a/drivers/media/IR/nuvoton-cir.c +++ b/drivers/media/IR/nuvoton-cir.c | |||
@@ -603,6 +603,8 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt) | |||
603 | count = nvt->pkts; | 603 | count = nvt->pkts; |
604 | nvt_dbg_verbose("Processing buffer of len %d", count); | 604 | nvt_dbg_verbose("Processing buffer of len %d", count); |
605 | 605 | ||
606 | init_ir_raw_event(&rawir); | ||
607 | |||
606 | for (i = 0; i < count; i++) { | 608 | for (i = 0; i < count; i++) { |
607 | nvt->pkts--; | 609 | nvt->pkts--; |
608 | sample = nvt->buf[i]; | 610 | sample = nvt->buf[i]; |
@@ -643,11 +645,15 @@ static void nvt_process_rx_ir_data(struct nvt_dev *nvt) | |||
643 | * indicates end of IR signal, but new data incoming. In both | 645 | * indicates end of IR signal, but new data incoming. In both |
644 | * cases, it means we're ready to call ir_raw_event_handle | 646 | * cases, it means we're ready to call ir_raw_event_handle |
645 | */ | 647 | */ |
646 | if (sample == BUF_PULSE_BIT || ((sample != BUF_LEN_MASK) && | 648 | if ((sample == BUF_PULSE_BIT) && nvt->pkts) { |
647 | (sample & BUF_REPEAT_MASK) == BUF_REPEAT_BYTE)) | 649 | nvt_dbg("Calling ir_raw_event_handle (signal end)\n"); |
648 | ir_raw_event_handle(nvt->rdev); | 650 | ir_raw_event_handle(nvt->rdev); |
651 | } | ||
649 | } | 652 | } |
650 | 653 | ||
654 | nvt_dbg("Calling ir_raw_event_handle (buffer empty)\n"); | ||
655 | ir_raw_event_handle(nvt->rdev); | ||
656 | |||
651 | if (nvt->pkts) { | 657 | if (nvt->pkts) { |
652 | nvt_dbg("Odd, pkts should be 0 now... (its %u)", nvt->pkts); | 658 | nvt_dbg("Odd, pkts should be 0 now... (its %u)", nvt->pkts); |
653 | nvt->pkts = 0; | 659 | nvt->pkts = 0; |
diff --git a/drivers/media/IR/streamzap.c b/drivers/media/IR/streamzap.c index 548381c35bfd..3a20aef67d08 100644 --- a/drivers/media/IR/streamzap.c +++ b/drivers/media/IR/streamzap.c | |||
@@ -34,8 +34,9 @@ | |||
34 | #include <linux/device.h> | 34 | #include <linux/device.h> |
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
36 | #include <linux/slab.h> | 36 | #include <linux/slab.h> |
37 | #include <linux/usb.h> | ||
38 | #include <linux/input.h> | 37 | #include <linux/input.h> |
38 | #include <linux/usb.h> | ||
39 | #include <linux/usb/input.h> | ||
39 | #include <media/ir-core.h> | 40 | #include <media/ir-core.h> |
40 | 41 | ||
41 | #define DRIVER_VERSION "1.61" | 42 | #define DRIVER_VERSION "1.61" |
@@ -140,7 +141,9 @@ static struct usb_driver streamzap_driver = { | |||
140 | 141 | ||
141 | static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir) | 142 | static void sz_push(struct streamzap_ir *sz, struct ir_raw_event rawir) |
142 | { | 143 | { |
143 | ir_raw_event_store(sz->idev, &rawir); | 144 | dev_dbg(sz->dev, "Storing %s with duration %u us\n", |
145 | (rawir.pulse ? "pulse" : "space"), rawir.duration); | ||
146 | ir_raw_event_store_with_filter(sz->idev, &rawir); | ||
144 | } | 147 | } |
145 | 148 | ||
146 | static void sz_push_full_pulse(struct streamzap_ir *sz, | 149 | static void sz_push_full_pulse(struct streamzap_ir *sz, |
@@ -167,7 +170,6 @@ static void sz_push_full_pulse(struct streamzap_ir *sz, | |||
167 | rawir.duration *= 1000; | 170 | rawir.duration *= 1000; |
168 | rawir.duration &= IR_MAX_DURATION; | 171 | rawir.duration &= IR_MAX_DURATION; |
169 | } | 172 | } |
170 | dev_dbg(sz->dev, "ls %u\n", rawir.duration); | ||
171 | sz_push(sz, rawir); | 173 | sz_push(sz, rawir); |
172 | 174 | ||
173 | sz->idle = false; | 175 | sz->idle = false; |
@@ -180,7 +182,6 @@ static void sz_push_full_pulse(struct streamzap_ir *sz, | |||
180 | sz->sum += rawir.duration; | 182 | sz->sum += rawir.duration; |
181 | rawir.duration *= 1000; | 183 | rawir.duration *= 1000; |
182 | rawir.duration &= IR_MAX_DURATION; | 184 | rawir.duration &= IR_MAX_DURATION; |
183 | dev_dbg(sz->dev, "p %u\n", rawir.duration); | ||
184 | sz_push(sz, rawir); | 185 | sz_push(sz, rawir); |
185 | } | 186 | } |
186 | 187 | ||
@@ -200,7 +201,6 @@ static void sz_push_full_space(struct streamzap_ir *sz, | |||
200 | rawir.duration += SZ_RESOLUTION / 2; | 201 | rawir.duration += SZ_RESOLUTION / 2; |
201 | sz->sum += rawir.duration; | 202 | sz->sum += rawir.duration; |
202 | rawir.duration *= 1000; | 203 | rawir.duration *= 1000; |
203 | dev_dbg(sz->dev, "s %u\n", rawir.duration); | ||
204 | sz_push(sz, rawir); | 204 | sz_push(sz, rawir); |
205 | } | 205 | } |
206 | 206 | ||
@@ -221,8 +221,6 @@ static void streamzap_callback(struct urb *urb) | |||
221 | struct streamzap_ir *sz; | 221 | struct streamzap_ir *sz; |
222 | unsigned int i; | 222 | unsigned int i; |
223 | int len; | 223 | int len; |
224 | static int timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) & | ||
225 | IR_MAX_DURATION) | 0x03000000); | ||
226 | 224 | ||
227 | if (!urb) | 225 | if (!urb) |
228 | return; | 226 | return; |
@@ -246,7 +244,7 @@ static void streamzap_callback(struct urb *urb) | |||
246 | 244 | ||
247 | dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len); | 245 | dev_dbg(sz->dev, "%s: received urb, len %d\n", __func__, len); |
248 | for (i = 0; i < len; i++) { | 246 | for (i = 0; i < len; i++) { |
249 | dev_dbg(sz->dev, "sz idx %d: %x\n", | 247 | dev_dbg(sz->dev, "sz->buf_in[%d]: %x\n", |
250 | i, (unsigned char)sz->buf_in[i]); | 248 | i, (unsigned char)sz->buf_in[i]); |
251 | switch (sz->decoder_state) { | 249 | switch (sz->decoder_state) { |
252 | case PulseSpace: | 250 | case PulseSpace: |
@@ -273,7 +271,7 @@ static void streamzap_callback(struct urb *urb) | |||
273 | DEFINE_IR_RAW_EVENT(rawir); | 271 | DEFINE_IR_RAW_EVENT(rawir); |
274 | 272 | ||
275 | rawir.pulse = false; | 273 | rawir.pulse = false; |
276 | rawir.duration = timeout; | 274 | rawir.duration = sz->props->timeout; |
277 | sz->idle = true; | 275 | sz->idle = true; |
278 | if (sz->timeout_enabled) | 276 | if (sz->timeout_enabled) |
279 | sz_push(sz, rawir); | 277 | sz_push(sz, rawir); |
@@ -335,6 +333,9 @@ static struct input_dev *streamzap_init_input_dev(struct streamzap_ir *sz) | |||
335 | 333 | ||
336 | sz->props = props; | 334 | sz->props = props; |
337 | 335 | ||
336 | usb_to_input_id(sz->usbdev, &idev->id); | ||
337 | idev->dev.parent = sz->dev; | ||
338 | |||
338 | ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME); | 339 | ret = ir_input_register(idev, RC_MAP_STREAMZAP, props, DRIVER_NAME); |
339 | if (ret < 0) { | 340 | if (ret < 0) { |
340 | dev_err(dev, "remote input device register failed\n"); | 341 | dev_err(dev, "remote input device register failed\n"); |
@@ -444,6 +445,8 @@ static int __devinit streamzap_probe(struct usb_interface *intf, | |||
444 | sz->decoder_state = PulseSpace; | 445 | sz->decoder_state = PulseSpace; |
445 | /* FIXME: don't yet have a way to set this */ | 446 | /* FIXME: don't yet have a way to set this */ |
446 | sz->timeout_enabled = true; | 447 | sz->timeout_enabled = true; |
448 | sz->props->timeout = (((SZ_TIMEOUT * SZ_RESOLUTION * 1000) & | ||
449 | IR_MAX_DURATION) | 0x03000000); | ||
447 | #if 0 | 450 | #if 0 |
448 | /* not yet supported, depends on patches from maxim */ | 451 | /* not yet supported, depends on patches from maxim */ |
449 | /* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */ | 452 | /* see also: LIRC_GET_REC_RESOLUTION and LIRC_SET_REC_TIMEOUT */ |
diff --git a/drivers/media/common/saa7146_hlp.c b/drivers/media/common/saa7146_hlp.c index 05bde9ccb770..1d1d8d200755 100644 --- a/drivers/media/common/saa7146_hlp.c +++ b/drivers/media/common/saa7146_hlp.c | |||
@@ -558,7 +558,7 @@ static void saa7146_set_window(struct saa7146_dev *dev, int width, int height, e | |||
558 | static void saa7146_set_position(struct saa7146_dev *dev, int w_x, int w_y, int w_height, enum v4l2_field field, u32 pixelformat) | 558 | static void saa7146_set_position(struct saa7146_dev *dev, int w_x, int w_y, int w_height, enum v4l2_field field, u32 pixelformat) |
559 | { | 559 | { |
560 | struct saa7146_vv *vv = dev->vv_data; | 560 | struct saa7146_vv *vv = dev->vv_data; |
561 | struct saa7146_format *sfmt = format_by_fourcc(dev, pixelformat); | 561 | struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev, pixelformat); |
562 | 562 | ||
563 | int b_depth = vv->ov_fmt->depth; | 563 | int b_depth = vv->ov_fmt->depth; |
564 | int b_bpl = vv->ov_fb.fmt.bytesperline; | 564 | int b_bpl = vv->ov_fb.fmt.bytesperline; |
@@ -702,7 +702,7 @@ static int calculate_video_dma_grab_packed(struct saa7146_dev* dev, struct saa71 | |||
702 | struct saa7146_vv *vv = dev->vv_data; | 702 | struct saa7146_vv *vv = dev->vv_data; |
703 | struct saa7146_video_dma vdma1; | 703 | struct saa7146_video_dma vdma1; |
704 | 704 | ||
705 | struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat); | 705 | struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); |
706 | 706 | ||
707 | int width = buf->fmt->width; | 707 | int width = buf->fmt->width; |
708 | int height = buf->fmt->height; | 708 | int height = buf->fmt->height; |
@@ -827,7 +827,7 @@ static int calculate_video_dma_grab_planar(struct saa7146_dev* dev, struct saa71 | |||
827 | struct saa7146_video_dma vdma2; | 827 | struct saa7146_video_dma vdma2; |
828 | struct saa7146_video_dma vdma3; | 828 | struct saa7146_video_dma vdma3; |
829 | 829 | ||
830 | struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat); | 830 | struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); |
831 | 831 | ||
832 | int width = buf->fmt->width; | 832 | int width = buf->fmt->width; |
833 | int height = buf->fmt->height; | 833 | int height = buf->fmt->height; |
@@ -994,7 +994,7 @@ static void program_capture_engine(struct saa7146_dev *dev, int planar) | |||
994 | 994 | ||
995 | void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next) | 995 | void saa7146_set_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next) |
996 | { | 996 | { |
997 | struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat); | 997 | struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); |
998 | struct saa7146_vv *vv = dev->vv_data; | 998 | struct saa7146_vv *vv = dev->vv_data; |
999 | u32 vdma1_prot_addr; | 999 | u32 vdma1_prot_addr; |
1000 | 1000 | ||
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c index 741c5732b430..d246910129e8 100644 --- a/drivers/media/common/saa7146_video.c +++ b/drivers/media/common/saa7146_video.c | |||
@@ -84,7 +84,7 @@ static struct saa7146_format formats[] = { | |||
84 | 84 | ||
85 | static int NUM_FORMATS = sizeof(formats)/sizeof(struct saa7146_format); | 85 | static int NUM_FORMATS = sizeof(formats)/sizeof(struct saa7146_format); |
86 | 86 | ||
87 | struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc) | 87 | struct saa7146_format* saa7146_format_by_fourcc(struct saa7146_dev *dev, int fourcc) |
88 | { | 88 | { |
89 | int i, j = NUM_FORMATS; | 89 | int i, j = NUM_FORMATS; |
90 | 90 | ||
@@ -266,7 +266,7 @@ static int saa7146_pgtable_build(struct saa7146_dev *dev, struct saa7146_buf *bu | |||
266 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); | 266 | struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb); |
267 | struct scatterlist *list = dma->sglist; | 267 | struct scatterlist *list = dma->sglist; |
268 | int length = dma->sglen; | 268 | int length = dma->sglen; |
269 | struct saa7146_format *sfmt = format_by_fourcc(dev,buf->fmt->pixelformat); | 269 | struct saa7146_format *sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); |
270 | 270 | ||
271 | DEB_EE(("dev:%p, buf:%p, sg_len:%d\n",dev,buf,length)); | 271 | DEB_EE(("dev:%p, buf:%p, sg_len:%d\n",dev,buf,length)); |
272 | 272 | ||
@@ -408,7 +408,7 @@ static int video_begin(struct saa7146_fh *fh) | |||
408 | } | 408 | } |
409 | } | 409 | } |
410 | 410 | ||
411 | fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat); | 411 | fmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat); |
412 | /* we need to have a valid format set here */ | 412 | /* we need to have a valid format set here */ |
413 | BUG_ON(NULL == fmt); | 413 | BUG_ON(NULL == fmt); |
414 | 414 | ||
@@ -460,7 +460,7 @@ static int video_end(struct saa7146_fh *fh, struct file *file) | |||
460 | return -EBUSY; | 460 | return -EBUSY; |
461 | } | 461 | } |
462 | 462 | ||
463 | fmt = format_by_fourcc(dev,fh->video_fmt.pixelformat); | 463 | fmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat); |
464 | /* we need to have a valid format set here */ | 464 | /* we need to have a valid format set here */ |
465 | BUG_ON(NULL == fmt); | 465 | BUG_ON(NULL == fmt); |
466 | 466 | ||
@@ -536,7 +536,7 @@ static int vidioc_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *f | |||
536 | return -EPERM; | 536 | return -EPERM; |
537 | 537 | ||
538 | /* check args */ | 538 | /* check args */ |
539 | fmt = format_by_fourcc(dev, fb->fmt.pixelformat); | 539 | fmt = saa7146_format_by_fourcc(dev, fb->fmt.pixelformat); |
540 | if (NULL == fmt) | 540 | if (NULL == fmt) |
541 | return -EINVAL; | 541 | return -EINVAL; |
542 | 542 | ||
@@ -760,7 +760,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_forma | |||
760 | 760 | ||
761 | DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh)); | 761 | DEB_EE(("V4L2_BUF_TYPE_VIDEO_CAPTURE: dev:%p, fh:%p\n", dev, fh)); |
762 | 762 | ||
763 | fmt = format_by_fourcc(dev, f->fmt.pix.pixelformat); | 763 | fmt = saa7146_format_by_fourcc(dev, f->fmt.pix.pixelformat); |
764 | if (NULL == fmt) | 764 | if (NULL == fmt) |
765 | return -EINVAL; | 765 | return -EINVAL; |
766 | 766 | ||
@@ -1264,7 +1264,7 @@ static int buffer_prepare(struct videobuf_queue *q, | |||
1264 | buf->fmt = &fh->video_fmt; | 1264 | buf->fmt = &fh->video_fmt; |
1265 | buf->vb.field = fh->video_fmt.field; | 1265 | buf->vb.field = fh->video_fmt.field; |
1266 | 1266 | ||
1267 | sfmt = format_by_fourcc(dev,buf->fmt->pixelformat); | 1267 | sfmt = saa7146_format_by_fourcc(dev,buf->fmt->pixelformat); |
1268 | 1268 | ||
1269 | release_all_pagetables(dev, buf); | 1269 | release_all_pagetables(dev, buf); |
1270 | if( 0 != IS_PLANAR(sfmt->trans)) { | 1270 | if( 0 != IS_PLANAR(sfmt->trans)) { |
@@ -1378,7 +1378,7 @@ static int video_open(struct saa7146_dev *dev, struct file *file) | |||
1378 | fh->video_fmt.pixelformat = V4L2_PIX_FMT_BGR24; | 1378 | fh->video_fmt.pixelformat = V4L2_PIX_FMT_BGR24; |
1379 | fh->video_fmt.bytesperline = 0; | 1379 | fh->video_fmt.bytesperline = 0; |
1380 | fh->video_fmt.field = V4L2_FIELD_ANY; | 1380 | fh->video_fmt.field = V4L2_FIELD_ANY; |
1381 | sfmt = format_by_fourcc(dev,fh->video_fmt.pixelformat); | 1381 | sfmt = saa7146_format_by_fourcc(dev,fh->video_fmt.pixelformat); |
1382 | fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8; | 1382 | fh->video_fmt.sizeimage = (fh->video_fmt.width * fh->video_fmt.height * sfmt->depth)/8; |
1383 | 1383 | ||
1384 | videobuf_queue_sg_init(&fh->video_q, &video_qops, | 1384 | videobuf_queue_sg_init(&fh->video_q, &video_qops, |
diff --git a/drivers/media/radio/radio-aimslab.c b/drivers/media/radio/radio-aimslab.c index 5bf4985daede..05e832f61c3e 100644 --- a/drivers/media/radio/radio-aimslab.c +++ b/drivers/media/radio/radio-aimslab.c | |||
@@ -361,7 +361,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
361 | 361 | ||
362 | static const struct v4l2_file_operations rtrack_fops = { | 362 | static const struct v4l2_file_operations rtrack_fops = { |
363 | .owner = THIS_MODULE, | 363 | .owner = THIS_MODULE, |
364 | .ioctl = video_ioctl2, | 364 | .unlocked_ioctl = video_ioctl2, |
365 | }; | 365 | }; |
366 | 366 | ||
367 | static const struct v4l2_ioctl_ops rtrack_ioctl_ops = { | 367 | static const struct v4l2_ioctl_ops rtrack_ioctl_ops = { |
@@ -412,13 +412,6 @@ static int __init rtrack_init(void) | |||
412 | rt->vdev.release = video_device_release_empty; | 412 | rt->vdev.release = video_device_release_empty; |
413 | video_set_drvdata(&rt->vdev, rt); | 413 | video_set_drvdata(&rt->vdev, rt); |
414 | 414 | ||
415 | if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
416 | v4l2_device_unregister(&rt->v4l2_dev); | ||
417 | release_region(rt->io, 2); | ||
418 | return -EINVAL; | ||
419 | } | ||
420 | v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n"); | ||
421 | |||
422 | /* Set up the I/O locking */ | 415 | /* Set up the I/O locking */ |
423 | 416 | ||
424 | mutex_init(&rt->lock); | 417 | mutex_init(&rt->lock); |
@@ -430,6 +423,13 @@ static int __init rtrack_init(void) | |||
430 | sleep_delay(2000000); /* make sure it's totally down */ | 423 | sleep_delay(2000000); /* make sure it's totally down */ |
431 | outb(0xc0, rt->io); /* steady volume, mute card */ | 424 | outb(0xc0, rt->io); /* steady volume, mute card */ |
432 | 425 | ||
426 | if (video_register_device(&rt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
427 | v4l2_device_unregister(&rt->v4l2_dev); | ||
428 | release_region(rt->io, 2); | ||
429 | return -EINVAL; | ||
430 | } | ||
431 | v4l2_info(v4l2_dev, "AIMSlab RadioTrack/RadioReveal card driver.\n"); | ||
432 | |||
433 | return 0; | 433 | return 0; |
434 | } | 434 | } |
435 | 435 | ||
diff --git a/drivers/media/radio/radio-aztech.c b/drivers/media/radio/radio-aztech.c index c22311393624..dd8a6ab0d437 100644 --- a/drivers/media/radio/radio-aztech.c +++ b/drivers/media/radio/radio-aztech.c | |||
@@ -324,7 +324,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
324 | 324 | ||
325 | static const struct v4l2_file_operations aztech_fops = { | 325 | static const struct v4l2_file_operations aztech_fops = { |
326 | .owner = THIS_MODULE, | 326 | .owner = THIS_MODULE, |
327 | .ioctl = video_ioctl2, | 327 | .unlocked_ioctl = video_ioctl2, |
328 | }; | 328 | }; |
329 | 329 | ||
330 | static const struct v4l2_ioctl_ops aztech_ioctl_ops = { | 330 | static const struct v4l2_ioctl_ops aztech_ioctl_ops = { |
@@ -375,6 +375,8 @@ static int __init aztech_init(void) | |||
375 | az->vdev.ioctl_ops = &aztech_ioctl_ops; | 375 | az->vdev.ioctl_ops = &aztech_ioctl_ops; |
376 | az->vdev.release = video_device_release_empty; | 376 | az->vdev.release = video_device_release_empty; |
377 | video_set_drvdata(&az->vdev, az); | 377 | video_set_drvdata(&az->vdev, az); |
378 | /* mute card - prevents noisy bootups */ | ||
379 | outb(0, az->io); | ||
378 | 380 | ||
379 | if (video_register_device(&az->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 381 | if (video_register_device(&az->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
380 | v4l2_device_unregister(v4l2_dev); | 382 | v4l2_device_unregister(v4l2_dev); |
@@ -383,8 +385,6 @@ static int __init aztech_init(void) | |||
383 | } | 385 | } |
384 | 386 | ||
385 | v4l2_info(v4l2_dev, "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n"); | 387 | v4l2_info(v4l2_dev, "Aztech radio card driver v1.00/19990224 rkroll@exploits.org\n"); |
386 | /* mute card - prevents noisy bootups */ | ||
387 | outb(0, az->io); | ||
388 | return 0; | 388 | return 0; |
389 | } | 389 | } |
390 | 390 | ||
diff --git a/drivers/media/radio/radio-cadet.c b/drivers/media/radio/radio-cadet.c index b701ea6e7c73..bc9ad0897c55 100644 --- a/drivers/media/radio/radio-cadet.c +++ b/drivers/media/radio/radio-cadet.c | |||
@@ -328,11 +328,10 @@ static ssize_t cadet_read(struct file *file, char __user *data, size_t count, lo | |||
328 | unsigned char readbuf[RDS_BUFFER]; | 328 | unsigned char readbuf[RDS_BUFFER]; |
329 | int i = 0; | 329 | int i = 0; |
330 | 330 | ||
331 | mutex_lock(&dev->lock); | ||
331 | if (dev->rdsstat == 0) { | 332 | if (dev->rdsstat == 0) { |
332 | mutex_lock(&dev->lock); | ||
333 | dev->rdsstat = 1; | 333 | dev->rdsstat = 1; |
334 | outb(0x80, dev->io); /* Select RDS fifo */ | 334 | outb(0x80, dev->io); /* Select RDS fifo */ |
335 | mutex_unlock(&dev->lock); | ||
336 | init_timer(&dev->readtimer); | 335 | init_timer(&dev->readtimer); |
337 | dev->readtimer.function = cadet_handler; | 336 | dev->readtimer.function = cadet_handler; |
338 | dev->readtimer.data = (unsigned long)dev; | 337 | dev->readtimer.data = (unsigned long)dev; |
@@ -340,12 +339,15 @@ static ssize_t cadet_read(struct file *file, char __user *data, size_t count, lo | |||
340 | add_timer(&dev->readtimer); | 339 | add_timer(&dev->readtimer); |
341 | } | 340 | } |
342 | if (dev->rdsin == dev->rdsout) { | 341 | if (dev->rdsin == dev->rdsout) { |
342 | mutex_unlock(&dev->lock); | ||
343 | if (file->f_flags & O_NONBLOCK) | 343 | if (file->f_flags & O_NONBLOCK) |
344 | return -EWOULDBLOCK; | 344 | return -EWOULDBLOCK; |
345 | interruptible_sleep_on(&dev->read_queue); | 345 | interruptible_sleep_on(&dev->read_queue); |
346 | mutex_lock(&dev->lock); | ||
346 | } | 347 | } |
347 | while (i < count && dev->rdsin != dev->rdsout) | 348 | while (i < count && dev->rdsin != dev->rdsout) |
348 | readbuf[i++] = dev->rdsbuf[dev->rdsout++]; | 349 | readbuf[i++] = dev->rdsbuf[dev->rdsout++]; |
350 | mutex_unlock(&dev->lock); | ||
349 | 351 | ||
350 | if (copy_to_user(data, readbuf, i)) | 352 | if (copy_to_user(data, readbuf, i)) |
351 | return -EFAULT; | 353 | return -EFAULT; |
@@ -525,9 +527,11 @@ static int cadet_open(struct file *file) | |||
525 | { | 527 | { |
526 | struct cadet *dev = video_drvdata(file); | 528 | struct cadet *dev = video_drvdata(file); |
527 | 529 | ||
530 | mutex_lock(&dev->lock); | ||
528 | dev->users++; | 531 | dev->users++; |
529 | if (1 == dev->users) | 532 | if (1 == dev->users) |
530 | init_waitqueue_head(&dev->read_queue); | 533 | init_waitqueue_head(&dev->read_queue); |
534 | mutex_unlock(&dev->lock); | ||
531 | return 0; | 535 | return 0; |
532 | } | 536 | } |
533 | 537 | ||
@@ -535,11 +539,13 @@ static int cadet_release(struct file *file) | |||
535 | { | 539 | { |
536 | struct cadet *dev = video_drvdata(file); | 540 | struct cadet *dev = video_drvdata(file); |
537 | 541 | ||
542 | mutex_lock(&dev->lock); | ||
538 | dev->users--; | 543 | dev->users--; |
539 | if (0 == dev->users) { | 544 | if (0 == dev->users) { |
540 | del_timer_sync(&dev->readtimer); | 545 | del_timer_sync(&dev->readtimer); |
541 | dev->rdsstat = 0; | 546 | dev->rdsstat = 0; |
542 | } | 547 | } |
548 | mutex_unlock(&dev->lock); | ||
543 | return 0; | 549 | return 0; |
544 | } | 550 | } |
545 | 551 | ||
@@ -559,7 +565,7 @@ static const struct v4l2_file_operations cadet_fops = { | |||
559 | .open = cadet_open, | 565 | .open = cadet_open, |
560 | .release = cadet_release, | 566 | .release = cadet_release, |
561 | .read = cadet_read, | 567 | .read = cadet_read, |
562 | .ioctl = video_ioctl2, | 568 | .unlocked_ioctl = video_ioctl2, |
563 | .poll = cadet_poll, | 569 | .poll = cadet_poll, |
564 | }; | 570 | }; |
565 | 571 | ||
diff --git a/drivers/media/radio/radio-gemtek-pci.c b/drivers/media/radio/radio-gemtek-pci.c index 79039674a0e0..28fa85ba2087 100644 --- a/drivers/media/radio/radio-gemtek-pci.c +++ b/drivers/media/radio/radio-gemtek-pci.c | |||
@@ -361,7 +361,7 @@ MODULE_DEVICE_TABLE(pci, gemtek_pci_id); | |||
361 | 361 | ||
362 | static const struct v4l2_file_operations gemtek_pci_fops = { | 362 | static const struct v4l2_file_operations gemtek_pci_fops = { |
363 | .owner = THIS_MODULE, | 363 | .owner = THIS_MODULE, |
364 | .ioctl = video_ioctl2, | 364 | .unlocked_ioctl = video_ioctl2, |
365 | }; | 365 | }; |
366 | 366 | ||
367 | static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = { | 367 | static const struct v4l2_ioctl_ops gemtek_pci_ioctl_ops = { |
@@ -422,11 +422,11 @@ static int __devinit gemtek_pci_probe(struct pci_dev *pdev, const struct pci_dev | |||
422 | card->vdev.release = video_device_release_empty; | 422 | card->vdev.release = video_device_release_empty; |
423 | video_set_drvdata(&card->vdev, card); | 423 | video_set_drvdata(&card->vdev, card); |
424 | 424 | ||
425 | gemtek_pci_mute(card); | ||
426 | |||
425 | if (video_register_device(&card->vdev, VFL_TYPE_RADIO, nr_radio) < 0) | 427 | if (video_register_device(&card->vdev, VFL_TYPE_RADIO, nr_radio) < 0) |
426 | goto err_video; | 428 | goto err_video; |
427 | 429 | ||
428 | gemtek_pci_mute(card); | ||
429 | |||
430 | v4l2_info(v4l2_dev, "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n", | 430 | v4l2_info(v4l2_dev, "Gemtek PCI Radio (rev. %d) found at 0x%04x-0x%04x.\n", |
431 | pdev->revision, card->iobase, card->iobase + card->length - 1); | 431 | pdev->revision, card->iobase, card->iobase + card->length - 1); |
432 | 432 | ||
diff --git a/drivers/media/radio/radio-gemtek.c b/drivers/media/radio/radio-gemtek.c index 73985f641f07..259936422e49 100644 --- a/drivers/media/radio/radio-gemtek.c +++ b/drivers/media/radio/radio-gemtek.c | |||
@@ -378,7 +378,7 @@ static int gemtek_probe(struct gemtek *gt) | |||
378 | 378 | ||
379 | static const struct v4l2_file_operations gemtek_fops = { | 379 | static const struct v4l2_file_operations gemtek_fops = { |
380 | .owner = THIS_MODULE, | 380 | .owner = THIS_MODULE, |
381 | .ioctl = video_ioctl2, | 381 | .unlocked_ioctl = video_ioctl2, |
382 | }; | 382 | }; |
383 | 383 | ||
384 | static int vidioc_querycap(struct file *file, void *priv, | 384 | static int vidioc_querycap(struct file *file, void *priv, |
@@ -577,12 +577,6 @@ static int __init gemtek_init(void) | |||
577 | gt->vdev.release = video_device_release_empty; | 577 | gt->vdev.release = video_device_release_empty; |
578 | video_set_drvdata(>->vdev, gt); | 578 | video_set_drvdata(>->vdev, gt); |
579 | 579 | ||
580 | if (video_register_device(>->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
581 | v4l2_device_unregister(v4l2_dev); | ||
582 | release_region(gt->io, 1); | ||
583 | return -EBUSY; | ||
584 | } | ||
585 | |||
586 | /* Set defaults */ | 580 | /* Set defaults */ |
587 | gt->lastfreq = GEMTEK_LOWFREQ; | 581 | gt->lastfreq = GEMTEK_LOWFREQ; |
588 | gt->bu2614data = 0; | 582 | gt->bu2614data = 0; |
@@ -590,6 +584,12 @@ static int __init gemtek_init(void) | |||
590 | if (initmute) | 584 | if (initmute) |
591 | gemtek_mute(gt); | 585 | gemtek_mute(gt); |
592 | 586 | ||
587 | if (video_register_device(>->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
588 | v4l2_device_unregister(v4l2_dev); | ||
589 | release_region(gt->io, 1); | ||
590 | return -EBUSY; | ||
591 | } | ||
592 | |||
593 | return 0; | 593 | return 0; |
594 | } | 594 | } |
595 | 595 | ||
diff --git a/drivers/media/radio/radio-maestro.c b/drivers/media/radio/radio-maestro.c index 08f1051979ca..6af61bfeb178 100644 --- a/drivers/media/radio/radio-maestro.c +++ b/drivers/media/radio/radio-maestro.c | |||
@@ -299,7 +299,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
299 | 299 | ||
300 | static const struct v4l2_file_operations maestro_fops = { | 300 | static const struct v4l2_file_operations maestro_fops = { |
301 | .owner = THIS_MODULE, | 301 | .owner = THIS_MODULE, |
302 | .ioctl = video_ioctl2, | 302 | .unlocked_ioctl = video_ioctl2, |
303 | }; | 303 | }; |
304 | 304 | ||
305 | static const struct v4l2_ioctl_ops maestro_ioctl_ops = { | 305 | static const struct v4l2_ioctl_ops maestro_ioctl_ops = { |
@@ -383,22 +383,20 @@ static int __devinit maestro_probe(struct pci_dev *pdev, | |||
383 | dev->vdev.release = video_device_release_empty; | 383 | dev->vdev.release = video_device_release_empty; |
384 | video_set_drvdata(&dev->vdev, dev); | 384 | video_set_drvdata(&dev->vdev, dev); |
385 | 385 | ||
386 | if (!radio_power_on(dev)) { | ||
387 | retval = -EIO; | ||
388 | goto errfr1; | ||
389 | } | ||
390 | |||
386 | retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr); | 391 | retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr); |
387 | if (retval) { | 392 | if (retval) { |
388 | v4l2_err(v4l2_dev, "can't register video device!\n"); | 393 | v4l2_err(v4l2_dev, "can't register video device!\n"); |
389 | goto errfr1; | 394 | goto errfr1; |
390 | } | 395 | } |
391 | 396 | ||
392 | if (!radio_power_on(dev)) { | ||
393 | retval = -EIO; | ||
394 | goto errunr; | ||
395 | } | ||
396 | |||
397 | v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n"); | 397 | v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n"); |
398 | 398 | ||
399 | return 0; | 399 | return 0; |
400 | errunr: | ||
401 | video_unregister_device(&dev->vdev); | ||
402 | errfr1: | 400 | errfr1: |
403 | v4l2_device_unregister(v4l2_dev); | 401 | v4l2_device_unregister(v4l2_dev); |
404 | errfr: | 402 | errfr: |
diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index 255d40df4b46..6459a220b0dd 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c | |||
@@ -346,7 +346,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
346 | 346 | ||
347 | static const struct v4l2_file_operations maxiradio_fops = { | 347 | static const struct v4l2_file_operations maxiradio_fops = { |
348 | .owner = THIS_MODULE, | 348 | .owner = THIS_MODULE, |
349 | .ioctl = video_ioctl2, | 349 | .unlocked_ioctl = video_ioctl2, |
350 | }; | 350 | }; |
351 | 351 | ||
352 | static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = { | 352 | static const struct v4l2_ioctl_ops maxiradio_ioctl_ops = { |
diff --git a/drivers/media/radio/radio-miropcm20.c b/drivers/media/radio/radio-miropcm20.c index 4ff885445fd4..3fb76e3834c9 100644 --- a/drivers/media/radio/radio-miropcm20.c +++ b/drivers/media/radio/radio-miropcm20.c | |||
@@ -33,6 +33,7 @@ struct pcm20 { | |||
33 | unsigned long freq; | 33 | unsigned long freq; |
34 | int muted; | 34 | int muted; |
35 | struct snd_miro_aci *aci; | 35 | struct snd_miro_aci *aci; |
36 | struct mutex lock; | ||
36 | }; | 37 | }; |
37 | 38 | ||
38 | static struct pcm20 pcm20_card = { | 39 | static struct pcm20 pcm20_card = { |
@@ -72,7 +73,7 @@ static int pcm20_setfreq(struct pcm20 *dev, unsigned long freq) | |||
72 | 73 | ||
73 | static const struct v4l2_file_operations pcm20_fops = { | 74 | static const struct v4l2_file_operations pcm20_fops = { |
74 | .owner = THIS_MODULE, | 75 | .owner = THIS_MODULE, |
75 | .ioctl = video_ioctl2, | 76 | .unlocked_ioctl = video_ioctl2, |
76 | }; | 77 | }; |
77 | 78 | ||
78 | static int vidioc_querycap(struct file *file, void *priv, | 79 | static int vidioc_querycap(struct file *file, void *priv, |
@@ -229,7 +230,7 @@ static int __init pcm20_init(void) | |||
229 | return -ENODEV; | 230 | return -ENODEV; |
230 | } | 231 | } |
231 | strlcpy(v4l2_dev->name, "miropcm20", sizeof(v4l2_dev->name)); | 232 | strlcpy(v4l2_dev->name, "miropcm20", sizeof(v4l2_dev->name)); |
232 | 233 | mutex_init(&dev->lock); | |
233 | 234 | ||
234 | res = v4l2_device_register(NULL, v4l2_dev); | 235 | res = v4l2_device_register(NULL, v4l2_dev); |
235 | if (res < 0) { | 236 | if (res < 0) { |
@@ -242,6 +243,7 @@ static int __init pcm20_init(void) | |||
242 | dev->vdev.fops = &pcm20_fops; | 243 | dev->vdev.fops = &pcm20_fops; |
243 | dev->vdev.ioctl_ops = &pcm20_ioctl_ops; | 244 | dev->vdev.ioctl_ops = &pcm20_ioctl_ops; |
244 | dev->vdev.release = video_device_release_empty; | 245 | dev->vdev.release = video_device_release_empty; |
246 | dev->vdev.lock = &dev->lock; | ||
245 | video_set_drvdata(&dev->vdev, dev); | 247 | video_set_drvdata(&dev->vdev, dev); |
246 | 248 | ||
247 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) | 249 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) |
diff --git a/drivers/media/radio/radio-rtrack2.c b/drivers/media/radio/radio-rtrack2.c index a79296aac9a9..8d6ea591bd18 100644 --- a/drivers/media/radio/radio-rtrack2.c +++ b/drivers/media/radio/radio-rtrack2.c | |||
@@ -266,7 +266,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
266 | 266 | ||
267 | static const struct v4l2_file_operations rtrack2_fops = { | 267 | static const struct v4l2_file_operations rtrack2_fops = { |
268 | .owner = THIS_MODULE, | 268 | .owner = THIS_MODULE, |
269 | .ioctl = video_ioctl2, | 269 | .unlocked_ioctl = video_ioctl2, |
270 | }; | 270 | }; |
271 | 271 | ||
272 | static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = { | 272 | static const struct v4l2_ioctl_ops rtrack2_ioctl_ops = { |
@@ -315,6 +315,10 @@ static int __init rtrack2_init(void) | |||
315 | dev->vdev.release = video_device_release_empty; | 315 | dev->vdev.release = video_device_release_empty; |
316 | video_set_drvdata(&dev->vdev, dev); | 316 | video_set_drvdata(&dev->vdev, dev); |
317 | 317 | ||
318 | /* mute card - prevents noisy bootups */ | ||
319 | outb(1, dev->io); | ||
320 | dev->muted = 1; | ||
321 | |||
318 | mutex_init(&dev->lock); | 322 | mutex_init(&dev->lock); |
319 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 323 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
320 | v4l2_device_unregister(v4l2_dev); | 324 | v4l2_device_unregister(v4l2_dev); |
@@ -324,10 +328,6 @@ static int __init rtrack2_init(void) | |||
324 | 328 | ||
325 | v4l2_info(v4l2_dev, "AIMSlab Radiotrack II card driver.\n"); | 329 | v4l2_info(v4l2_dev, "AIMSlab Radiotrack II card driver.\n"); |
326 | 330 | ||
327 | /* mute card - prevents noisy bootups */ | ||
328 | outb(1, dev->io); | ||
329 | dev->muted = 1; | ||
330 | |||
331 | return 0; | 331 | return 0; |
332 | } | 332 | } |
333 | 333 | ||
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c index 985359d18aa5..b5a5f89e238a 100644 --- a/drivers/media/radio/radio-sf16fmi.c +++ b/drivers/media/radio/radio-sf16fmi.c | |||
@@ -260,7 +260,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
260 | 260 | ||
261 | static const struct v4l2_file_operations fmi_fops = { | 261 | static const struct v4l2_file_operations fmi_fops = { |
262 | .owner = THIS_MODULE, | 262 | .owner = THIS_MODULE, |
263 | .ioctl = video_ioctl2, | 263 | .unlocked_ioctl = video_ioctl2, |
264 | }; | 264 | }; |
265 | 265 | ||
266 | static const struct v4l2_ioctl_ops fmi_ioctl_ops = { | 266 | static const struct v4l2_ioctl_ops fmi_ioctl_ops = { |
@@ -382,6 +382,9 @@ static int __init fmi_init(void) | |||
382 | 382 | ||
383 | mutex_init(&fmi->lock); | 383 | mutex_init(&fmi->lock); |
384 | 384 | ||
385 | /* mute card - prevents noisy bootups */ | ||
386 | fmi_mute(fmi); | ||
387 | |||
385 | if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 388 | if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
386 | v4l2_device_unregister(v4l2_dev); | 389 | v4l2_device_unregister(v4l2_dev); |
387 | release_region(fmi->io, 2); | 390 | release_region(fmi->io, 2); |
@@ -391,8 +394,6 @@ static int __init fmi_init(void) | |||
391 | } | 394 | } |
392 | 395 | ||
393 | v4l2_info(v4l2_dev, "card driver at 0x%x\n", fmi->io); | 396 | v4l2_info(v4l2_dev, "card driver at 0x%x\n", fmi->io); |
394 | /* mute card - prevents noisy bootups */ | ||
395 | fmi_mute(fmi); | ||
396 | return 0; | 397 | return 0; |
397 | } | 398 | } |
398 | 399 | ||
diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index 52c7bbb32b8b..dc3f04c52d5e 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c | |||
@@ -376,7 +376,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
376 | 376 | ||
377 | static const struct v4l2_file_operations fmr2_fops = { | 377 | static const struct v4l2_file_operations fmr2_fops = { |
378 | .owner = THIS_MODULE, | 378 | .owner = THIS_MODULE, |
379 | .ioctl = video_ioctl2, | 379 | .unlocked_ioctl = video_ioctl2, |
380 | }; | 380 | }; |
381 | 381 | ||
382 | static const struct v4l2_ioctl_ops fmr2_ioctl_ops = { | 382 | static const struct v4l2_ioctl_ops fmr2_ioctl_ops = { |
@@ -424,6 +424,10 @@ static int __init fmr2_init(void) | |||
424 | fmr2->vdev.release = video_device_release_empty; | 424 | fmr2->vdev.release = video_device_release_empty; |
425 | video_set_drvdata(&fmr2->vdev, fmr2); | 425 | video_set_drvdata(&fmr2->vdev, fmr2); |
426 | 426 | ||
427 | /* mute card - prevents noisy bootups */ | ||
428 | fmr2_mute(fmr2->io); | ||
429 | fmr2_product_info(fmr2); | ||
430 | |||
427 | if (video_register_device(&fmr2->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 431 | if (video_register_device(&fmr2->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
428 | v4l2_device_unregister(v4l2_dev); | 432 | v4l2_device_unregister(v4l2_dev); |
429 | release_region(fmr2->io, 2); | 433 | release_region(fmr2->io, 2); |
@@ -431,11 +435,6 @@ static int __init fmr2_init(void) | |||
431 | } | 435 | } |
432 | 436 | ||
433 | v4l2_info(v4l2_dev, "SF16FMR2 radio card driver at 0x%x.\n", fmr2->io); | 437 | v4l2_info(v4l2_dev, "SF16FMR2 radio card driver at 0x%x.\n", fmr2->io); |
434 | /* mute card - prevents noisy bootups */ | ||
435 | mutex_lock(&fmr2->lock); | ||
436 | fmr2_mute(fmr2->io); | ||
437 | fmr2_product_info(fmr2); | ||
438 | mutex_unlock(&fmr2->lock); | ||
439 | debug_print((KERN_DEBUG "card_type %d\n", fmr2->card_type)); | 438 | debug_print((KERN_DEBUG "card_type %d\n", fmr2->card_type)); |
440 | return 0; | 439 | return 0; |
441 | } | 440 | } |
diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c index 03829e6818bd..726d367ad8d0 100644 --- a/drivers/media/radio/radio-si4713.c +++ b/drivers/media/radio/radio-si4713.c | |||
@@ -53,7 +53,8 @@ struct radio_si4713_device { | |||
53 | /* radio_si4713_fops - file operations interface */ | 53 | /* radio_si4713_fops - file operations interface */ |
54 | static const struct v4l2_file_operations radio_si4713_fops = { | 54 | static const struct v4l2_file_operations radio_si4713_fops = { |
55 | .owner = THIS_MODULE, | 55 | .owner = THIS_MODULE, |
56 | .ioctl = video_ioctl2, | 56 | /* Note: locking is done at the subdev level in the i2c driver. */ |
57 | .unlocked_ioctl = video_ioctl2, | ||
57 | }; | 58 | }; |
58 | 59 | ||
59 | /* Video4Linux Interface */ | 60 | /* Video4Linux Interface */ |
diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c index 789d2ec66e19..0e71d816c725 100644 --- a/drivers/media/radio/radio-tea5764.c +++ b/drivers/media/radio/radio-tea5764.c | |||
@@ -142,7 +142,6 @@ struct tea5764_device { | |||
142 | struct video_device *videodev; | 142 | struct video_device *videodev; |
143 | struct tea5764_regs regs; | 143 | struct tea5764_regs regs; |
144 | struct mutex mutex; | 144 | struct mutex mutex; |
145 | int users; | ||
146 | }; | 145 | }; |
147 | 146 | ||
148 | /* I2C code related */ | 147 | /* I2C code related */ |
@@ -458,41 +457,10 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
458 | return 0; | 457 | return 0; |
459 | } | 458 | } |
460 | 459 | ||
461 | static int tea5764_open(struct file *file) | ||
462 | { | ||
463 | /* Currently we support only one device */ | ||
464 | struct tea5764_device *radio = video_drvdata(file); | ||
465 | |||
466 | mutex_lock(&radio->mutex); | ||
467 | /* Only exclusive access */ | ||
468 | if (radio->users) { | ||
469 | mutex_unlock(&radio->mutex); | ||
470 | return -EBUSY; | ||
471 | } | ||
472 | radio->users++; | ||
473 | mutex_unlock(&radio->mutex); | ||
474 | file->private_data = radio; | ||
475 | return 0; | ||
476 | } | ||
477 | |||
478 | static int tea5764_close(struct file *file) | ||
479 | { | ||
480 | struct tea5764_device *radio = video_drvdata(file); | ||
481 | |||
482 | if (!radio) | ||
483 | return -ENODEV; | ||
484 | mutex_lock(&radio->mutex); | ||
485 | radio->users--; | ||
486 | mutex_unlock(&radio->mutex); | ||
487 | return 0; | ||
488 | } | ||
489 | |||
490 | /* File system interface */ | 460 | /* File system interface */ |
491 | static const struct v4l2_file_operations tea5764_fops = { | 461 | static const struct v4l2_file_operations tea5764_fops = { |
492 | .owner = THIS_MODULE, | 462 | .owner = THIS_MODULE, |
493 | .open = tea5764_open, | 463 | .unlocked_ioctl = video_ioctl2, |
494 | .release = tea5764_close, | ||
495 | .ioctl = video_ioctl2, | ||
496 | }; | 464 | }; |
497 | 465 | ||
498 | static const struct v4l2_ioctl_ops tea5764_ioctl_ops = { | 466 | static const struct v4l2_ioctl_ops tea5764_ioctl_ops = { |
@@ -527,7 +495,7 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client, | |||
527 | int ret; | 495 | int ret; |
528 | 496 | ||
529 | PDEBUG("probe"); | 497 | PDEBUG("probe"); |
530 | radio = kmalloc(sizeof(struct tea5764_device), GFP_KERNEL); | 498 | radio = kzalloc(sizeof(struct tea5764_device), GFP_KERNEL); |
531 | if (!radio) | 499 | if (!radio) |
532 | return -ENOMEM; | 500 | return -ENOMEM; |
533 | 501 | ||
@@ -555,12 +523,7 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client, | |||
555 | 523 | ||
556 | i2c_set_clientdata(client, radio); | 524 | i2c_set_clientdata(client, radio); |
557 | video_set_drvdata(radio->videodev, radio); | 525 | video_set_drvdata(radio->videodev, radio); |
558 | 526 | radio->videodev->lock = &radio->mutex; | |
559 | ret = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr); | ||
560 | if (ret < 0) { | ||
561 | PWARN("Could not register video device!"); | ||
562 | goto errrel; | ||
563 | } | ||
564 | 527 | ||
565 | /* initialize and power off the chip */ | 528 | /* initialize and power off the chip */ |
566 | tea5764_i2c_read(radio); | 529 | tea5764_i2c_read(radio); |
@@ -568,6 +531,12 @@ static int __devinit tea5764_i2c_probe(struct i2c_client *client, | |||
568 | tea5764_mute(radio, 1); | 531 | tea5764_mute(radio, 1); |
569 | tea5764_power_down(radio); | 532 | tea5764_power_down(radio); |
570 | 533 | ||
534 | ret = video_register_device(radio->videodev, VFL_TYPE_RADIO, radio_nr); | ||
535 | if (ret < 0) { | ||
536 | PWARN("Could not register video device!"); | ||
537 | goto errrel; | ||
538 | } | ||
539 | |||
571 | PINFO("registered."); | 540 | PINFO("registered."); |
572 | return 0; | 541 | return 0; |
573 | errrel: | 542 | errrel: |
diff --git a/drivers/media/radio/radio-terratec.c b/drivers/media/radio/radio-terratec.c index fc1c860fd438..a32663917059 100644 --- a/drivers/media/radio/radio-terratec.c +++ b/drivers/media/radio/radio-terratec.c | |||
@@ -338,7 +338,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
338 | 338 | ||
339 | static const struct v4l2_file_operations terratec_fops = { | 339 | static const struct v4l2_file_operations terratec_fops = { |
340 | .owner = THIS_MODULE, | 340 | .owner = THIS_MODULE, |
341 | .ioctl = video_ioctl2, | 341 | .unlocked_ioctl = video_ioctl2, |
342 | }; | 342 | }; |
343 | 343 | ||
344 | static const struct v4l2_ioctl_ops terratec_ioctl_ops = { | 344 | static const struct v4l2_ioctl_ops terratec_ioctl_ops = { |
@@ -389,6 +389,9 @@ static int __init terratec_init(void) | |||
389 | 389 | ||
390 | mutex_init(&tt->lock); | 390 | mutex_init(&tt->lock); |
391 | 391 | ||
392 | /* mute card - prevents noisy bootups */ | ||
393 | tt_write_vol(tt, 0); | ||
394 | |||
392 | if (video_register_device(&tt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 395 | if (video_register_device(&tt->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
393 | v4l2_device_unregister(&tt->v4l2_dev); | 396 | v4l2_device_unregister(&tt->v4l2_dev); |
394 | release_region(tt->io, 2); | 397 | release_region(tt->io, 2); |
@@ -396,9 +399,6 @@ static int __init terratec_init(void) | |||
396 | } | 399 | } |
397 | 400 | ||
398 | v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver.\n"); | 401 | v4l2_info(v4l2_dev, "TERRATEC ActivRadio Standalone card driver.\n"); |
399 | |||
400 | /* mute card - prevents noisy bootups */ | ||
401 | tt_write_vol(tt, 0); | ||
402 | return 0; | 402 | return 0; |
403 | } | 403 | } |
404 | 404 | ||
diff --git a/drivers/media/radio/radio-timb.c b/drivers/media/radio/radio-timb.c index b8bb3ef47df5..a185610b376b 100644 --- a/drivers/media/radio/radio-timb.c +++ b/drivers/media/radio/radio-timb.c | |||
@@ -34,6 +34,7 @@ struct timbradio { | |||
34 | struct v4l2_subdev *sd_dsp; | 34 | struct v4l2_subdev *sd_dsp; |
35 | struct video_device video_dev; | 35 | struct video_device video_dev; |
36 | struct v4l2_device v4l2_dev; | 36 | struct v4l2_device v4l2_dev; |
37 | struct mutex lock; | ||
37 | }; | 38 | }; |
38 | 39 | ||
39 | 40 | ||
@@ -142,7 +143,7 @@ static const struct v4l2_ioctl_ops timbradio_ioctl_ops = { | |||
142 | 143 | ||
143 | static const struct v4l2_file_operations timbradio_fops = { | 144 | static const struct v4l2_file_operations timbradio_fops = { |
144 | .owner = THIS_MODULE, | 145 | .owner = THIS_MODULE, |
145 | .ioctl = video_ioctl2, | 146 | .unlocked_ioctl = video_ioctl2, |
146 | }; | 147 | }; |
147 | 148 | ||
148 | static int __devinit timbradio_probe(struct platform_device *pdev) | 149 | static int __devinit timbradio_probe(struct platform_device *pdev) |
@@ -164,6 +165,7 @@ static int __devinit timbradio_probe(struct platform_device *pdev) | |||
164 | } | 165 | } |
165 | 166 | ||
166 | tr->pdata = *pdata; | 167 | tr->pdata = *pdata; |
168 | mutex_init(&tr->lock); | ||
167 | 169 | ||
168 | strlcpy(tr->video_dev.name, "Timberdale Radio", | 170 | strlcpy(tr->video_dev.name, "Timberdale Radio", |
169 | sizeof(tr->video_dev.name)); | 171 | sizeof(tr->video_dev.name)); |
@@ -171,6 +173,7 @@ static int __devinit timbradio_probe(struct platform_device *pdev) | |||
171 | tr->video_dev.ioctl_ops = &timbradio_ioctl_ops; | 173 | tr->video_dev.ioctl_ops = &timbradio_ioctl_ops; |
172 | tr->video_dev.release = video_device_release_empty; | 174 | tr->video_dev.release = video_device_release_empty; |
173 | tr->video_dev.minor = -1; | 175 | tr->video_dev.minor = -1; |
176 | tr->video_dev.lock = &tr->lock; | ||
174 | 177 | ||
175 | strlcpy(tr->v4l2_dev.name, DRIVER_NAME, sizeof(tr->v4l2_dev.name)); | 178 | strlcpy(tr->v4l2_dev.name, DRIVER_NAME, sizeof(tr->v4l2_dev.name)); |
176 | err = v4l2_device_register(NULL, &tr->v4l2_dev); | 179 | err = v4l2_device_register(NULL, &tr->v4l2_dev); |
diff --git a/drivers/media/radio/radio-trust.c b/drivers/media/radio/radio-trust.c index 9d6dcf8af5b0..22fa9cc28abe 100644 --- a/drivers/media/radio/radio-trust.c +++ b/drivers/media/radio/radio-trust.c | |||
@@ -344,7 +344,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
344 | 344 | ||
345 | static const struct v4l2_file_operations trust_fops = { | 345 | static const struct v4l2_file_operations trust_fops = { |
346 | .owner = THIS_MODULE, | 346 | .owner = THIS_MODULE, |
347 | .ioctl = video_ioctl2, | 347 | .unlocked_ioctl = video_ioctl2, |
348 | }; | 348 | }; |
349 | 349 | ||
350 | static const struct v4l2_ioctl_ops trust_ioctl_ops = { | 350 | static const struct v4l2_ioctl_ops trust_ioctl_ops = { |
@@ -396,14 +396,6 @@ static int __init trust_init(void) | |||
396 | tr->vdev.release = video_device_release_empty; | 396 | tr->vdev.release = video_device_release_empty; |
397 | video_set_drvdata(&tr->vdev, tr); | 397 | video_set_drvdata(&tr->vdev, tr); |
398 | 398 | ||
399 | if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
400 | v4l2_device_unregister(v4l2_dev); | ||
401 | release_region(tr->io, 2); | ||
402 | return -EINVAL; | ||
403 | } | ||
404 | |||
405 | v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n"); | ||
406 | |||
407 | write_i2c(tr, 2, TDA7318_ADDR, 0x80); /* speaker att. LF = 0 dB */ | 399 | write_i2c(tr, 2, TDA7318_ADDR, 0x80); /* speaker att. LF = 0 dB */ |
408 | write_i2c(tr, 2, TDA7318_ADDR, 0xa0); /* speaker att. RF = 0 dB */ | 400 | write_i2c(tr, 2, TDA7318_ADDR, 0xa0); /* speaker att. RF = 0 dB */ |
409 | write_i2c(tr, 2, TDA7318_ADDR, 0xc0); /* speaker att. LR = 0 dB */ | 401 | write_i2c(tr, 2, TDA7318_ADDR, 0xc0); /* speaker att. LR = 0 dB */ |
@@ -418,6 +410,14 @@ static int __init trust_init(void) | |||
418 | /* mute card - prevents noisy bootups */ | 410 | /* mute card - prevents noisy bootups */ |
419 | tr_setmute(tr, 1); | 411 | tr_setmute(tr, 1); |
420 | 412 | ||
413 | if (video_register_device(&tr->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
414 | v4l2_device_unregister(v4l2_dev); | ||
415 | release_region(tr->io, 2); | ||
416 | return -EINVAL; | ||
417 | } | ||
418 | |||
419 | v4l2_info(v4l2_dev, "Trust FM Radio card driver v1.0.\n"); | ||
420 | |||
421 | return 0; | 421 | return 0; |
422 | } | 422 | } |
423 | 423 | ||
diff --git a/drivers/media/radio/radio-typhoon.c b/drivers/media/radio/radio-typhoon.c index b1f630527dc1..8dbbf08f2207 100644 --- a/drivers/media/radio/radio-typhoon.c +++ b/drivers/media/radio/radio-typhoon.c | |||
@@ -317,7 +317,7 @@ static int vidioc_log_status(struct file *file, void *priv) | |||
317 | 317 | ||
318 | static const struct v4l2_file_operations typhoon_fops = { | 318 | static const struct v4l2_file_operations typhoon_fops = { |
319 | .owner = THIS_MODULE, | 319 | .owner = THIS_MODULE, |
320 | .ioctl = video_ioctl2, | 320 | .unlocked_ioctl = video_ioctl2, |
321 | }; | 321 | }; |
322 | 322 | ||
323 | static const struct v4l2_ioctl_ops typhoon_ioctl_ops = { | 323 | static const struct v4l2_ioctl_ops typhoon_ioctl_ops = { |
@@ -344,18 +344,18 @@ static int __init typhoon_init(void) | |||
344 | 344 | ||
345 | strlcpy(v4l2_dev->name, "typhoon", sizeof(v4l2_dev->name)); | 345 | strlcpy(v4l2_dev->name, "typhoon", sizeof(v4l2_dev->name)); |
346 | dev->io = io; | 346 | dev->io = io; |
347 | dev->curfreq = dev->mutefreq = mutefreq; | ||
348 | 347 | ||
349 | if (dev->io == -1) { | 348 | if (dev->io == -1) { |
350 | v4l2_err(v4l2_dev, "You must set an I/O address with io=0x316 or io=0x336\n"); | 349 | v4l2_err(v4l2_dev, "You must set an I/O address with io=0x316 or io=0x336\n"); |
351 | return -EINVAL; | 350 | return -EINVAL; |
352 | } | 351 | } |
353 | 352 | ||
354 | if (dev->mutefreq < 87000 || dev->mutefreq > 108500) { | 353 | if (mutefreq < 87000 || mutefreq > 108500) { |
355 | v4l2_err(v4l2_dev, "You must set a frequency (in kHz) used when muting the card,\n"); | 354 | v4l2_err(v4l2_dev, "You must set a frequency (in kHz) used when muting the card,\n"); |
356 | v4l2_err(v4l2_dev, "e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n"); | 355 | v4l2_err(v4l2_dev, "e.g. with \"mutefreq=87500\" (87000 <= mutefreq <= 108500)\n"); |
357 | return -EINVAL; | 356 | return -EINVAL; |
358 | } | 357 | } |
358 | dev->curfreq = dev->mutefreq = mutefreq << 4; | ||
359 | 359 | ||
360 | mutex_init(&dev->lock); | 360 | mutex_init(&dev->lock); |
361 | if (!request_region(dev->io, 8, "typhoon")) { | 361 | if (!request_region(dev->io, 8, "typhoon")) { |
@@ -378,17 +378,17 @@ static int __init typhoon_init(void) | |||
378 | dev->vdev.ioctl_ops = &typhoon_ioctl_ops; | 378 | dev->vdev.ioctl_ops = &typhoon_ioctl_ops; |
379 | dev->vdev.release = video_device_release_empty; | 379 | dev->vdev.release = video_device_release_empty; |
380 | video_set_drvdata(&dev->vdev, dev); | 380 | video_set_drvdata(&dev->vdev, dev); |
381 | |||
382 | /* mute card - prevents noisy bootups */ | ||
383 | typhoon_mute(dev); | ||
384 | |||
381 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | 385 | if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { |
382 | v4l2_device_unregister(&dev->v4l2_dev); | 386 | v4l2_device_unregister(&dev->v4l2_dev); |
383 | release_region(dev->io, 8); | 387 | release_region(dev->io, 8); |
384 | return -EINVAL; | 388 | return -EINVAL; |
385 | } | 389 | } |
386 | v4l2_info(v4l2_dev, "port 0x%x.\n", dev->io); | 390 | v4l2_info(v4l2_dev, "port 0x%x.\n", dev->io); |
387 | v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", dev->mutefreq); | 391 | v4l2_info(v4l2_dev, "mute frequency is %lu kHz.\n", mutefreq); |
388 | dev->mutefreq <<= 4; | ||
389 | |||
390 | /* mute card - prevents noisy bootups */ | ||
391 | typhoon_mute(dev); | ||
392 | 392 | ||
393 | return 0; | 393 | return 0; |
394 | } | 394 | } |
diff --git a/drivers/media/radio/radio-zoltrix.c b/drivers/media/radio/radio-zoltrix.c index f31eab99c943..af99c5bd88c1 100644 --- a/drivers/media/radio/radio-zoltrix.c +++ b/drivers/media/radio/radio-zoltrix.c | |||
@@ -377,7 +377,7 @@ static int vidioc_s_audio(struct file *file, void *priv, | |||
377 | static const struct v4l2_file_operations zoltrix_fops = | 377 | static const struct v4l2_file_operations zoltrix_fops = |
378 | { | 378 | { |
379 | .owner = THIS_MODULE, | 379 | .owner = THIS_MODULE, |
380 | .ioctl = video_ioctl2, | 380 | .unlocked_ioctl = video_ioctl2, |
381 | }; | 381 | }; |
382 | 382 | ||
383 | static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = { | 383 | static const struct v4l2_ioctl_ops zoltrix_ioctl_ops = { |
@@ -424,20 +424,6 @@ static int __init zoltrix_init(void) | |||
424 | return res; | 424 | return res; |
425 | } | 425 | } |
426 | 426 | ||
427 | strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name)); | ||
428 | zol->vdev.v4l2_dev = v4l2_dev; | ||
429 | zol->vdev.fops = &zoltrix_fops; | ||
430 | zol->vdev.ioctl_ops = &zoltrix_ioctl_ops; | ||
431 | zol->vdev.release = video_device_release_empty; | ||
432 | video_set_drvdata(&zol->vdev, zol); | ||
433 | |||
434 | if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
435 | v4l2_device_unregister(v4l2_dev); | ||
436 | release_region(zol->io, 2); | ||
437 | return -EINVAL; | ||
438 | } | ||
439 | v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n"); | ||
440 | |||
441 | mutex_init(&zol->lock); | 427 | mutex_init(&zol->lock); |
442 | 428 | ||
443 | /* mute card - prevents noisy bootups */ | 429 | /* mute card - prevents noisy bootups */ |
@@ -452,6 +438,20 @@ static int __init zoltrix_init(void) | |||
452 | zol->curvol = 0; | 438 | zol->curvol = 0; |
453 | zol->stereo = 1; | 439 | zol->stereo = 1; |
454 | 440 | ||
441 | strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name)); | ||
442 | zol->vdev.v4l2_dev = v4l2_dev; | ||
443 | zol->vdev.fops = &zoltrix_fops; | ||
444 | zol->vdev.ioctl_ops = &zoltrix_ioctl_ops; | ||
445 | zol->vdev.release = video_device_release_empty; | ||
446 | video_set_drvdata(&zol->vdev, zol); | ||
447 | |||
448 | if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { | ||
449 | v4l2_device_unregister(v4l2_dev); | ||
450 | release_region(zol->io, 2); | ||
451 | return -EINVAL; | ||
452 | } | ||
453 | v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n"); | ||
454 | |||
455 | return 0; | 455 | return 0; |
456 | } | 456 | } |
457 | 457 | ||
diff --git a/drivers/media/video/arv.c b/drivers/media/video/arv.c index 31e7a123d19a..f989f2820d88 100644 --- a/drivers/media/video/arv.c +++ b/drivers/media/video/arv.c | |||
@@ -712,7 +712,7 @@ static int ar_initialize(struct ar *ar) | |||
712 | static const struct v4l2_file_operations ar_fops = { | 712 | static const struct v4l2_file_operations ar_fops = { |
713 | .owner = THIS_MODULE, | 713 | .owner = THIS_MODULE, |
714 | .read = ar_read, | 714 | .read = ar_read, |
715 | .ioctl = video_ioctl2, | 715 | .unlocked_ioctl = video_ioctl2, |
716 | }; | 716 | }; |
717 | 717 | ||
718 | static const struct v4l2_ioctl_ops ar_ioctl_ops = { | 718 | static const struct v4l2_ioctl_ops ar_ioctl_ops = { |
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index a529619e51f6..0902ec041c7a 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -854,7 +854,6 @@ int check_alloc_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bit) | |||
854 | xbits |= RESOURCE_VIDEO_READ | RESOURCE_VIDEO_STREAM; | 854 | xbits |= RESOURCE_VIDEO_READ | RESOURCE_VIDEO_STREAM; |
855 | 855 | ||
856 | /* is it free? */ | 856 | /* is it free? */ |
857 | mutex_lock(&btv->lock); | ||
858 | if (btv->resources & xbits) { | 857 | if (btv->resources & xbits) { |
859 | /* no, someone else uses it */ | 858 | /* no, someone else uses it */ |
860 | goto fail; | 859 | goto fail; |
@@ -884,11 +883,9 @@ int check_alloc_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bit) | |||
884 | /* it's free, grab it */ | 883 | /* it's free, grab it */ |
885 | fh->resources |= bit; | 884 | fh->resources |= bit; |
886 | btv->resources |= bit; | 885 | btv->resources |= bit; |
887 | mutex_unlock(&btv->lock); | ||
888 | return 1; | 886 | return 1; |
889 | 887 | ||
890 | fail: | 888 | fail: |
891 | mutex_unlock(&btv->lock); | ||
892 | return 0; | 889 | return 0; |
893 | } | 890 | } |
894 | 891 | ||
@@ -940,7 +937,6 @@ void free_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bits) | |||
940 | /* trying to free ressources not allocated by us ... */ | 937 | /* trying to free ressources not allocated by us ... */ |
941 | printk("bttv: BUG! (btres)\n"); | 938 | printk("bttv: BUG! (btres)\n"); |
942 | } | 939 | } |
943 | mutex_lock(&btv->lock); | ||
944 | fh->resources &= ~bits; | 940 | fh->resources &= ~bits; |
945 | btv->resources &= ~bits; | 941 | btv->resources &= ~bits; |
946 | 942 | ||
@@ -951,8 +947,6 @@ void free_btres_lock(struct bttv *btv, struct bttv_fh *fh, int bits) | |||
951 | 947 | ||
952 | if (0 == (bits & VBI_RESOURCES)) | 948 | if (0 == (bits & VBI_RESOURCES)) |
953 | disclaim_vbi_lines(btv); | 949 | disclaim_vbi_lines(btv); |
954 | |||
955 | mutex_unlock(&btv->lock); | ||
956 | } | 950 | } |
957 | 951 | ||
958 | /* ----------------------------------------------------------------------- */ | 952 | /* ----------------------------------------------------------------------- */ |
@@ -1713,28 +1707,20 @@ static int bttv_prepare_buffer(struct videobuf_queue *q,struct bttv *btv, | |||
1713 | 1707 | ||
1714 | /* Make sure tvnorm and vbi_end remain consistent | 1708 | /* Make sure tvnorm and vbi_end remain consistent |
1715 | until we're done. */ | 1709 | until we're done. */ |
1716 | mutex_lock(&btv->lock); | ||
1717 | 1710 | ||
1718 | norm = btv->tvnorm; | 1711 | norm = btv->tvnorm; |
1719 | 1712 | ||
1720 | /* In this mode capturing always starts at defrect.top | 1713 | /* In this mode capturing always starts at defrect.top |
1721 | (default VDELAY), ignoring cropping parameters. */ | 1714 | (default VDELAY), ignoring cropping parameters. */ |
1722 | if (btv->vbi_end > bttv_tvnorms[norm].cropcap.defrect.top) { | 1715 | if (btv->vbi_end > bttv_tvnorms[norm].cropcap.defrect.top) { |
1723 | mutex_unlock(&btv->lock); | ||
1724 | return -EINVAL; | 1716 | return -EINVAL; |
1725 | } | 1717 | } |
1726 | 1718 | ||
1727 | mutex_unlock(&btv->lock); | ||
1728 | |||
1729 | c.rect = bttv_tvnorms[norm].cropcap.defrect; | 1719 | c.rect = bttv_tvnorms[norm].cropcap.defrect; |
1730 | } else { | 1720 | } else { |
1731 | mutex_lock(&btv->lock); | ||
1732 | |||
1733 | norm = btv->tvnorm; | 1721 | norm = btv->tvnorm; |
1734 | c = btv->crop[!!fh->do_crop]; | 1722 | c = btv->crop[!!fh->do_crop]; |
1735 | 1723 | ||
1736 | mutex_unlock(&btv->lock); | ||
1737 | |||
1738 | if (width < c.min_scaled_width || | 1724 | if (width < c.min_scaled_width || |
1739 | width > c.max_scaled_width || | 1725 | width > c.max_scaled_width || |
1740 | height < c.min_scaled_height) | 1726 | height < c.min_scaled_height) |
@@ -1858,7 +1844,6 @@ static int bttv_s_std(struct file *file, void *priv, v4l2_std_id *id) | |||
1858 | unsigned int i; | 1844 | unsigned int i; |
1859 | int err; | 1845 | int err; |
1860 | 1846 | ||
1861 | mutex_lock(&btv->lock); | ||
1862 | err = v4l2_prio_check(&btv->prio, fh->prio); | 1847 | err = v4l2_prio_check(&btv->prio, fh->prio); |
1863 | if (err) | 1848 | if (err) |
1864 | goto err; | 1849 | goto err; |
@@ -1874,7 +1859,6 @@ static int bttv_s_std(struct file *file, void *priv, v4l2_std_id *id) | |||
1874 | set_tvnorm(btv, i); | 1859 | set_tvnorm(btv, i); |
1875 | 1860 | ||
1876 | err: | 1861 | err: |
1877 | mutex_unlock(&btv->lock); | ||
1878 | 1862 | ||
1879 | return err; | 1863 | return err; |
1880 | } | 1864 | } |
@@ -1898,7 +1882,6 @@ static int bttv_enum_input(struct file *file, void *priv, | |||
1898 | struct bttv *btv = fh->btv; | 1882 | struct bttv *btv = fh->btv; |
1899 | int rc = 0; | 1883 | int rc = 0; |
1900 | 1884 | ||
1901 | mutex_lock(&btv->lock); | ||
1902 | if (i->index >= bttv_tvcards[btv->c.type].video_inputs) { | 1885 | if (i->index >= bttv_tvcards[btv->c.type].video_inputs) { |
1903 | rc = -EINVAL; | 1886 | rc = -EINVAL; |
1904 | goto err; | 1887 | goto err; |
@@ -1928,7 +1911,6 @@ static int bttv_enum_input(struct file *file, void *priv, | |||
1928 | i->std = BTTV_NORMS; | 1911 | i->std = BTTV_NORMS; |
1929 | 1912 | ||
1930 | err: | 1913 | err: |
1931 | mutex_unlock(&btv->lock); | ||
1932 | 1914 | ||
1933 | return rc; | 1915 | return rc; |
1934 | } | 1916 | } |
@@ -1938,9 +1920,7 @@ static int bttv_g_input(struct file *file, void *priv, unsigned int *i) | |||
1938 | struct bttv_fh *fh = priv; | 1920 | struct bttv_fh *fh = priv; |
1939 | struct bttv *btv = fh->btv; | 1921 | struct bttv *btv = fh->btv; |
1940 | 1922 | ||
1941 | mutex_lock(&btv->lock); | ||
1942 | *i = btv->input; | 1923 | *i = btv->input; |
1943 | mutex_unlock(&btv->lock); | ||
1944 | 1924 | ||
1945 | return 0; | 1925 | return 0; |
1946 | } | 1926 | } |
@@ -1952,7 +1932,6 @@ static int bttv_s_input(struct file *file, void *priv, unsigned int i) | |||
1952 | 1932 | ||
1953 | int err; | 1933 | int err; |
1954 | 1934 | ||
1955 | mutex_lock(&btv->lock); | ||
1956 | err = v4l2_prio_check(&btv->prio, fh->prio); | 1935 | err = v4l2_prio_check(&btv->prio, fh->prio); |
1957 | if (unlikely(err)) | 1936 | if (unlikely(err)) |
1958 | goto err; | 1937 | goto err; |
@@ -1965,7 +1944,6 @@ static int bttv_s_input(struct file *file, void *priv, unsigned int i) | |||
1965 | set_input(btv, i, btv->tvnorm); | 1944 | set_input(btv, i, btv->tvnorm); |
1966 | 1945 | ||
1967 | err: | 1946 | err: |
1968 | mutex_unlock(&btv->lock); | ||
1969 | return 0; | 1947 | return 0; |
1970 | } | 1948 | } |
1971 | 1949 | ||
@@ -1979,7 +1957,6 @@ static int bttv_s_tuner(struct file *file, void *priv, | |||
1979 | if (unlikely(0 != t->index)) | 1957 | if (unlikely(0 != t->index)) |
1980 | return -EINVAL; | 1958 | return -EINVAL; |
1981 | 1959 | ||
1982 | mutex_lock(&btv->lock); | ||
1983 | if (unlikely(btv->tuner_type == TUNER_ABSENT)) { | 1960 | if (unlikely(btv->tuner_type == TUNER_ABSENT)) { |
1984 | err = -EINVAL; | 1961 | err = -EINVAL; |
1985 | goto err; | 1962 | goto err; |
@@ -1995,7 +1972,6 @@ static int bttv_s_tuner(struct file *file, void *priv, | |||
1995 | btv->audio_mode_gpio(btv, t, 1); | 1972 | btv->audio_mode_gpio(btv, t, 1); |
1996 | 1973 | ||
1997 | err: | 1974 | err: |
1998 | mutex_unlock(&btv->lock); | ||
1999 | 1975 | ||
2000 | return 0; | 1976 | return 0; |
2001 | } | 1977 | } |
@@ -2006,10 +1982,8 @@ static int bttv_g_frequency(struct file *file, void *priv, | |||
2006 | struct bttv_fh *fh = priv; | 1982 | struct bttv_fh *fh = priv; |
2007 | struct bttv *btv = fh->btv; | 1983 | struct bttv *btv = fh->btv; |
2008 | 1984 | ||
2009 | mutex_lock(&btv->lock); | ||
2010 | f->type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | 1985 | f->type = btv->radio_user ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; |
2011 | f->frequency = btv->freq; | 1986 | f->frequency = btv->freq; |
2012 | mutex_unlock(&btv->lock); | ||
2013 | 1987 | ||
2014 | return 0; | 1988 | return 0; |
2015 | } | 1989 | } |
@@ -2024,7 +1998,6 @@ static int bttv_s_frequency(struct file *file, void *priv, | |||
2024 | if (unlikely(f->tuner != 0)) | 1998 | if (unlikely(f->tuner != 0)) |
2025 | return -EINVAL; | 1999 | return -EINVAL; |
2026 | 2000 | ||
2027 | mutex_lock(&btv->lock); | ||
2028 | err = v4l2_prio_check(&btv->prio, fh->prio); | 2001 | err = v4l2_prio_check(&btv->prio, fh->prio); |
2029 | if (unlikely(err)) | 2002 | if (unlikely(err)) |
2030 | goto err; | 2003 | goto err; |
@@ -2039,7 +2012,6 @@ static int bttv_s_frequency(struct file *file, void *priv, | |||
2039 | if (btv->has_matchbox && btv->radio_user) | 2012 | if (btv->has_matchbox && btv->radio_user) |
2040 | tea5757_set_freq(btv, btv->freq); | 2013 | tea5757_set_freq(btv, btv->freq); |
2041 | err: | 2014 | err: |
2042 | mutex_unlock(&btv->lock); | ||
2043 | 2015 | ||
2044 | return 0; | 2016 | return 0; |
2045 | } | 2017 | } |
@@ -2172,7 +2144,6 @@ limit_scaled_size_lock (struct bttv_fh * fh, | |||
2172 | 2144 | ||
2173 | /* Make sure tvnorm, vbi_end and the current cropping parameters | 2145 | /* Make sure tvnorm, vbi_end and the current cropping parameters |
2174 | remain consistent until we're done. */ | 2146 | remain consistent until we're done. */ |
2175 | mutex_lock(&btv->lock); | ||
2176 | 2147 | ||
2177 | b = &bttv_tvnorms[btv->tvnorm].cropcap.bounds; | 2148 | b = &bttv_tvnorms[btv->tvnorm].cropcap.bounds; |
2178 | 2149 | ||
@@ -2250,7 +2221,6 @@ limit_scaled_size_lock (struct bttv_fh * fh, | |||
2250 | rc = 0; /* success */ | 2221 | rc = 0; /* success */ |
2251 | 2222 | ||
2252 | fail: | 2223 | fail: |
2253 | mutex_unlock(&btv->lock); | ||
2254 | 2224 | ||
2255 | return rc; | 2225 | return rc; |
2256 | } | 2226 | } |
@@ -2282,9 +2252,7 @@ verify_window_lock (struct bttv_fh * fh, | |||
2282 | if (V4L2_FIELD_ANY == field) { | 2252 | if (V4L2_FIELD_ANY == field) { |
2283 | __s32 height2; | 2253 | __s32 height2; |
2284 | 2254 | ||
2285 | mutex_lock(&fh->btv->lock); | ||
2286 | height2 = fh->btv->crop[!!fh->do_crop].rect.height >> 1; | 2255 | height2 = fh->btv->crop[!!fh->do_crop].rect.height >> 1; |
2287 | mutex_unlock(&fh->btv->lock); | ||
2288 | field = (win->w.height > height2) | 2256 | field = (win->w.height > height2) |
2289 | ? V4L2_FIELD_INTERLACED | 2257 | ? V4L2_FIELD_INTERLACED |
2290 | : V4L2_FIELD_TOP; | 2258 | : V4L2_FIELD_TOP; |
@@ -2360,7 +2328,6 @@ static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv, | |||
2360 | } | 2328 | } |
2361 | } | 2329 | } |
2362 | 2330 | ||
2363 | mutex_lock(&fh->cap.vb_lock); | ||
2364 | /* clip against screen */ | 2331 | /* clip against screen */ |
2365 | if (NULL != btv->fbuf.base) | 2332 | if (NULL != btv->fbuf.base) |
2366 | n = btcx_screen_clips(btv->fbuf.fmt.width, btv->fbuf.fmt.height, | 2333 | n = btcx_screen_clips(btv->fbuf.fmt.width, btv->fbuf.fmt.height, |
@@ -2391,13 +2358,6 @@ static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv, | |||
2391 | fh->ov.field = win->field; | 2358 | fh->ov.field = win->field; |
2392 | fh->ov.setup_ok = 1; | 2359 | fh->ov.setup_ok = 1; |
2393 | 2360 | ||
2394 | /* | ||
2395 | * FIXME: btv is protected by btv->lock mutex, while btv->init | ||
2396 | * is protected by fh->cap.vb_lock. This seems to open the | ||
2397 | * possibility for some race situations. Maybe the better would | ||
2398 | * be to unify those locks or to use another way to store the | ||
2399 | * init values that will be consumed by videobuf callbacks | ||
2400 | */ | ||
2401 | btv->init.ov.w.width = win->w.width; | 2361 | btv->init.ov.w.width = win->w.width; |
2402 | btv->init.ov.w.height = win->w.height; | 2362 | btv->init.ov.w.height = win->w.height; |
2403 | btv->init.ov.field = win->field; | 2363 | btv->init.ov.field = win->field; |
@@ -2412,7 +2372,6 @@ static int setup_window_lock(struct bttv_fh *fh, struct bttv *btv, | |||
2412 | bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); | 2372 | bttv_overlay_risc(btv, &fh->ov, fh->ovfmt, new); |
2413 | retval = bttv_switch_overlay(btv,fh,new); | 2373 | retval = bttv_switch_overlay(btv,fh,new); |
2414 | } | 2374 | } |
2415 | mutex_unlock(&fh->cap.vb_lock); | ||
2416 | return retval; | 2375 | return retval; |
2417 | } | 2376 | } |
2418 | 2377 | ||
@@ -2526,9 +2485,7 @@ static int bttv_try_fmt_vid_cap(struct file *file, void *priv, | |||
2526 | if (V4L2_FIELD_ANY == field) { | 2485 | if (V4L2_FIELD_ANY == field) { |
2527 | __s32 height2; | 2486 | __s32 height2; |
2528 | 2487 | ||
2529 | mutex_lock(&btv->lock); | ||
2530 | height2 = btv->crop[!!fh->do_crop].rect.height >> 1; | 2488 | height2 = btv->crop[!!fh->do_crop].rect.height >> 1; |
2531 | mutex_unlock(&btv->lock); | ||
2532 | field = (f->fmt.pix.height > height2) | 2489 | field = (f->fmt.pix.height > height2) |
2533 | ? V4L2_FIELD_INTERLACED | 2490 | ? V4L2_FIELD_INTERLACED |
2534 | : V4L2_FIELD_BOTTOM; | 2491 | : V4L2_FIELD_BOTTOM; |
@@ -2614,7 +2571,6 @@ static int bttv_s_fmt_vid_cap(struct file *file, void *priv, | |||
2614 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); | 2571 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); |
2615 | 2572 | ||
2616 | /* update our state informations */ | 2573 | /* update our state informations */ |
2617 | mutex_lock(&fh->cap.vb_lock); | ||
2618 | fh->fmt = fmt; | 2574 | fh->fmt = fmt; |
2619 | fh->cap.field = f->fmt.pix.field; | 2575 | fh->cap.field = f->fmt.pix.field; |
2620 | fh->cap.last = V4L2_FIELD_NONE; | 2576 | fh->cap.last = V4L2_FIELD_NONE; |
@@ -2623,7 +2579,6 @@ static int bttv_s_fmt_vid_cap(struct file *file, void *priv, | |||
2623 | btv->init.fmt = fmt; | 2579 | btv->init.fmt = fmt; |
2624 | btv->init.width = f->fmt.pix.width; | 2580 | btv->init.width = f->fmt.pix.width; |
2625 | btv->init.height = f->fmt.pix.height; | 2581 | btv->init.height = f->fmt.pix.height; |
2626 | mutex_unlock(&fh->cap.vb_lock); | ||
2627 | 2582 | ||
2628 | return 0; | 2583 | return 0; |
2629 | } | 2584 | } |
@@ -2649,11 +2604,9 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) | |||
2649 | unsigned int i; | 2604 | unsigned int i; |
2650 | struct bttv_fh *fh = priv; | 2605 | struct bttv_fh *fh = priv; |
2651 | 2606 | ||
2652 | mutex_lock(&fh->cap.vb_lock); | ||
2653 | retval = __videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize, | 2607 | retval = __videobuf_mmap_setup(&fh->cap, gbuffers, gbufsize, |
2654 | V4L2_MEMORY_MMAP); | 2608 | V4L2_MEMORY_MMAP); |
2655 | if (retval < 0) { | 2609 | if (retval < 0) { |
2656 | mutex_unlock(&fh->cap.vb_lock); | ||
2657 | return retval; | 2610 | return retval; |
2658 | } | 2611 | } |
2659 | 2612 | ||
@@ -2665,7 +2618,6 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf) | |||
2665 | for (i = 0; i < gbuffers; i++) | 2618 | for (i = 0; i < gbuffers; i++) |
2666 | mbuf->offsets[i] = i * gbufsize; | 2619 | mbuf->offsets[i] = i * gbufsize; |
2667 | 2620 | ||
2668 | mutex_unlock(&fh->cap.vb_lock); | ||
2669 | return 0; | 2621 | return 0; |
2670 | } | 2622 | } |
2671 | #endif | 2623 | #endif |
@@ -2775,10 +2727,8 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on) | |||
2775 | int retval = 0; | 2727 | int retval = 0; |
2776 | 2728 | ||
2777 | if (on) { | 2729 | if (on) { |
2778 | mutex_lock(&fh->cap.vb_lock); | ||
2779 | /* verify args */ | 2730 | /* verify args */ |
2780 | if (unlikely(!btv->fbuf.base)) { | 2731 | if (unlikely(!btv->fbuf.base)) { |
2781 | mutex_unlock(&fh->cap.vb_lock); | ||
2782 | return -EINVAL; | 2732 | return -EINVAL; |
2783 | } | 2733 | } |
2784 | if (unlikely(!fh->ov.setup_ok)) { | 2734 | if (unlikely(!fh->ov.setup_ok)) { |
@@ -2787,13 +2737,11 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on) | |||
2787 | } | 2737 | } |
2788 | if (retval) | 2738 | if (retval) |
2789 | return retval; | 2739 | return retval; |
2790 | mutex_unlock(&fh->cap.vb_lock); | ||
2791 | } | 2740 | } |
2792 | 2741 | ||
2793 | if (!check_alloc_btres_lock(btv, fh, RESOURCE_OVERLAY)) | 2742 | if (!check_alloc_btres_lock(btv, fh, RESOURCE_OVERLAY)) |
2794 | return -EBUSY; | 2743 | return -EBUSY; |
2795 | 2744 | ||
2796 | mutex_lock(&fh->cap.vb_lock); | ||
2797 | if (on) { | 2745 | if (on) { |
2798 | fh->ov.tvnorm = btv->tvnorm; | 2746 | fh->ov.tvnorm = btv->tvnorm; |
2799 | new = videobuf_sg_alloc(sizeof(*new)); | 2747 | new = videobuf_sg_alloc(sizeof(*new)); |
@@ -2805,7 +2753,6 @@ static int bttv_overlay(struct file *file, void *f, unsigned int on) | |||
2805 | 2753 | ||
2806 | /* switch over */ | 2754 | /* switch over */ |
2807 | retval = bttv_switch_overlay(btv, fh, new); | 2755 | retval = bttv_switch_overlay(btv, fh, new); |
2808 | mutex_unlock(&fh->cap.vb_lock); | ||
2809 | return retval; | 2756 | return retval; |
2810 | } | 2757 | } |
2811 | 2758 | ||
@@ -2844,7 +2791,6 @@ static int bttv_s_fbuf(struct file *file, void *f, | |||
2844 | } | 2791 | } |
2845 | 2792 | ||
2846 | /* ok, accept it */ | 2793 | /* ok, accept it */ |
2847 | mutex_lock(&fh->cap.vb_lock); | ||
2848 | btv->fbuf.base = fb->base; | 2794 | btv->fbuf.base = fb->base; |
2849 | btv->fbuf.fmt.width = fb->fmt.width; | 2795 | btv->fbuf.fmt.width = fb->fmt.width; |
2850 | btv->fbuf.fmt.height = fb->fmt.height; | 2796 | btv->fbuf.fmt.height = fb->fmt.height; |
@@ -2876,7 +2822,6 @@ static int bttv_s_fbuf(struct file *file, void *f, | |||
2876 | retval = bttv_switch_overlay(btv, fh, new); | 2822 | retval = bttv_switch_overlay(btv, fh, new); |
2877 | } | 2823 | } |
2878 | } | 2824 | } |
2879 | mutex_unlock(&fh->cap.vb_lock); | ||
2880 | return retval; | 2825 | return retval; |
2881 | } | 2826 | } |
2882 | 2827 | ||
@@ -2955,7 +2900,6 @@ static int bttv_queryctrl(struct file *file, void *priv, | |||
2955 | c->id >= V4L2_CID_PRIVATE_LASTP1)) | 2900 | c->id >= V4L2_CID_PRIVATE_LASTP1)) |
2956 | return -EINVAL; | 2901 | return -EINVAL; |
2957 | 2902 | ||
2958 | mutex_lock(&btv->lock); | ||
2959 | if (!btv->volume_gpio && (c->id == V4L2_CID_AUDIO_VOLUME)) | 2903 | if (!btv->volume_gpio && (c->id == V4L2_CID_AUDIO_VOLUME)) |
2960 | *c = no_ctl; | 2904 | *c = no_ctl; |
2961 | else { | 2905 | else { |
@@ -2963,7 +2907,6 @@ static int bttv_queryctrl(struct file *file, void *priv, | |||
2963 | 2907 | ||
2964 | *c = (NULL != ctrl) ? *ctrl : no_ctl; | 2908 | *c = (NULL != ctrl) ? *ctrl : no_ctl; |
2965 | } | 2909 | } |
2966 | mutex_unlock(&btv->lock); | ||
2967 | 2910 | ||
2968 | return 0; | 2911 | return 0; |
2969 | } | 2912 | } |
@@ -2974,10 +2917,8 @@ static int bttv_g_parm(struct file *file, void *f, | |||
2974 | struct bttv_fh *fh = f; | 2917 | struct bttv_fh *fh = f; |
2975 | struct bttv *btv = fh->btv; | 2918 | struct bttv *btv = fh->btv; |
2976 | 2919 | ||
2977 | mutex_lock(&btv->lock); | ||
2978 | v4l2_video_std_frame_period(bttv_tvnorms[btv->tvnorm].v4l2_id, | 2920 | v4l2_video_std_frame_period(bttv_tvnorms[btv->tvnorm].v4l2_id, |
2979 | &parm->parm.capture.timeperframe); | 2921 | &parm->parm.capture.timeperframe); |
2980 | mutex_unlock(&btv->lock); | ||
2981 | 2922 | ||
2982 | return 0; | 2923 | return 0; |
2983 | } | 2924 | } |
@@ -2993,7 +2934,6 @@ static int bttv_g_tuner(struct file *file, void *priv, | |||
2993 | if (0 != t->index) | 2934 | if (0 != t->index) |
2994 | return -EINVAL; | 2935 | return -EINVAL; |
2995 | 2936 | ||
2996 | mutex_lock(&btv->lock); | ||
2997 | t->rxsubchans = V4L2_TUNER_SUB_MONO; | 2937 | t->rxsubchans = V4L2_TUNER_SUB_MONO; |
2998 | bttv_call_all(btv, tuner, g_tuner, t); | 2938 | bttv_call_all(btv, tuner, g_tuner, t); |
2999 | strcpy(t->name, "Television"); | 2939 | strcpy(t->name, "Television"); |
@@ -3005,7 +2945,6 @@ static int bttv_g_tuner(struct file *file, void *priv, | |||
3005 | if (btv->audio_mode_gpio) | 2945 | if (btv->audio_mode_gpio) |
3006 | btv->audio_mode_gpio(btv, t, 0); | 2946 | btv->audio_mode_gpio(btv, t, 0); |
3007 | 2947 | ||
3008 | mutex_unlock(&btv->lock); | ||
3009 | return 0; | 2948 | return 0; |
3010 | } | 2949 | } |
3011 | 2950 | ||
@@ -3014,9 +2953,7 @@ static int bttv_g_priority(struct file *file, void *f, enum v4l2_priority *p) | |||
3014 | struct bttv_fh *fh = f; | 2953 | struct bttv_fh *fh = f; |
3015 | struct bttv *btv = fh->btv; | 2954 | struct bttv *btv = fh->btv; |
3016 | 2955 | ||
3017 | mutex_lock(&btv->lock); | ||
3018 | *p = v4l2_prio_max(&btv->prio); | 2956 | *p = v4l2_prio_max(&btv->prio); |
3019 | mutex_unlock(&btv->lock); | ||
3020 | 2957 | ||
3021 | return 0; | 2958 | return 0; |
3022 | } | 2959 | } |
@@ -3028,9 +2965,7 @@ static int bttv_s_priority(struct file *file, void *f, | |||
3028 | struct bttv *btv = fh->btv; | 2965 | struct bttv *btv = fh->btv; |
3029 | int rc; | 2966 | int rc; |
3030 | 2967 | ||
3031 | mutex_lock(&btv->lock); | ||
3032 | rc = v4l2_prio_change(&btv->prio, &fh->prio, prio); | 2968 | rc = v4l2_prio_change(&btv->prio, &fh->prio, prio); |
3033 | mutex_unlock(&btv->lock); | ||
3034 | 2969 | ||
3035 | return rc; | 2970 | return rc; |
3036 | } | 2971 | } |
@@ -3045,9 +2980,7 @@ static int bttv_cropcap(struct file *file, void *priv, | |||
3045 | cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) | 2980 | cap->type != V4L2_BUF_TYPE_VIDEO_OVERLAY) |
3046 | return -EINVAL; | 2981 | return -EINVAL; |
3047 | 2982 | ||
3048 | mutex_lock(&btv->lock); | ||
3049 | *cap = bttv_tvnorms[btv->tvnorm].cropcap; | 2983 | *cap = bttv_tvnorms[btv->tvnorm].cropcap; |
3050 | mutex_unlock(&btv->lock); | ||
3051 | 2984 | ||
3052 | return 0; | 2985 | return 0; |
3053 | } | 2986 | } |
@@ -3065,9 +2998,7 @@ static int bttv_g_crop(struct file *file, void *f, struct v4l2_crop *crop) | |||
3065 | inconsistent with fh->width or fh->height and apps | 2998 | inconsistent with fh->width or fh->height and apps |
3066 | do not expect a change here. */ | 2999 | do not expect a change here. */ |
3067 | 3000 | ||
3068 | mutex_lock(&btv->lock); | ||
3069 | crop->c = btv->crop[!!fh->do_crop].rect; | 3001 | crop->c = btv->crop[!!fh->do_crop].rect; |
3070 | mutex_unlock(&btv->lock); | ||
3071 | 3002 | ||
3072 | return 0; | 3003 | return 0; |
3073 | } | 3004 | } |
@@ -3091,17 +3022,14 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop) | |||
3091 | /* Make sure tvnorm, vbi_end and the current cropping | 3022 | /* Make sure tvnorm, vbi_end and the current cropping |
3092 | parameters remain consistent until we're done. Note | 3023 | parameters remain consistent until we're done. Note |
3093 | read() may change vbi_end in check_alloc_btres_lock(). */ | 3024 | read() may change vbi_end in check_alloc_btres_lock(). */ |
3094 | mutex_lock(&btv->lock); | ||
3095 | retval = v4l2_prio_check(&btv->prio, fh->prio); | 3025 | retval = v4l2_prio_check(&btv->prio, fh->prio); |
3096 | if (0 != retval) { | 3026 | if (0 != retval) { |
3097 | mutex_unlock(&btv->lock); | ||
3098 | return retval; | 3027 | return retval; |
3099 | } | 3028 | } |
3100 | 3029 | ||
3101 | retval = -EBUSY; | 3030 | retval = -EBUSY; |
3102 | 3031 | ||
3103 | if (locked_btres(fh->btv, VIDEO_RESOURCES)) { | 3032 | if (locked_btres(fh->btv, VIDEO_RESOURCES)) { |
3104 | mutex_unlock(&btv->lock); | ||
3105 | return retval; | 3033 | return retval; |
3106 | } | 3034 | } |
3107 | 3035 | ||
@@ -3113,7 +3041,6 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop) | |||
3113 | 3041 | ||
3114 | b_top = max(b->top, btv->vbi_end); | 3042 | b_top = max(b->top, btv->vbi_end); |
3115 | if (b_top + 32 >= b_bottom) { | 3043 | if (b_top + 32 >= b_bottom) { |
3116 | mutex_unlock(&btv->lock); | ||
3117 | return retval; | 3044 | return retval; |
3118 | } | 3045 | } |
3119 | 3046 | ||
@@ -3136,12 +3063,8 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop) | |||
3136 | 3063 | ||
3137 | btv->crop[1] = c; | 3064 | btv->crop[1] = c; |
3138 | 3065 | ||
3139 | mutex_unlock(&btv->lock); | ||
3140 | |||
3141 | fh->do_crop = 1; | 3066 | fh->do_crop = 1; |
3142 | 3067 | ||
3143 | mutex_lock(&fh->cap.vb_lock); | ||
3144 | |||
3145 | if (fh->width < c.min_scaled_width) { | 3068 | if (fh->width < c.min_scaled_width) { |
3146 | fh->width = c.min_scaled_width; | 3069 | fh->width = c.min_scaled_width; |
3147 | btv->init.width = c.min_scaled_width; | 3070 | btv->init.width = c.min_scaled_width; |
@@ -3158,8 +3081,6 @@ static int bttv_s_crop(struct file *file, void *f, struct v4l2_crop *crop) | |||
3158 | btv->init.height = c.max_scaled_height; | 3081 | btv->init.height = c.max_scaled_height; |
3159 | } | 3082 | } |
3160 | 3083 | ||
3161 | mutex_unlock(&fh->cap.vb_lock); | ||
3162 | |||
3163 | return 0; | 3084 | return 0; |
3164 | } | 3085 | } |
3165 | 3086 | ||
@@ -3227,7 +3148,6 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) | |||
3227 | return videobuf_poll_stream(file, &fh->vbi, wait); | 3148 | return videobuf_poll_stream(file, &fh->vbi, wait); |
3228 | } | 3149 | } |
3229 | 3150 | ||
3230 | mutex_lock(&fh->cap.vb_lock); | ||
3231 | if (check_btres(fh,RESOURCE_VIDEO_STREAM)) { | 3151 | if (check_btres(fh,RESOURCE_VIDEO_STREAM)) { |
3232 | /* streaming capture */ | 3152 | /* streaming capture */ |
3233 | if (list_empty(&fh->cap.stream)) | 3153 | if (list_empty(&fh->cap.stream)) |
@@ -3262,7 +3182,6 @@ static unsigned int bttv_poll(struct file *file, poll_table *wait) | |||
3262 | else | 3182 | else |
3263 | rc = 0; | 3183 | rc = 0; |
3264 | err: | 3184 | err: |
3265 | mutex_unlock(&fh->cap.vb_lock); | ||
3266 | return rc; | 3185 | return rc; |
3267 | } | 3186 | } |
3268 | 3187 | ||
@@ -3293,23 +3212,11 @@ static int bttv_open(struct file *file) | |||
3293 | return -ENOMEM; | 3212 | return -ENOMEM; |
3294 | file->private_data = fh; | 3213 | file->private_data = fh; |
3295 | 3214 | ||
3296 | /* | ||
3297 | * btv is protected by btv->lock mutex, while btv->init and other | ||
3298 | * streaming vars are protected by fh->cap.vb_lock. We need to take | ||
3299 | * care of both locks to avoid troubles. However, vb_lock is used also | ||
3300 | * inside videobuf, without calling buf->lock. So, it is a very bad | ||
3301 | * idea to hold both locks at the same time. | ||
3302 | * Let's first copy btv->init at fh, holding cap.vb_lock, and then work | ||
3303 | * with the rest of init, holding btv->lock. | ||
3304 | */ | ||
3305 | mutex_lock(&fh->cap.vb_lock); | ||
3306 | *fh = btv->init; | 3215 | *fh = btv->init; |
3307 | mutex_unlock(&fh->cap.vb_lock); | ||
3308 | 3216 | ||
3309 | fh->type = type; | 3217 | fh->type = type; |
3310 | fh->ov.setup_ok = 0; | 3218 | fh->ov.setup_ok = 0; |
3311 | 3219 | ||
3312 | mutex_lock(&btv->lock); | ||
3313 | v4l2_prio_open(&btv->prio, &fh->prio); | 3220 | v4l2_prio_open(&btv->prio, &fh->prio); |
3314 | 3221 | ||
3315 | videobuf_queue_sg_init(&fh->cap, &bttv_video_qops, | 3222 | videobuf_queue_sg_init(&fh->cap, &bttv_video_qops, |
@@ -3317,13 +3224,13 @@ static int bttv_open(struct file *file) | |||
3317 | V4L2_BUF_TYPE_VIDEO_CAPTURE, | 3224 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
3318 | V4L2_FIELD_INTERLACED, | 3225 | V4L2_FIELD_INTERLACED, |
3319 | sizeof(struct bttv_buffer), | 3226 | sizeof(struct bttv_buffer), |
3320 | fh, NULL); | 3227 | fh, &btv->lock); |
3321 | videobuf_queue_sg_init(&fh->vbi, &bttv_vbi_qops, | 3228 | videobuf_queue_sg_init(&fh->vbi, &bttv_vbi_qops, |
3322 | &btv->c.pci->dev, &btv->s_lock, | 3229 | &btv->c.pci->dev, &btv->s_lock, |
3323 | V4L2_BUF_TYPE_VBI_CAPTURE, | 3230 | V4L2_BUF_TYPE_VBI_CAPTURE, |
3324 | V4L2_FIELD_SEQ_TB, | 3231 | V4L2_FIELD_SEQ_TB, |
3325 | sizeof(struct bttv_buffer), | 3232 | sizeof(struct bttv_buffer), |
3326 | fh, NULL); | 3233 | fh, &btv->lock); |
3327 | set_tvnorm(btv,btv->tvnorm); | 3234 | set_tvnorm(btv,btv->tvnorm); |
3328 | set_input(btv, btv->input, btv->tvnorm); | 3235 | set_input(btv, btv->input, btv->tvnorm); |
3329 | 3236 | ||
@@ -3346,7 +3253,6 @@ static int bttv_open(struct file *file) | |||
3346 | bttv_vbi_fmt_reset(&fh->vbi_fmt, btv->tvnorm); | 3253 | bttv_vbi_fmt_reset(&fh->vbi_fmt, btv->tvnorm); |
3347 | 3254 | ||
3348 | bttv_field_count(btv); | 3255 | bttv_field_count(btv); |
3349 | mutex_unlock(&btv->lock); | ||
3350 | return 0; | 3256 | return 0; |
3351 | } | 3257 | } |
3352 | 3258 | ||
@@ -3355,7 +3261,6 @@ static int bttv_release(struct file *file) | |||
3355 | struct bttv_fh *fh = file->private_data; | 3261 | struct bttv_fh *fh = file->private_data; |
3356 | struct bttv *btv = fh->btv; | 3262 | struct bttv *btv = fh->btv; |
3357 | 3263 | ||
3358 | mutex_lock(&btv->lock); | ||
3359 | /* turn off overlay */ | 3264 | /* turn off overlay */ |
3360 | if (check_btres(fh, RESOURCE_OVERLAY)) | 3265 | if (check_btres(fh, RESOURCE_OVERLAY)) |
3361 | bttv_switch_overlay(btv,fh,NULL); | 3266 | bttv_switch_overlay(btv,fh,NULL); |
@@ -3381,14 +3286,8 @@ static int bttv_release(struct file *file) | |||
3381 | 3286 | ||
3382 | /* free stuff */ | 3287 | /* free stuff */ |
3383 | 3288 | ||
3384 | /* | ||
3385 | * videobuf uses cap.vb_lock - we should avoid holding btv->lock, | ||
3386 | * otherwise we may have dead lock conditions | ||
3387 | */ | ||
3388 | mutex_unlock(&btv->lock); | ||
3389 | videobuf_mmap_free(&fh->cap); | 3289 | videobuf_mmap_free(&fh->cap); |
3390 | videobuf_mmap_free(&fh->vbi); | 3290 | videobuf_mmap_free(&fh->vbi); |
3391 | mutex_lock(&btv->lock); | ||
3392 | v4l2_prio_close(&btv->prio, fh->prio); | 3291 | v4l2_prio_close(&btv->prio, fh->prio); |
3393 | file->private_data = NULL; | 3292 | file->private_data = NULL; |
3394 | kfree(fh); | 3293 | kfree(fh); |
@@ -3398,7 +3297,6 @@ static int bttv_release(struct file *file) | |||
3398 | 3297 | ||
3399 | if (!btv->users) | 3298 | if (!btv->users) |
3400 | audio_mute(btv, 1); | 3299 | audio_mute(btv, 1); |
3401 | mutex_unlock(&btv->lock); | ||
3402 | 3300 | ||
3403 | return 0; | 3301 | return 0; |
3404 | } | 3302 | } |
@@ -3502,11 +3400,8 @@ static int radio_open(struct file *file) | |||
3502 | if (unlikely(!fh)) | 3400 | if (unlikely(!fh)) |
3503 | return -ENOMEM; | 3401 | return -ENOMEM; |
3504 | file->private_data = fh; | 3402 | file->private_data = fh; |
3505 | mutex_lock(&fh->cap.vb_lock); | ||
3506 | *fh = btv->init; | 3403 | *fh = btv->init; |
3507 | mutex_unlock(&fh->cap.vb_lock); | ||
3508 | 3404 | ||
3509 | mutex_lock(&btv->lock); | ||
3510 | v4l2_prio_open(&btv->prio, &fh->prio); | 3405 | v4l2_prio_open(&btv->prio, &fh->prio); |
3511 | 3406 | ||
3512 | btv->radio_user++; | 3407 | btv->radio_user++; |
@@ -3514,7 +3409,6 @@ static int radio_open(struct file *file) | |||
3514 | bttv_call_all(btv, tuner, s_radio); | 3409 | bttv_call_all(btv, tuner, s_radio); |
3515 | audio_input(btv,TVAUDIO_INPUT_RADIO); | 3410 | audio_input(btv,TVAUDIO_INPUT_RADIO); |
3516 | 3411 | ||
3517 | mutex_unlock(&btv->lock); | ||
3518 | return 0; | 3412 | return 0; |
3519 | } | 3413 | } |
3520 | 3414 | ||
@@ -3524,7 +3418,6 @@ static int radio_release(struct file *file) | |||
3524 | struct bttv *btv = fh->btv; | 3418 | struct bttv *btv = fh->btv; |
3525 | struct rds_command cmd; | 3419 | struct rds_command cmd; |
3526 | 3420 | ||
3527 | mutex_lock(&btv->lock); | ||
3528 | v4l2_prio_close(&btv->prio, fh->prio); | 3421 | v4l2_prio_close(&btv->prio, fh->prio); |
3529 | file->private_data = NULL; | 3422 | file->private_data = NULL; |
3530 | kfree(fh); | 3423 | kfree(fh); |
@@ -3532,7 +3425,6 @@ static int radio_release(struct file *file) | |||
3532 | btv->radio_user--; | 3425 | btv->radio_user--; |
3533 | 3426 | ||
3534 | bttv_call_all(btv, core, ioctl, RDS_CMD_CLOSE, &cmd); | 3427 | bttv_call_all(btv, core, ioctl, RDS_CMD_CLOSE, &cmd); |
3535 | mutex_unlock(&btv->lock); | ||
3536 | 3428 | ||
3537 | return 0; | 3429 | return 0; |
3538 | } | 3430 | } |
@@ -3561,7 +3453,6 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) | |||
3561 | return -EINVAL; | 3453 | return -EINVAL; |
3562 | if (0 != t->index) | 3454 | if (0 != t->index) |
3563 | return -EINVAL; | 3455 | return -EINVAL; |
3564 | mutex_lock(&btv->lock); | ||
3565 | strcpy(t->name, "Radio"); | 3456 | strcpy(t->name, "Radio"); |
3566 | t->type = V4L2_TUNER_RADIO; | 3457 | t->type = V4L2_TUNER_RADIO; |
3567 | 3458 | ||
@@ -3570,8 +3461,6 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t) | |||
3570 | if (btv->audio_mode_gpio) | 3461 | if (btv->audio_mode_gpio) |
3571 | btv->audio_mode_gpio(btv, t, 0); | 3462 | btv->audio_mode_gpio(btv, t, 0); |
3572 | 3463 | ||
3573 | mutex_unlock(&btv->lock); | ||
3574 | |||
3575 | return 0; | 3464 | return 0; |
3576 | } | 3465 | } |
3577 | 3466 | ||
@@ -3692,7 +3581,7 @@ static const struct v4l2_file_operations radio_fops = | |||
3692 | .open = radio_open, | 3581 | .open = radio_open, |
3693 | .read = radio_read, | 3582 | .read = radio_read, |
3694 | .release = radio_release, | 3583 | .release = radio_release, |
3695 | .ioctl = video_ioctl2, | 3584 | .unlocked_ioctl = video_ioctl2, |
3696 | .poll = radio_poll, | 3585 | .poll = radio_poll, |
3697 | }; | 3586 | }; |
3698 | 3587 | ||
diff --git a/drivers/media/video/bw-qcam.c b/drivers/media/video/bw-qcam.c index 935e0c9a9674..c1193506131c 100644 --- a/drivers/media/video/bw-qcam.c +++ b/drivers/media/video/bw-qcam.c | |||
@@ -860,7 +860,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf, | |||
860 | 860 | ||
861 | static const struct v4l2_file_operations qcam_fops = { | 861 | static const struct v4l2_file_operations qcam_fops = { |
862 | .owner = THIS_MODULE, | 862 | .owner = THIS_MODULE, |
863 | .ioctl = video_ioctl2, | 863 | .unlocked_ioctl = video_ioctl2, |
864 | .read = qcam_read, | 864 | .read = qcam_read, |
865 | }; | 865 | }; |
866 | 866 | ||
diff --git a/drivers/media/video/c-qcam.c b/drivers/media/video/c-qcam.c index 6e4b19698c13..24fc00965a12 100644 --- a/drivers/media/video/c-qcam.c +++ b/drivers/media/video/c-qcam.c | |||
@@ -718,7 +718,7 @@ static ssize_t qcam_read(struct file *file, char __user *buf, | |||
718 | 718 | ||
719 | static const struct v4l2_file_operations qcam_fops = { | 719 | static const struct v4l2_file_operations qcam_fops = { |
720 | .owner = THIS_MODULE, | 720 | .owner = THIS_MODULE, |
721 | .ioctl = video_ioctl2, | 721 | .unlocked_ioctl = video_ioctl2, |
722 | .read = qcam_read, | 722 | .read = qcam_read, |
723 | }; | 723 | }; |
724 | 724 | ||
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 260c666ce931..0dfff50891e4 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c | |||
@@ -1775,7 +1775,7 @@ static const struct v4l2_file_operations cafe_v4l_fops = { | |||
1775 | .read = cafe_v4l_read, | 1775 | .read = cafe_v4l_read, |
1776 | .poll = cafe_v4l_poll, | 1776 | .poll = cafe_v4l_poll, |
1777 | .mmap = cafe_v4l_mmap, | 1777 | .mmap = cafe_v4l_mmap, |
1778 | .ioctl = video_ioctl2, | 1778 | .unlocked_ioctl = video_ioctl2, |
1779 | }; | 1779 | }; |
1780 | 1780 | ||
1781 | static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = { | 1781 | static const struct v4l2_ioctl_ops cafe_v4l_ioctl_ops = { |
diff --git a/drivers/media/video/cx18/cx18-alsa-pcm.c b/drivers/media/video/cx18/cx18-alsa-pcm.c index 8f55692db36d..82d195be9197 100644 --- a/drivers/media/video/cx18/cx18-alsa-pcm.c +++ b/drivers/media/video/cx18/cx18-alsa-pcm.c | |||
@@ -218,7 +218,13 @@ static int snd_cx18_pcm_capture_close(struct snd_pcm_substream *substream) | |||
218 | static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream, | 218 | static int snd_cx18_pcm_ioctl(struct snd_pcm_substream *substream, |
219 | unsigned int cmd, void *arg) | 219 | unsigned int cmd, void *arg) |
220 | { | 220 | { |
221 | return snd_pcm_lib_ioctl(substream, cmd, arg); | 221 | struct snd_cx18_card *cxsc = snd_pcm_substream_chip(substream); |
222 | int ret; | ||
223 | |||
224 | snd_cx18_lock(cxsc); | ||
225 | ret = snd_pcm_lib_ioctl(substream, cmd, arg); | ||
226 | snd_cx18_unlock(cxsc); | ||
227 | return ret; | ||
222 | } | 228 | } |
223 | 229 | ||
224 | 230 | ||
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index 9045f1ece0eb..ab461e27d9dd 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c | |||
@@ -41,7 +41,7 @@ static struct v4l2_file_operations cx18_v4l2_enc_fops = { | |||
41 | .read = cx18_v4l2_read, | 41 | .read = cx18_v4l2_read, |
42 | .open = cx18_v4l2_open, | 42 | .open = cx18_v4l2_open, |
43 | /* FIXME change to video_ioctl2 if serialization lock can be removed */ | 43 | /* FIXME change to video_ioctl2 if serialization lock can be removed */ |
44 | .ioctl = cx18_v4l2_ioctl, | 44 | .unlocked_ioctl = cx18_v4l2_ioctl, |
45 | .release = cx18_v4l2_close, | 45 | .release = cx18_v4l2_close, |
46 | .poll = cx18_v4l2_enc_poll, | 46 | .poll = cx18_v4l2_enc_poll, |
47 | }; | 47 | }; |
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index dfb198d0415b..f16461844c5c 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c | |||
@@ -1989,8 +1989,23 @@ static int cx25840_probe(struct i2c_client *client, | |||
1989 | v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops, | 1989 | v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops, |
1990 | V4L2_CID_HUE, -128, 127, 1, 0); | 1990 | V4L2_CID_HUE, -128, 127, 1, 0); |
1991 | if (!is_cx2583x(state)) { | 1991 | if (!is_cx2583x(state)) { |
1992 | default_volume = 228 - cx25840_read(client, 0x8d4); | 1992 | default_volume = cx25840_read(client, 0x8d4); |
1993 | default_volume = ((default_volume / 2) + 23) << 9; | 1993 | /* |
1994 | * Enforce the legacy PVR-350/MSP3400 to PVR-150/CX25843 volume | ||
1995 | * scale mapping limits to avoid -ERANGE errors when | ||
1996 | * initializing the volume control | ||
1997 | */ | ||
1998 | if (default_volume > 228) { | ||
1999 | /* Bottom out at -96 dB, v4l2 vol range 0x2e00-0x2fff */ | ||
2000 | default_volume = 228; | ||
2001 | cx25840_write(client, 0x8d4, 228); | ||
2002 | } | ||
2003 | else if (default_volume < 20) { | ||
2004 | /* Top out at + 8 dB, v4l2 vol range 0xfe00-0xffff */ | ||
2005 | default_volume = 20; | ||
2006 | cx25840_write(client, 0x8d4, 20); | ||
2007 | } | ||
2008 | default_volume = (((228 - default_volume) >> 1) + 23) << 9; | ||
1994 | 2009 | ||
1995 | state->volume = v4l2_ctrl_new_std(&state->hdl, | 2010 | state->volume = v4l2_ctrl_new_std(&state->hdl, |
1996 | &cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME, | 2011 | &cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME, |
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c index 4aaa47c0eabf..54b7fcd469a8 100644 --- a/drivers/media/video/cx88/cx88-alsa.c +++ b/drivers/media/video/cx88/cx88-alsa.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include <sound/control.h> | 40 | #include <sound/control.h> |
41 | #include <sound/initval.h> | 41 | #include <sound/initval.h> |
42 | #include <sound/tlv.h> | 42 | #include <sound/tlv.h> |
43 | #include <media/wm8775.h> | ||
44 | 43 | ||
45 | #include "cx88.h" | 44 | #include "cx88.h" |
46 | #include "cx88-reg.h" | 45 | #include "cx88-reg.h" |
@@ -587,47 +586,26 @@ static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol, | |||
587 | int left, right, v, b; | 586 | int left, right, v, b; |
588 | int changed = 0; | 587 | int changed = 0; |
589 | u32 old; | 588 | u32 old; |
590 | struct v4l2_control client_ctl; | ||
591 | |||
592 | /* Pass volume & balance onto any WM8775 */ | ||
593 | if (value->value.integer.value[0] >= value->value.integer.value[1]) { | ||
594 | v = value->value.integer.value[0] << 10; | ||
595 | b = value->value.integer.value[0] ? | ||
596 | (0x8000 * value->value.integer.value[1]) / value->value.integer.value[0] : | ||
597 | 0x8000; | ||
598 | } else { | ||
599 | v = value->value.integer.value[1] << 10; | ||
600 | b = value->value.integer.value[1] ? | ||
601 | 0xffff - (0x8000 * value->value.integer.value[0]) / value->value.integer.value[1] : | ||
602 | 0x8000; | ||
603 | } | ||
604 | client_ctl.value = v; | ||
605 | client_ctl.id = V4L2_CID_AUDIO_VOLUME; | ||
606 | call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl); | ||
607 | |||
608 | client_ctl.value = b; | ||
609 | client_ctl.id = V4L2_CID_AUDIO_BALANCE; | ||
610 | call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl); | ||
611 | 589 | ||
612 | left = value->value.integer.value[0] & 0x3f; | 590 | left = value->value.integer.value[0] & 0x3f; |
613 | right = value->value.integer.value[1] & 0x3f; | 591 | right = value->value.integer.value[1] & 0x3f; |
614 | b = right - left; | 592 | b = right - left; |
615 | if (b < 0) { | 593 | if (b < 0) { |
616 | v = 0x3f - left; | 594 | v = 0x3f - left; |
617 | b = (-b) | 0x40; | 595 | b = (-b) | 0x40; |
618 | } else { | 596 | } else { |
619 | v = 0x3f - right; | 597 | v = 0x3f - right; |
620 | } | 598 | } |
621 | /* Do we really know this will always be called with IRQs on? */ | 599 | /* Do we really know this will always be called with IRQs on? */ |
622 | spin_lock_irq(&chip->reg_lock); | 600 | spin_lock_irq(&chip->reg_lock); |
623 | old = cx_read(AUD_VOL_CTL); | 601 | old = cx_read(AUD_VOL_CTL); |
624 | if (v != (old & 0x3f)) { | 602 | if (v != (old & 0x3f)) { |
625 | cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, (old & ~0x3f) | v); | 603 | cx_write(AUD_VOL_CTL, (old & ~0x3f) | v); |
626 | changed = 1; | 604 | changed = 1; |
627 | } | 605 | } |
628 | if ((cx_read(AUD_BAL_CTL) & 0x7f) != b) { | 606 | if (cx_read(AUD_BAL_CTL) != b) { |
629 | cx_write(AUD_BAL_CTL, b); | 607 | cx_write(AUD_BAL_CTL, b); |
630 | changed = 1; | 608 | changed = 1; |
631 | } | 609 | } |
632 | spin_unlock_irq(&chip->reg_lock); | 610 | spin_unlock_irq(&chip->reg_lock); |
633 | 611 | ||
@@ -640,7 +618,7 @@ static const struct snd_kcontrol_new snd_cx88_volume = { | |||
640 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 618 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
641 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | 619 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | |
642 | SNDRV_CTL_ELEM_ACCESS_TLV_READ, | 620 | SNDRV_CTL_ELEM_ACCESS_TLV_READ, |
643 | .name = "Analog-TV Volume", | 621 | .name = "Playback Volume", |
644 | .info = snd_cx88_volume_info, | 622 | .info = snd_cx88_volume_info, |
645 | .get = snd_cx88_volume_get, | 623 | .get = snd_cx88_volume_get, |
646 | .put = snd_cx88_volume_put, | 624 | .put = snd_cx88_volume_put, |
@@ -671,14 +649,7 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol, | |||
671 | vol = cx_read(AUD_VOL_CTL); | 649 | vol = cx_read(AUD_VOL_CTL); |
672 | if (value->value.integer.value[0] != !(vol & bit)) { | 650 | if (value->value.integer.value[0] != !(vol & bit)) { |
673 | vol ^= bit; | 651 | vol ^= bit; |
674 | cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, vol); | 652 | cx_write(AUD_VOL_CTL, vol); |
675 | /* Pass mute onto any WM8775 */ | ||
676 | if ((1<<6) == bit) { | ||
677 | struct v4l2_control client_ctl; | ||
678 | client_ctl.value = 0 != (vol & bit); | ||
679 | client_ctl.id = V4L2_CID_AUDIO_MUTE; | ||
680 | call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl); | ||
681 | } | ||
682 | ret = 1; | 653 | ret = 1; |
683 | } | 654 | } |
684 | spin_unlock_irq(&chip->reg_lock); | 655 | spin_unlock_irq(&chip->reg_lock); |
@@ -687,7 +658,7 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol, | |||
687 | 658 | ||
688 | static const struct snd_kcontrol_new snd_cx88_dac_switch = { | 659 | static const struct snd_kcontrol_new snd_cx88_dac_switch = { |
689 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 660 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
690 | .name = "Audio-Out Switch", | 661 | .name = "Playback Switch", |
691 | .info = snd_ctl_boolean_mono_info, | 662 | .info = snd_ctl_boolean_mono_info, |
692 | .get = snd_cx88_switch_get, | 663 | .get = snd_cx88_switch_get, |
693 | .put = snd_cx88_switch_put, | 664 | .put = snd_cx88_switch_put, |
@@ -696,49 +667,13 @@ static const struct snd_kcontrol_new snd_cx88_dac_switch = { | |||
696 | 667 | ||
697 | static const struct snd_kcontrol_new snd_cx88_source_switch = { | 668 | static const struct snd_kcontrol_new snd_cx88_source_switch = { |
698 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 669 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
699 | .name = "Analog-TV Switch", | 670 | .name = "Capture Switch", |
700 | .info = snd_ctl_boolean_mono_info, | 671 | .info = snd_ctl_boolean_mono_info, |
701 | .get = snd_cx88_switch_get, | 672 | .get = snd_cx88_switch_get, |
702 | .put = snd_cx88_switch_put, | 673 | .put = snd_cx88_switch_put, |
703 | .private_value = (1<<6), | 674 | .private_value = (1<<6), |
704 | }; | 675 | }; |
705 | 676 | ||
706 | static int snd_cx88_alc_get(struct snd_kcontrol *kcontrol, | ||
707 | struct snd_ctl_elem_value *value) | ||
708 | { | ||
709 | snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); | ||
710 | struct cx88_core *core = chip->core; | ||
711 | struct v4l2_control client_ctl; | ||
712 | |||
713 | client_ctl.id = V4L2_CID_AUDIO_LOUDNESS; | ||
714 | call_hw(core, WM8775_GID, core, g_ctrl, &client_ctl); | ||
715 | value->value.integer.value[0] = client_ctl.value ? 1 : 0; | ||
716 | |||
717 | return 0; | ||
718 | } | ||
719 | |||
720 | static int snd_cx88_alc_put(struct snd_kcontrol *kcontrol, | ||
721 | struct snd_ctl_elem_value *value) | ||
722 | { | ||
723 | snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol); | ||
724 | struct cx88_core *core = chip->core; | ||
725 | struct v4l2_control client_ctl; | ||
726 | |||
727 | client_ctl.value = 0 != value->value.integer.value[0]; | ||
728 | client_ctl.id = V4L2_CID_AUDIO_LOUDNESS; | ||
729 | call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl); | ||
730 | |||
731 | return 0; | ||
732 | } | ||
733 | |||
734 | static struct snd_kcontrol_new snd_cx88_alc_switch = { | ||
735 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
736 | .name = "Line-In ALC Switch", | ||
737 | .info = snd_ctl_boolean_mono_info, | ||
738 | .get = snd_cx88_alc_get, | ||
739 | .put = snd_cx88_alc_put, | ||
740 | }; | ||
741 | |||
742 | /**************************************************************************** | 677 | /**************************************************************************** |
743 | Basic Flow for Sound Devices | 678 | Basic Flow for Sound Devices |
744 | ****************************************************************************/ | 679 | ****************************************************************************/ |
@@ -860,7 +795,6 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci, | |||
860 | { | 795 | { |
861 | struct snd_card *card; | 796 | struct snd_card *card; |
862 | snd_cx88_card_t *chip; | 797 | snd_cx88_card_t *chip; |
863 | struct v4l2_subdev *sd; | ||
864 | int err; | 798 | int err; |
865 | 799 | ||
866 | if (devno >= SNDRV_CARDS) | 800 | if (devno >= SNDRV_CARDS) |
@@ -896,15 +830,6 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci, | |||
896 | if (err < 0) | 830 | if (err < 0) |
897 | goto error; | 831 | goto error; |
898 | 832 | ||
899 | /* If there's a wm8775 then add a Line-In ALC switch */ | ||
900 | list_for_each_entry(sd, &chip->core->v4l2_dev.subdevs, list) { | ||
901 | if (WM8775_GID == sd->grp_id) { | ||
902 | snd_ctl_add(card, snd_ctl_new1(&snd_cx88_alc_switch, | ||
903 | chip)); | ||
904 | break; | ||
905 | } | ||
906 | } | ||
907 | |||
908 | strcpy (card->driver, "CX88x"); | 833 | strcpy (card->driver, "CX88x"); |
909 | sprintf(card->shortname, "Conexant CX%x", pci->device); | 834 | sprintf(card->shortname, "Conexant CX%x", pci->device); |
910 | sprintf(card->longname, "%s at %#llx", | 835 | sprintf(card->longname, "%s at %#llx", |
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index 9b9e169cce90..0ccc2afd7266 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c | |||
@@ -1007,15 +1007,22 @@ static const struct cx88_board cx88_boards[] = { | |||
1007 | .radio_type = UNSET, | 1007 | .radio_type = UNSET, |
1008 | .tuner_addr = ADDR_UNSET, | 1008 | .tuner_addr = ADDR_UNSET, |
1009 | .radio_addr = ADDR_UNSET, | 1009 | .radio_addr = ADDR_UNSET, |
1010 | .audio_chip = V4L2_IDENT_WM8775, | ||
1010 | .input = {{ | 1011 | .input = {{ |
1011 | .type = CX88_VMUX_DVB, | 1012 | .type = CX88_VMUX_DVB, |
1012 | .vmux = 0, | 1013 | .vmux = 0, |
1014 | /* 2: Line-In */ | ||
1015 | .audioroute = 2, | ||
1013 | },{ | 1016 | },{ |
1014 | .type = CX88_VMUX_COMPOSITE1, | 1017 | .type = CX88_VMUX_COMPOSITE1, |
1015 | .vmux = 1, | 1018 | .vmux = 1, |
1019 | /* 2: Line-In */ | ||
1020 | .audioroute = 2, | ||
1016 | },{ | 1021 | },{ |
1017 | .type = CX88_VMUX_SVIDEO, | 1022 | .type = CX88_VMUX_SVIDEO, |
1018 | .vmux = 2, | 1023 | .vmux = 2, |
1024 | /* 2: Line-In */ | ||
1025 | .audioroute = 2, | ||
1019 | }}, | 1026 | }}, |
1020 | .mpeg = CX88_MPEG_DVB, | 1027 | .mpeg = CX88_MPEG_DVB, |
1021 | }, | 1028 | }, |
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index 62cea9549404..d9249e5a04c9 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include "cx88.h" | 40 | #include "cx88.h" |
41 | #include <media/v4l2-common.h> | 41 | #include <media/v4l2-common.h> |
42 | #include <media/v4l2-ioctl.h> | 42 | #include <media/v4l2-ioctl.h> |
43 | #include <media/wm8775.h> | ||
44 | 43 | ||
45 | MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); | 44 | MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); |
46 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | 45 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); |
@@ -977,7 +976,6 @@ int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl) | |||
977 | const struct cx88_ctrl *c = NULL; | 976 | const struct cx88_ctrl *c = NULL; |
978 | u32 value,mask; | 977 | u32 value,mask; |
979 | int i; | 978 | int i; |
980 | struct v4l2_control client_ctl; | ||
981 | 979 | ||
982 | for (i = 0; i < CX8800_CTLS; i++) { | 980 | for (i = 0; i < CX8800_CTLS; i++) { |
983 | if (cx8800_ctls[i].v.id == ctl->id) { | 981 | if (cx8800_ctls[i].v.id == ctl->id) { |
@@ -991,27 +989,6 @@ int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl) | |||
991 | ctl->value = c->v.minimum; | 989 | ctl->value = c->v.minimum; |
992 | if (ctl->value > c->v.maximum) | 990 | if (ctl->value > c->v.maximum) |
993 | ctl->value = c->v.maximum; | 991 | ctl->value = c->v.maximum; |
994 | |||
995 | /* Pass changes onto any WM8775 */ | ||
996 | client_ctl.id = ctl->id; | ||
997 | switch (ctl->id) { | ||
998 | case V4L2_CID_AUDIO_MUTE: | ||
999 | client_ctl.value = ctl->value; | ||
1000 | break; | ||
1001 | case V4L2_CID_AUDIO_VOLUME: | ||
1002 | client_ctl.value = (ctl->value) ? | ||
1003 | (0x90 + ctl->value) << 8 : 0; | ||
1004 | break; | ||
1005 | case V4L2_CID_AUDIO_BALANCE: | ||
1006 | client_ctl.value = ctl->value << 9; | ||
1007 | break; | ||
1008 | default: | ||
1009 | client_ctl.id = 0; | ||
1010 | break; | ||
1011 | } | ||
1012 | if (client_ctl.id) | ||
1013 | call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl); | ||
1014 | |||
1015 | mask=c->mask; | 992 | mask=c->mask; |
1016 | switch (ctl->id) { | 993 | switch (ctl->id) { |
1017 | case V4L2_CID_AUDIO_BALANCE: | 994 | case V4L2_CID_AUDIO_BALANCE: |
@@ -1558,9 +1535,7 @@ static int radio_queryctrl (struct file *file, void *priv, | |||
1558 | if (c->id < V4L2_CID_BASE || | 1535 | if (c->id < V4L2_CID_BASE || |
1559 | c->id >= V4L2_CID_LASTP1) | 1536 | c->id >= V4L2_CID_LASTP1) |
1560 | return -EINVAL; | 1537 | return -EINVAL; |
1561 | if (c->id == V4L2_CID_AUDIO_MUTE || | 1538 | if (c->id == V4L2_CID_AUDIO_MUTE) { |
1562 | c->id == V4L2_CID_AUDIO_VOLUME || | ||
1563 | c->id == V4L2_CID_AUDIO_BALANCE) { | ||
1564 | for (i = 0; i < CX8800_CTLS; i++) { | 1539 | for (i = 0; i < CX8800_CTLS; i++) { |
1565 | if (cx8800_ctls[i].v.id == c->id) | 1540 | if (cx8800_ctls[i].v.id == c->id) |
1566 | break; | 1541 | break; |
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index e8c732e7ae4f..c9981e77416a 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
@@ -398,19 +398,17 @@ static inline struct cx88_core *to_core(struct v4l2_device *v4l2_dev) | |||
398 | return container_of(v4l2_dev, struct cx88_core, v4l2_dev); | 398 | return container_of(v4l2_dev, struct cx88_core, v4l2_dev); |
399 | } | 399 | } |
400 | 400 | ||
401 | #define call_hw(core, grpid, o, f, args...) \ | 401 | #define call_all(core, o, f, args...) \ |
402 | do { \ | 402 | do { \ |
403 | if (!core->i2c_rc) { \ | 403 | if (!core->i2c_rc) { \ |
404 | if (core->gate_ctrl) \ | 404 | if (core->gate_ctrl) \ |
405 | core->gate_ctrl(core, 1); \ | 405 | core->gate_ctrl(core, 1); \ |
406 | v4l2_device_call_all(&core->v4l2_dev, grpid, o, f, ##args); \ | 406 | v4l2_device_call_all(&core->v4l2_dev, 0, o, f, ##args); \ |
407 | if (core->gate_ctrl) \ | 407 | if (core->gate_ctrl) \ |
408 | core->gate_ctrl(core, 0); \ | 408 | core->gate_ctrl(core, 0); \ |
409 | } \ | 409 | } \ |
410 | } while (0) | 410 | } while (0) |
411 | 411 | ||
412 | #define call_all(core, o, f, args...) call_hw(core, 0, o, f, ##args) | ||
413 | |||
414 | struct cx8800_dev; | 412 | struct cx8800_dev; |
415 | struct cx8802_dev; | 413 | struct cx8802_dev; |
416 | 414 | ||
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 908e3bc88303..2c3007280032 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c | |||
@@ -2377,7 +2377,7 @@ static const struct v4l2_file_operations radio_fops = { | |||
2377 | .owner = THIS_MODULE, | 2377 | .owner = THIS_MODULE, |
2378 | .open = em28xx_v4l2_open, | 2378 | .open = em28xx_v4l2_open, |
2379 | .release = em28xx_v4l2_close, | 2379 | .release = em28xx_v4l2_close, |
2380 | .ioctl = video_ioctl2, | 2380 | .unlocked_ioctl = video_ioctl2, |
2381 | }; | 2381 | }; |
2382 | 2382 | ||
2383 | static const struct v4l2_ioctl_ops radio_ioctl_ops = { | 2383 | static const struct v4l2_ioctl_ops radio_ioctl_ops = { |
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c index a5cfc76b40b7..bb164099ea2c 100644 --- a/drivers/media/video/et61x251/et61x251_core.c +++ b/drivers/media/video/et61x251/et61x251_core.c | |||
@@ -2530,7 +2530,7 @@ static const struct v4l2_file_operations et61x251_fops = { | |||
2530 | .owner = THIS_MODULE, | 2530 | .owner = THIS_MODULE, |
2531 | .open = et61x251_open, | 2531 | .open = et61x251_open, |
2532 | .release = et61x251_release, | 2532 | .release = et61x251_release, |
2533 | .ioctl = et61x251_ioctl, | 2533 | .unlocked_ioctl = et61x251_ioctl, |
2534 | .read = et61x251_read, | 2534 | .read = et61x251_read, |
2535 | .poll = et61x251_poll, | 2535 | .poll = et61x251_poll, |
2536 | .mmap = et61x251_mmap, | 2536 | .mmap = et61x251_mmap, |
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c index 330dadc00106..e23de57e2c73 100644 --- a/drivers/media/video/gspca/sonixj.c +++ b/drivers/media/video/gspca/sonixj.c | |||
@@ -63,7 +63,10 @@ struct sd { | |||
63 | #define QUALITY_DEF 80 | 63 | #define QUALITY_DEF 80 |
64 | u8 jpegqual; /* webcam quality */ | 64 | u8 jpegqual; /* webcam quality */ |
65 | 65 | ||
66 | u8 reg01; | ||
67 | u8 reg17; | ||
66 | u8 reg18; | 68 | u8 reg18; |
69 | u8 flags; | ||
67 | 70 | ||
68 | s8 ag_cnt; | 71 | s8 ag_cnt; |
69 | #define AG_CNT_START 13 | 72 | #define AG_CNT_START 13 |
@@ -96,6 +99,22 @@ enum sensors { | |||
96 | SENSOR_SP80708, | 99 | SENSOR_SP80708, |
97 | }; | 100 | }; |
98 | 101 | ||
102 | /* device flags */ | ||
103 | #define PDN_INV 1 /* inverse pin S_PWR_DN / sn_xxx tables */ | ||
104 | |||
105 | /* sn9c1xx definitions */ | ||
106 | /* register 0x01 */ | ||
107 | #define S_PWR_DN 0x01 /* sensor power down */ | ||
108 | #define S_PDN_INV 0x02 /* inverse pin S_PWR_DN */ | ||
109 | #define V_TX_EN 0x04 /* video transfer enable */ | ||
110 | #define LED 0x08 /* output to pin LED */ | ||
111 | #define SCL_SEL_OD 0x20 /* open-drain mode */ | ||
112 | #define SYS_SEL_48M 0x40 /* system clock 0: 24MHz, 1: 48MHz */ | ||
113 | /* register 0x17 */ | ||
114 | #define MCK_SIZE_MASK 0x1f /* sensor master clock */ | ||
115 | #define SEN_CLK_EN 0x20 /* enable sensor clock */ | ||
116 | #define DEF_EN 0x80 /* defect pixel by 0: soft, 1: hard */ | ||
117 | |||
99 | /* V4L2 controls supported by the driver */ | 118 | /* V4L2 controls supported by the driver */ |
100 | static void setbrightness(struct gspca_dev *gspca_dev); | 119 | static void setbrightness(struct gspca_dev *gspca_dev); |
101 | static void setcontrast(struct gspca_dev *gspca_dev); | 120 | static void setcontrast(struct gspca_dev *gspca_dev); |
@@ -1755,141 +1774,6 @@ static void po2030n_probe(struct gspca_dev *gspca_dev) | |||
1755 | } | 1774 | } |
1756 | } | 1775 | } |
1757 | 1776 | ||
1758 | static void bridge_init(struct gspca_dev *gspca_dev, | ||
1759 | const u8 *sn9c1xx) | ||
1760 | { | ||
1761 | struct sd *sd = (struct sd *) gspca_dev; | ||
1762 | u8 reg0102[2]; | ||
1763 | const u8 *reg9a; | ||
1764 | static const u8 reg9a_def[] = | ||
1765 | {0x00, 0x40, 0x20, 0x00, 0x00, 0x00}; | ||
1766 | static const u8 reg9a_spec[] = | ||
1767 | {0x00, 0x40, 0x38, 0x30, 0x00, 0x20}; | ||
1768 | static const u8 regd4[] = {0x60, 0x00, 0x00}; | ||
1769 | |||
1770 | /* sensor clock already enabled in sd_init */ | ||
1771 | /* reg_w1(gspca_dev, 0xf1, 0x00); */ | ||
1772 | reg_w1(gspca_dev, 0x01, sn9c1xx[1]); | ||
1773 | |||
1774 | /* configure gpio */ | ||
1775 | reg0102[0] = sn9c1xx[1]; | ||
1776 | reg0102[1] = sn9c1xx[2]; | ||
1777 | if (gspca_dev->audio) | ||
1778 | reg0102[1] |= 0x04; /* keep the audio connection */ | ||
1779 | reg_w(gspca_dev, 0x01, reg0102, 2); | ||
1780 | reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); | ||
1781 | reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); | ||
1782 | switch (sd->sensor) { | ||
1783 | case SENSOR_GC0307: | ||
1784 | case SENSOR_OV7660: | ||
1785 | case SENSOR_PO1030: | ||
1786 | case SENSOR_PO2030N: | ||
1787 | case SENSOR_SOI768: | ||
1788 | case SENSOR_SP80708: | ||
1789 | reg9a = reg9a_spec; | ||
1790 | break; | ||
1791 | default: | ||
1792 | reg9a = reg9a_def; | ||
1793 | break; | ||
1794 | } | ||
1795 | reg_w(gspca_dev, 0x9a, reg9a, 6); | ||
1796 | |||
1797 | reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); | ||
1798 | |||
1799 | reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); | ||
1800 | |||
1801 | switch (sd->sensor) { | ||
1802 | case SENSOR_ADCM1700: | ||
1803 | reg_w1(gspca_dev, 0x01, 0x43); | ||
1804 | reg_w1(gspca_dev, 0x17, 0x62); | ||
1805 | reg_w1(gspca_dev, 0x01, 0x42); | ||
1806 | reg_w1(gspca_dev, 0x01, 0x42); | ||
1807 | break; | ||
1808 | case SENSOR_GC0307: | ||
1809 | msleep(50); | ||
1810 | reg_w1(gspca_dev, 0x01, 0x61); | ||
1811 | reg_w1(gspca_dev, 0x17, 0x22); | ||
1812 | reg_w1(gspca_dev, 0x01, 0x60); | ||
1813 | reg_w1(gspca_dev, 0x01, 0x40); | ||
1814 | msleep(50); | ||
1815 | break; | ||
1816 | case SENSOR_MI0360B: | ||
1817 | reg_w1(gspca_dev, 0x01, 0x61); | ||
1818 | reg_w1(gspca_dev, 0x17, 0x60); | ||
1819 | reg_w1(gspca_dev, 0x01, 0x60); | ||
1820 | reg_w1(gspca_dev, 0x01, 0x40); | ||
1821 | break; | ||
1822 | case SENSOR_MT9V111: | ||
1823 | reg_w1(gspca_dev, 0x01, 0x61); | ||
1824 | reg_w1(gspca_dev, 0x17, 0x61); | ||
1825 | reg_w1(gspca_dev, 0x01, 0x60); | ||
1826 | reg_w1(gspca_dev, 0x01, 0x40); | ||
1827 | break; | ||
1828 | case SENSOR_OM6802: | ||
1829 | msleep(10); | ||
1830 | reg_w1(gspca_dev, 0x02, 0x73); | ||
1831 | reg_w1(gspca_dev, 0x17, 0x60); | ||
1832 | reg_w1(gspca_dev, 0x01, 0x22); | ||
1833 | msleep(100); | ||
1834 | reg_w1(gspca_dev, 0x01, 0x62); | ||
1835 | reg_w1(gspca_dev, 0x17, 0x64); | ||
1836 | reg_w1(gspca_dev, 0x17, 0x64); | ||
1837 | reg_w1(gspca_dev, 0x01, 0x42); | ||
1838 | msleep(10); | ||
1839 | reg_w1(gspca_dev, 0x01, 0x42); | ||
1840 | i2c_w8(gspca_dev, om6802_init0[0]); | ||
1841 | i2c_w8(gspca_dev, om6802_init0[1]); | ||
1842 | msleep(15); | ||
1843 | reg_w1(gspca_dev, 0x02, 0x71); | ||
1844 | msleep(150); | ||
1845 | break; | ||
1846 | case SENSOR_OV7630: | ||
1847 | reg_w1(gspca_dev, 0x01, 0x61); | ||
1848 | reg_w1(gspca_dev, 0x17, 0xe2); | ||
1849 | reg_w1(gspca_dev, 0x01, 0x60); | ||
1850 | reg_w1(gspca_dev, 0x01, 0x40); | ||
1851 | break; | ||
1852 | case SENSOR_OV7648: | ||
1853 | reg_w1(gspca_dev, 0x01, 0x63); | ||
1854 | reg_w1(gspca_dev, 0x17, 0x20); | ||
1855 | reg_w1(gspca_dev, 0x01, 0x62); | ||
1856 | reg_w1(gspca_dev, 0x01, 0x42); | ||
1857 | break; | ||
1858 | case SENSOR_PO1030: | ||
1859 | case SENSOR_SOI768: | ||
1860 | reg_w1(gspca_dev, 0x01, 0x61); | ||
1861 | reg_w1(gspca_dev, 0x17, 0x20); | ||
1862 | reg_w1(gspca_dev, 0x01, 0x60); | ||
1863 | reg_w1(gspca_dev, 0x01, 0x40); | ||
1864 | break; | ||
1865 | case SENSOR_PO2030N: | ||
1866 | case SENSOR_OV7660: | ||
1867 | reg_w1(gspca_dev, 0x01, 0x63); | ||
1868 | reg_w1(gspca_dev, 0x17, 0x20); | ||
1869 | reg_w1(gspca_dev, 0x01, 0x62); | ||
1870 | reg_w1(gspca_dev, 0x01, 0x42); | ||
1871 | break; | ||
1872 | case SENSOR_SP80708: | ||
1873 | reg_w1(gspca_dev, 0x01, 0x63); | ||
1874 | reg_w1(gspca_dev, 0x17, 0x20); | ||
1875 | reg_w1(gspca_dev, 0x01, 0x62); | ||
1876 | reg_w1(gspca_dev, 0x01, 0x42); | ||
1877 | msleep(100); | ||
1878 | reg_w1(gspca_dev, 0x02, 0x62); | ||
1879 | break; | ||
1880 | default: | ||
1881 | /* case SENSOR_HV7131R: */ | ||
1882 | /* case SENSOR_MI0360: */ | ||
1883 | /* case SENSOR_MO4000: */ | ||
1884 | reg_w1(gspca_dev, 0x01, 0x43); | ||
1885 | reg_w1(gspca_dev, 0x17, 0x61); | ||
1886 | reg_w1(gspca_dev, 0x01, 0x42); | ||
1887 | if (sd->sensor == SENSOR_HV7131R) | ||
1888 | hv7131r_probe(gspca_dev); | ||
1889 | break; | ||
1890 | } | ||
1891 | } | ||
1892 | |||
1893 | /* this function is called at probe time */ | 1777 | /* this function is called at probe time */ |
1894 | static int sd_config(struct gspca_dev *gspca_dev, | 1778 | static int sd_config(struct gspca_dev *gspca_dev, |
1895 | const struct usb_device_id *id) | 1779 | const struct usb_device_id *id) |
@@ -1898,7 +1782,8 @@ static int sd_config(struct gspca_dev *gspca_dev, | |||
1898 | struct cam *cam; | 1782 | struct cam *cam; |
1899 | 1783 | ||
1900 | sd->bridge = id->driver_info >> 16; | 1784 | sd->bridge = id->driver_info >> 16; |
1901 | sd->sensor = id->driver_info; | 1785 | sd->sensor = id->driver_info >> 8; |
1786 | sd->flags = id->driver_info; | ||
1902 | 1787 | ||
1903 | cam = &gspca_dev->cam; | 1788 | cam = &gspca_dev->cam; |
1904 | if (sd->sensor == SENSOR_ADCM1700) { | 1789 | if (sd->sensor == SENSOR_ADCM1700) { |
@@ -1929,7 +1814,7 @@ static int sd_init(struct gspca_dev *gspca_dev) | |||
1929 | /* setup a selector by bridge */ | 1814 | /* setup a selector by bridge */ |
1930 | reg_w1(gspca_dev, 0xf1, 0x01); | 1815 | reg_w1(gspca_dev, 0xf1, 0x01); |
1931 | reg_r(gspca_dev, 0x00, 1); | 1816 | reg_r(gspca_dev, 0x00, 1); |
1932 | reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]); | 1817 | reg_w1(gspca_dev, 0xf1, 0x00); |
1933 | reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */ | 1818 | reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */ |
1934 | regF1 = gspca_dev->usb_buf[0]; | 1819 | regF1 = gspca_dev->usb_buf[0]; |
1935 | if (gspca_dev->usb_err < 0) | 1820 | if (gspca_dev->usb_err < 0) |
@@ -2423,10 +2308,17 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2423 | { | 2308 | { |
2424 | struct sd *sd = (struct sd *) gspca_dev; | 2309 | struct sd *sd = (struct sd *) gspca_dev; |
2425 | int i; | 2310 | int i; |
2426 | u8 reg1, reg17; | 2311 | u8 reg01, reg17; |
2312 | u8 reg0102[2]; | ||
2427 | const u8 *sn9c1xx; | 2313 | const u8 *sn9c1xx; |
2428 | const u8 (*init)[8]; | 2314 | const u8 (*init)[8]; |
2315 | const u8 *reg9a; | ||
2429 | int mode; | 2316 | int mode; |
2317 | static const u8 reg9a_def[] = | ||
2318 | {0x00, 0x40, 0x20, 0x00, 0x00, 0x00}; | ||
2319 | static const u8 reg9a_spec[] = | ||
2320 | {0x00, 0x40, 0x38, 0x30, 0x00, 0x20}; | ||
2321 | static const u8 regd4[] = {0x60, 0x00, 0x00}; | ||
2430 | static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; | 2322 | static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f }; |
2431 | static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; | 2323 | static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec }; |
2432 | static const u8 CA_adcm1700[] = | 2324 | static const u8 CA_adcm1700[] = |
@@ -2448,7 +2340,85 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2448 | 2340 | ||
2449 | /* initialize the bridge */ | 2341 | /* initialize the bridge */ |
2450 | sn9c1xx = sn_tb[sd->sensor]; | 2342 | sn9c1xx = sn_tb[sd->sensor]; |
2451 | bridge_init(gspca_dev, sn9c1xx); | 2343 | |
2344 | /* sensor clock already enabled in sd_init */ | ||
2345 | /* reg_w1(gspca_dev, 0xf1, 0x00); */ | ||
2346 | reg01 = sn9c1xx[1]; | ||
2347 | if (sd->flags & PDN_INV) | ||
2348 | reg01 ^= S_PDN_INV; /* power down inverted */ | ||
2349 | reg_w1(gspca_dev, 0x01, reg01); | ||
2350 | |||
2351 | /* configure gpio */ | ||
2352 | reg0102[0] = reg01; | ||
2353 | reg0102[1] = sn9c1xx[2]; | ||
2354 | if (gspca_dev->audio) | ||
2355 | reg0102[1] |= 0x04; /* keep the audio connection */ | ||
2356 | reg_w(gspca_dev, 0x01, reg0102, 2); | ||
2357 | reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2); | ||
2358 | reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); | ||
2359 | switch (sd->sensor) { | ||
2360 | case SENSOR_GC0307: | ||
2361 | case SENSOR_OV7660: | ||
2362 | case SENSOR_PO1030: | ||
2363 | case SENSOR_PO2030N: | ||
2364 | case SENSOR_SOI768: | ||
2365 | case SENSOR_SP80708: | ||
2366 | reg9a = reg9a_spec; | ||
2367 | break; | ||
2368 | default: | ||
2369 | reg9a = reg9a_def; | ||
2370 | break; | ||
2371 | } | ||
2372 | reg_w(gspca_dev, 0x9a, reg9a, 6); | ||
2373 | |||
2374 | reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); | ||
2375 | |||
2376 | reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f); | ||
2377 | |||
2378 | reg17 = sn9c1xx[0x17]; | ||
2379 | switch (sd->sensor) { | ||
2380 | case SENSOR_GC0307: | ||
2381 | msleep(50); /*fixme: is it useful? */ | ||
2382 | break; | ||
2383 | case SENSOR_OM6802: | ||
2384 | msleep(10); | ||
2385 | reg_w1(gspca_dev, 0x02, 0x73); | ||
2386 | reg17 |= SEN_CLK_EN; | ||
2387 | reg_w1(gspca_dev, 0x17, reg17); | ||
2388 | reg_w1(gspca_dev, 0x01, 0x22); | ||
2389 | msleep(100); | ||
2390 | reg01 = SCL_SEL_OD | S_PDN_INV; | ||
2391 | reg17 &= MCK_SIZE_MASK; | ||
2392 | reg17 |= 0x04; /* clock / 4 */ | ||
2393 | break; | ||
2394 | } | ||
2395 | reg01 |= SYS_SEL_48M; | ||
2396 | reg_w1(gspca_dev, 0x01, reg01); | ||
2397 | reg17 |= SEN_CLK_EN; | ||
2398 | reg_w1(gspca_dev, 0x17, reg17); | ||
2399 | reg01 &= ~S_PWR_DN; /* sensor power on */ | ||
2400 | reg_w1(gspca_dev, 0x01, reg01); | ||
2401 | reg01 &= ~SYS_SEL_48M; | ||
2402 | reg_w1(gspca_dev, 0x01, reg01); | ||
2403 | |||
2404 | switch (sd->sensor) { | ||
2405 | case SENSOR_HV7131R: | ||
2406 | hv7131r_probe(gspca_dev); /*fixme: is it useful? */ | ||
2407 | break; | ||
2408 | case SENSOR_OM6802: | ||
2409 | msleep(10); | ||
2410 | reg_w1(gspca_dev, 0x01, reg01); | ||
2411 | i2c_w8(gspca_dev, om6802_init0[0]); | ||
2412 | i2c_w8(gspca_dev, om6802_init0[1]); | ||
2413 | msleep(15); | ||
2414 | reg_w1(gspca_dev, 0x02, 0x71); | ||
2415 | msleep(150); | ||
2416 | break; | ||
2417 | case SENSOR_SP80708: | ||
2418 | msleep(100); | ||
2419 | reg_w1(gspca_dev, 0x02, 0x62); | ||
2420 | break; | ||
2421 | } | ||
2452 | 2422 | ||
2453 | /* initialize the sensor */ | 2423 | /* initialize the sensor */ |
2454 | i2c_w_seq(gspca_dev, sensor_init[sd->sensor]); | 2424 | i2c_w_seq(gspca_dev, sensor_init[sd->sensor]); |
@@ -2476,30 +2446,11 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2476 | } | 2446 | } |
2477 | reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); | 2447 | reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]); |
2478 | switch (sd->sensor) { | 2448 | switch (sd->sensor) { |
2479 | case SENSOR_GC0307: | 2449 | case SENSOR_OM6802: |
2480 | reg17 = 0xa2; | 2450 | /* case SENSOR_OV7648: * fixme: sometimes */ |
2481 | break; | ||
2482 | case SENSOR_MT9V111: | ||
2483 | case SENSOR_MI0360B: | ||
2484 | reg17 = 0xe0; | ||
2485 | break; | ||
2486 | case SENSOR_ADCM1700: | ||
2487 | case SENSOR_OV7630: | ||
2488 | reg17 = 0xe2; | ||
2489 | break; | ||
2490 | case SENSOR_OV7648: | ||
2491 | reg17 = 0x20; | ||
2492 | break; | ||
2493 | case SENSOR_OV7660: | ||
2494 | case SENSOR_SOI768: | ||
2495 | reg17 = 0xa0; | ||
2496 | break; | ||
2497 | case SENSOR_PO1030: | ||
2498 | case SENSOR_PO2030N: | ||
2499 | reg17 = 0xa0; | ||
2500 | break; | 2451 | break; |
2501 | default: | 2452 | default: |
2502 | reg17 = 0x60; | 2453 | reg17 |= DEF_EN; |
2503 | break; | 2454 | break; |
2504 | } | 2455 | } |
2505 | reg_w1(gspca_dev, 0x17, reg17); | 2456 | reg_w1(gspca_dev, 0x17, reg17); |
@@ -2546,95 +2497,67 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2546 | 2497 | ||
2547 | init = NULL; | 2498 | init = NULL; |
2548 | mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; | 2499 | mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv; |
2549 | if (mode) | 2500 | reg01 |= SYS_SEL_48M | V_TX_EN; |
2550 | reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */ | 2501 | reg17 &= ~MCK_SIZE_MASK; |
2551 | else | 2502 | reg17 |= 0x02; /* clock / 2 */ |
2552 | reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */ | ||
2553 | reg17 = 0x61; /* 0x:20: enable sensor clock */ | ||
2554 | switch (sd->sensor) { | 2503 | switch (sd->sensor) { |
2555 | case SENSOR_ADCM1700: | 2504 | case SENSOR_ADCM1700: |
2556 | init = adcm1700_sensor_param1; | 2505 | init = adcm1700_sensor_param1; |
2557 | reg1 = 0x46; | ||
2558 | reg17 = 0xe2; | ||
2559 | break; | 2506 | break; |
2560 | case SENSOR_GC0307: | 2507 | case SENSOR_GC0307: |
2561 | init = gc0307_sensor_param1; | 2508 | init = gc0307_sensor_param1; |
2562 | reg17 = 0xa2; | 2509 | break; |
2563 | reg1 = 0x44; | 2510 | case SENSOR_HV7131R: |
2511 | case SENSOR_MI0360: | ||
2512 | if (mode) | ||
2513 | reg01 |= SYS_SEL_48M; /* 320x240: clk 48Mhz */ | ||
2514 | else | ||
2515 | reg01 &= ~SYS_SEL_48M; /* 640x480: clk 24Mhz */ | ||
2516 | reg17 &= ~MCK_SIZE_MASK; | ||
2517 | reg17 |= 0x01; /* clock / 1 */ | ||
2564 | break; | 2518 | break; |
2565 | case SENSOR_MI0360B: | 2519 | case SENSOR_MI0360B: |
2566 | init = mi0360b_sensor_param1; | 2520 | init = mi0360b_sensor_param1; |
2567 | reg1 &= ~0x02; /* don't inverse pin S_PWR_DN */ | ||
2568 | reg17 = 0xe2; | ||
2569 | break; | 2521 | break; |
2570 | case SENSOR_MO4000: | 2522 | case SENSOR_MO4000: |
2571 | if (mode) { | 2523 | if (mode) { /* if 320x240 */ |
2572 | /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */ | 2524 | reg01 &= ~SYS_SEL_48M; /* clk 24Mz */ |
2573 | reg1 = 0x06; /* clk 24Mz */ | 2525 | reg17 &= ~MCK_SIZE_MASK; |
2574 | } else { | 2526 | reg17 |= 0x01; /* clock / 1 */ |
2575 | reg17 = 0x22; /* 640 MCKSIZE */ | ||
2576 | /* reg1 = 0x06; * 640 clk 24Mz (done) */ | ||
2577 | } | 2527 | } |
2578 | break; | 2528 | break; |
2579 | case SENSOR_MT9V111: | 2529 | case SENSOR_MT9V111: |
2580 | init = mt9v111_sensor_param1; | 2530 | init = mt9v111_sensor_param1; |
2581 | if (mode) { | ||
2582 | reg1 = 0x04; /* 320 clk 48Mhz */ | ||
2583 | } else { | ||
2584 | /* reg1 = 0x06; * 640 clk 24Mz (done) */ | ||
2585 | reg17 = 0xc2; | ||
2586 | } | ||
2587 | break; | 2531 | break; |
2588 | case SENSOR_OM6802: | 2532 | case SENSOR_OM6802: |
2589 | init = om6802_sensor_param1; | 2533 | init = om6802_sensor_param1; |
2590 | reg17 = 0x64; /* 640 MCKSIZE */ | 2534 | if (!mode) { /* if 640x480 */ |
2535 | reg17 &= ~MCK_SIZE_MASK; | ||
2536 | reg17 |= 0x01; /* clock / 4 */ | ||
2537 | } | ||
2591 | break; | 2538 | break; |
2592 | case SENSOR_OV7630: | 2539 | case SENSOR_OV7630: |
2593 | init = ov7630_sensor_param1; | 2540 | init = ov7630_sensor_param1; |
2594 | reg17 = 0xe2; | ||
2595 | reg1 = 0x44; | ||
2596 | break; | 2541 | break; |
2597 | case SENSOR_OV7648: | 2542 | case SENSOR_OV7648: |
2598 | init = ov7648_sensor_param1; | 2543 | init = ov7648_sensor_param1; |
2599 | reg17 = 0x21; | 2544 | reg17 &= ~MCK_SIZE_MASK; |
2600 | /* reg1 = 0x42; * 42 - 46? */ | 2545 | reg17 |= 0x01; /* clock / 1 */ |
2601 | break; | 2546 | break; |
2602 | case SENSOR_OV7660: | 2547 | case SENSOR_OV7660: |
2603 | init = ov7660_sensor_param1; | 2548 | init = ov7660_sensor_param1; |
2604 | if (sd->bridge == BRIDGE_SN9C120) { | ||
2605 | if (mode) { /* 320x240 - 160x120 */ | ||
2606 | reg17 = 0xa2; | ||
2607 | reg1 = 0x44; /* 48 Mhz, video trf eneble */ | ||
2608 | } | ||
2609 | } else { | ||
2610 | reg17 = 0x22; | ||
2611 | reg1 = 0x06; /* 24 Mhz, video trf eneble | ||
2612 | * inverse power down */ | ||
2613 | } | ||
2614 | break; | 2549 | break; |
2615 | case SENSOR_PO1030: | 2550 | case SENSOR_PO1030: |
2616 | init = po1030_sensor_param1; | 2551 | init = po1030_sensor_param1; |
2617 | reg17 = 0xa2; | ||
2618 | reg1 = 0x44; | ||
2619 | break; | 2552 | break; |
2620 | case SENSOR_PO2030N: | 2553 | case SENSOR_PO2030N: |
2621 | init = po2030n_sensor_param1; | 2554 | init = po2030n_sensor_param1; |
2622 | reg1 = 0x46; | ||
2623 | reg17 = 0xa2; | ||
2624 | break; | 2555 | break; |
2625 | case SENSOR_SOI768: | 2556 | case SENSOR_SOI768: |
2626 | init = soi768_sensor_param1; | 2557 | init = soi768_sensor_param1; |
2627 | reg1 = 0x44; | ||
2628 | reg17 = 0xa2; | ||
2629 | break; | 2558 | break; |
2630 | case SENSOR_SP80708: | 2559 | case SENSOR_SP80708: |
2631 | init = sp80708_sensor_param1; | 2560 | init = sp80708_sensor_param1; |
2632 | if (mode) { | ||
2633 | /*?? reg1 = 0x04; * 320 clk 48Mhz */ | ||
2634 | } else { | ||
2635 | reg1 = 0x46; /* 640 clk 48Mz */ | ||
2636 | reg17 = 0xa2; | ||
2637 | } | ||
2638 | break; | 2561 | break; |
2639 | } | 2562 | } |
2640 | 2563 | ||
@@ -2684,7 +2607,9 @@ static int sd_start(struct gspca_dev *gspca_dev) | |||
2684 | setjpegqual(gspca_dev); | 2607 | setjpegqual(gspca_dev); |
2685 | 2608 | ||
2686 | reg_w1(gspca_dev, 0x17, reg17); | 2609 | reg_w1(gspca_dev, 0x17, reg17); |
2687 | reg_w1(gspca_dev, 0x01, reg1); | 2610 | reg_w1(gspca_dev, 0x01, reg01); |
2611 | sd->reg01 = reg01; | ||
2612 | sd->reg17 = reg17; | ||
2688 | 2613 | ||
2689 | sethvflip(gspca_dev); | 2614 | sethvflip(gspca_dev); |
2690 | setbrightness(gspca_dev); | 2615 | setbrightness(gspca_dev); |
@@ -2706,41 +2631,64 @@ static void sd_stopN(struct gspca_dev *gspca_dev) | |||
2706 | { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 }; | 2631 | { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 }; |
2707 | static const u8 stopsoi768[] = | 2632 | static const u8 stopsoi768[] = |
2708 | { 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 }; | 2633 | { 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 }; |
2709 | u8 data; | 2634 | u8 reg01; |
2710 | const u8 *sn9c1xx; | 2635 | u8 reg17; |
2711 | 2636 | ||
2712 | data = 0x0b; | 2637 | reg01 = sd->reg01; |
2638 | reg17 = sd->reg17 & ~SEN_CLK_EN; | ||
2713 | switch (sd->sensor) { | 2639 | switch (sd->sensor) { |
2640 | case SENSOR_ADCM1700: | ||
2714 | case SENSOR_GC0307: | 2641 | case SENSOR_GC0307: |
2715 | data = 0x29; | 2642 | case SENSOR_PO2030N: |
2643 | case SENSOR_SP80708: | ||
2644 | reg01 |= LED; | ||
2645 | reg_w1(gspca_dev, 0x01, reg01); | ||
2646 | reg01 &= ~(LED | V_TX_EN); | ||
2647 | reg_w1(gspca_dev, 0x01, reg01); | ||
2648 | /* reg_w1(gspca_dev, 0x02, 0x??); * LED off ? */ | ||
2716 | break; | 2649 | break; |
2717 | case SENSOR_HV7131R: | 2650 | case SENSOR_HV7131R: |
2651 | reg01 &= ~V_TX_EN; | ||
2652 | reg_w1(gspca_dev, 0x01, reg01); | ||
2718 | i2c_w8(gspca_dev, stophv7131); | 2653 | i2c_w8(gspca_dev, stophv7131); |
2719 | data = 0x2b; | ||
2720 | break; | 2654 | break; |
2721 | case SENSOR_MI0360: | 2655 | case SENSOR_MI0360: |
2722 | case SENSOR_MI0360B: | 2656 | case SENSOR_MI0360B: |
2657 | reg01 &= ~V_TX_EN; | ||
2658 | reg_w1(gspca_dev, 0x01, reg01); | ||
2659 | /* reg_w1(gspca_dev, 0x02, 0x40); * LED off ? */ | ||
2723 | i2c_w8(gspca_dev, stopmi0360); | 2660 | i2c_w8(gspca_dev, stopmi0360); |
2724 | data = 0x29; | ||
2725 | break; | 2661 | break; |
2726 | case SENSOR_OV7648: | ||
2727 | i2c_w8(gspca_dev, stopov7648); | ||
2728 | /* fall thru */ | ||
2729 | case SENSOR_MT9V111: | 2662 | case SENSOR_MT9V111: |
2730 | case SENSOR_OV7630: | 2663 | case SENSOR_OM6802: |
2731 | case SENSOR_PO1030: | 2664 | case SENSOR_PO1030: |
2732 | data = 0x29; | 2665 | reg01 &= ~V_TX_EN; |
2666 | reg_w1(gspca_dev, 0x01, reg01); | ||
2667 | break; | ||
2668 | case SENSOR_OV7630: | ||
2669 | case SENSOR_OV7648: | ||
2670 | reg01 &= ~V_TX_EN; | ||
2671 | reg_w1(gspca_dev, 0x01, reg01); | ||
2672 | i2c_w8(gspca_dev, stopov7648); | ||
2673 | break; | ||
2674 | case SENSOR_OV7660: | ||
2675 | reg01 &= ~V_TX_EN; | ||
2676 | reg_w1(gspca_dev, 0x01, reg01); | ||
2733 | break; | 2677 | break; |
2734 | case SENSOR_SOI768: | 2678 | case SENSOR_SOI768: |
2735 | i2c_w8(gspca_dev, stopsoi768); | 2679 | i2c_w8(gspca_dev, stopsoi768); |
2736 | data = 0x29; | ||
2737 | break; | 2680 | break; |
2738 | } | 2681 | } |
2739 | sn9c1xx = sn_tb[sd->sensor]; | 2682 | |
2740 | reg_w1(gspca_dev, 0x01, sn9c1xx[1]); | 2683 | reg01 |= SCL_SEL_OD; |
2741 | reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]); | 2684 | reg_w1(gspca_dev, 0x01, reg01); |
2742 | reg_w1(gspca_dev, 0x01, sn9c1xx[1]); | 2685 | reg01 |= S_PWR_DN; /* sensor power down */ |
2743 | reg_w1(gspca_dev, 0x01, data); | 2686 | reg_w1(gspca_dev, 0x01, reg01); |
2687 | reg_w1(gspca_dev, 0x17, reg17); | ||
2688 | reg01 &= ~SYS_SEL_48M; /* clock 24MHz */ | ||
2689 | reg_w1(gspca_dev, 0x01, reg01); | ||
2690 | reg01 |= LED; | ||
2691 | reg_w1(gspca_dev, 0x01, reg01); | ||
2744 | /* Don't disable sensor clock as that disables the button on the cam */ | 2692 | /* Don't disable sensor clock as that disables the button on the cam */ |
2745 | /* reg_w1(gspca_dev, 0xf1, 0x01); */ | 2693 | /* reg_w1(gspca_dev, 0xf1, 0x01); */ |
2746 | } | 2694 | } |
@@ -2954,14 +2902,18 @@ static const struct sd_desc sd_desc = { | |||
2954 | /* -- module initialisation -- */ | 2902 | /* -- module initialisation -- */ |
2955 | #define BS(bridge, sensor) \ | 2903 | #define BS(bridge, sensor) \ |
2956 | .driver_info = (BRIDGE_ ## bridge << 16) \ | 2904 | .driver_info = (BRIDGE_ ## bridge << 16) \ |
2957 | | SENSOR_ ## sensor | 2905 | | (SENSOR_ ## sensor << 8) |
2906 | #define BSF(bridge, sensor, flags) \ | ||
2907 | .driver_info = (BRIDGE_ ## bridge << 16) \ | ||
2908 | | (SENSOR_ ## sensor << 8) \ | ||
2909 | | (flags) | ||
2958 | static const __devinitdata struct usb_device_id device_table[] = { | 2910 | static const __devinitdata struct usb_device_id device_table[] = { |
2959 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE | 2911 | #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE |
2960 | {USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)}, | 2912 | {USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)}, |
2961 | {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)}, | 2913 | {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)}, |
2962 | #endif | 2914 | #endif |
2963 | {USB_DEVICE(0x045e, 0x00f5), BS(SN9C105, OV7660)}, | 2915 | {USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, PDN_INV)}, |
2964 | {USB_DEVICE(0x045e, 0x00f7), BS(SN9C105, OV7660)}, | 2916 | {USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, PDN_INV)}, |
2965 | {USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)}, | 2917 | {USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)}, |
2966 | {USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)}, | 2918 | {USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)}, |
2967 | {USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)}, | 2919 | {USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)}, |
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c index 2be23bccd3c8..48d2c2419c13 100644 --- a/drivers/media/video/meye.c +++ b/drivers/media/video/meye.c | |||
@@ -1659,7 +1659,7 @@ static const struct v4l2_file_operations meye_fops = { | |||
1659 | .open = meye_open, | 1659 | .open = meye_open, |
1660 | .release = meye_release, | 1660 | .release = meye_release, |
1661 | .mmap = meye_mmap, | 1661 | .mmap = meye_mmap, |
1662 | .ioctl = video_ioctl2, | 1662 | .unlocked_ioctl = video_ioctl2, |
1663 | .poll = meye_poll, | 1663 | .poll = meye_poll, |
1664 | }; | 1664 | }; |
1665 | 1665 | ||
@@ -1831,12 +1831,6 @@ static int __devinit meye_probe(struct pci_dev *pcidev, | |||
1831 | msleep(1); | 1831 | msleep(1); |
1832 | mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK); | 1832 | mchip_set(MCHIP_MM_INTA, MCHIP_MM_INTA_HIC_1_MASK); |
1833 | 1833 | ||
1834 | if (video_register_device(meye.vdev, VFL_TYPE_GRABBER, | ||
1835 | video_nr) < 0) { | ||
1836 | v4l2_err(v4l2_dev, "video_register_device failed\n"); | ||
1837 | goto outvideoreg; | ||
1838 | } | ||
1839 | |||
1840 | mutex_init(&meye.lock); | 1834 | mutex_init(&meye.lock); |
1841 | init_waitqueue_head(&meye.proc_list); | 1835 | init_waitqueue_head(&meye.proc_list); |
1842 | meye.brightness = 32 << 10; | 1836 | meye.brightness = 32 << 10; |
@@ -1858,6 +1852,12 @@ static int __devinit meye_probe(struct pci_dev *pcidev, | |||
1858 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE, 0); | 1852 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAPICTURE, 0); |
1859 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC, 48); | 1853 | sony_pic_camera_command(SONY_PIC_COMMAND_SETCAMERAAGC, 48); |
1860 | 1854 | ||
1855 | if (video_register_device(meye.vdev, VFL_TYPE_GRABBER, | ||
1856 | video_nr) < 0) { | ||
1857 | v4l2_err(v4l2_dev, "video_register_device failed\n"); | ||
1858 | goto outvideoreg; | ||
1859 | } | ||
1860 | |||
1861 | v4l2_info(v4l2_dev, "Motion Eye Camera Driver v%s.\n", | 1861 | v4l2_info(v4l2_dev, "Motion Eye Camera Driver v%s.\n", |
1862 | MEYE_DRIVER_VERSION); | 1862 | MEYE_DRIVER_VERSION); |
1863 | v4l2_info(v4l2_dev, "mchip KL5A72002 rev. %d, base %lx, irq %d\n", | 1863 | v4l2_info(v4l2_dev, "mchip KL5A72002 rev. %d, base %lx, irq %d\n", |
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index 072bd2d1cfad..13565cba237d 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c | |||
@@ -807,8 +807,6 @@ static int mx2_camera_set_bus_param(struct soc_camera_device *icd, | |||
807 | 807 | ||
808 | if (common_flags & SOCAM_PCLK_SAMPLE_RISING) | 808 | if (common_flags & SOCAM_PCLK_SAMPLE_RISING) |
809 | csicr1 |= CSICR1_REDGE; | 809 | csicr1 |= CSICR1_REDGE; |
810 | if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) | ||
811 | csicr1 |= CSICR1_INV_PCLK; | ||
812 | if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH) | 810 | if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH) |
813 | csicr1 |= CSICR1_SOF_POL; | 811 | csicr1 |= CSICR1_SOF_POL; |
814 | if (common_flags & SOCAM_HSYNC_ACTIVE_HIGH) | 812 | if (common_flags & SOCAM_HSYNC_ACTIVE_HIGH) |
diff --git a/drivers/media/video/pms.c b/drivers/media/video/pms.c index 7129b50757db..7551907f8c28 100644 --- a/drivers/media/video/pms.c +++ b/drivers/media/video/pms.c | |||
@@ -932,7 +932,7 @@ static ssize_t pms_read(struct file *file, char __user *buf, | |||
932 | 932 | ||
933 | static const struct v4l2_file_operations pms_fops = { | 933 | static const struct v4l2_file_operations pms_fops = { |
934 | .owner = THIS_MODULE, | 934 | .owner = THIS_MODULE, |
935 | .ioctl = video_ioctl2, | 935 | .unlocked_ioctl = video_ioctl2, |
936 | .read = pms_read, | 936 | .read = pms_read, |
937 | }; | 937 | }; |
938 | 938 | ||
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index 1b93207c89e8..2f500809f53d 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c | |||
@@ -522,6 +522,7 @@ static int fimc_cap_streamon(struct file *file, void *priv, | |||
522 | INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q); | 522 | INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q); |
523 | fimc->vid_cap.active_buf_cnt = 0; | 523 | fimc->vid_cap.active_buf_cnt = 0; |
524 | fimc->vid_cap.frame_count = 0; | 524 | fimc->vid_cap.frame_count = 0; |
525 | fimc->vid_cap.buf_index = fimc_hw_get_frame_index(fimc); | ||
525 | 526 | ||
526 | set_bit(ST_CAPT_PEND, &fimc->state); | 527 | set_bit(ST_CAPT_PEND, &fimc->state); |
527 | ret = videobuf_streamon(&fimc->vid_cap.vbq); | 528 | ret = videobuf_streamon(&fimc->vid_cap.vbq); |
@@ -652,6 +653,50 @@ static int fimc_cap_s_ctrl(struct file *file, void *priv, | |||
652 | return ret; | 653 | return ret; |
653 | } | 654 | } |
654 | 655 | ||
656 | static int fimc_cap_cropcap(struct file *file, void *fh, | ||
657 | struct v4l2_cropcap *cr) | ||
658 | { | ||
659 | struct fimc_frame *f; | ||
660 | struct fimc_ctx *ctx = fh; | ||
661 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
662 | |||
663 | if (cr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | ||
664 | return -EINVAL; | ||
665 | |||
666 | if (mutex_lock_interruptible(&fimc->lock)) | ||
667 | return -ERESTARTSYS; | ||
668 | |||
669 | f = &ctx->s_frame; | ||
670 | cr->bounds.left = 0; | ||
671 | cr->bounds.top = 0; | ||
672 | cr->bounds.width = f->o_width; | ||
673 | cr->bounds.height = f->o_height; | ||
674 | cr->defrect = cr->bounds; | ||
675 | |||
676 | mutex_unlock(&fimc->lock); | ||
677 | return 0; | ||
678 | } | ||
679 | |||
680 | static int fimc_cap_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) | ||
681 | { | ||
682 | struct fimc_frame *f; | ||
683 | struct fimc_ctx *ctx = file->private_data; | ||
684 | struct fimc_dev *fimc = ctx->fimc_dev; | ||
685 | |||
686 | |||
687 | if (mutex_lock_interruptible(&fimc->lock)) | ||
688 | return -ERESTARTSYS; | ||
689 | |||
690 | f = &ctx->s_frame; | ||
691 | cr->c.left = f->offs_h; | ||
692 | cr->c.top = f->offs_v; | ||
693 | cr->c.width = f->width; | ||
694 | cr->c.height = f->height; | ||
695 | |||
696 | mutex_unlock(&fimc->lock); | ||
697 | return 0; | ||
698 | } | ||
699 | |||
655 | static int fimc_cap_s_crop(struct file *file, void *fh, | 700 | static int fimc_cap_s_crop(struct file *file, void *fh, |
656 | struct v4l2_crop *cr) | 701 | struct v4l2_crop *cr) |
657 | { | 702 | { |
@@ -716,9 +761,9 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = { | |||
716 | .vidioc_g_ctrl = fimc_vidioc_g_ctrl, | 761 | .vidioc_g_ctrl = fimc_vidioc_g_ctrl, |
717 | .vidioc_s_ctrl = fimc_cap_s_ctrl, | 762 | .vidioc_s_ctrl = fimc_cap_s_ctrl, |
718 | 763 | ||
719 | .vidioc_g_crop = fimc_vidioc_g_crop, | 764 | .vidioc_g_crop = fimc_cap_g_crop, |
720 | .vidioc_s_crop = fimc_cap_s_crop, | 765 | .vidioc_s_crop = fimc_cap_s_crop, |
721 | .vidioc_cropcap = fimc_vidioc_cropcap, | 766 | .vidioc_cropcap = fimc_cap_cropcap, |
722 | 767 | ||
723 | .vidioc_enum_input = fimc_cap_enum_input, | 768 | .vidioc_enum_input = fimc_cap_enum_input, |
724 | .vidioc_s_input = fimc_cap_s_input, | 769 | .vidioc_s_input = fimc_cap_s_input, |
@@ -785,7 +830,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc) | |||
785 | videobuf_queue_dma_contig_init(&vid_cap->vbq, &fimc_qops, | 830 | videobuf_queue_dma_contig_init(&vid_cap->vbq, &fimc_qops, |
786 | vid_cap->v4l2_dev.dev, &fimc->irqlock, | 831 | vid_cap->v4l2_dev.dev, &fimc->irqlock, |
787 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, | 832 | V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, |
788 | sizeof(struct fimc_vid_buffer), (void *)ctx); | 833 | sizeof(struct fimc_vid_buffer), (void *)ctx, NULL); |
789 | 834 | ||
790 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); | 835 | ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); |
791 | if (ret) { | 836 | if (ret) { |
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index 2e7c547894b6..bb99f2d805d3 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c | |||
@@ -50,8 +50,8 @@ static struct fimc_fmt fimc_formats[] = { | |||
50 | .planes_cnt = 1, | 50 | .planes_cnt = 1, |
51 | .flags = FMT_FLAGS_M2M, | 51 | .flags = FMT_FLAGS_M2M, |
52 | }, { | 52 | }, { |
53 | .name = "XRGB-8-8-8-8, 24 bpp", | 53 | .name = "XRGB-8-8-8-8, 32 bpp", |
54 | .fourcc = V4L2_PIX_FMT_RGB24, | 54 | .fourcc = V4L2_PIX_FMT_RGB32, |
55 | .depth = 32, | 55 | .depth = 32, |
56 | .color = S5P_FIMC_RGB888, | 56 | .color = S5P_FIMC_RGB888, |
57 | .buff_cnt = 1, | 57 | .buff_cnt = 1, |
@@ -983,6 +983,7 @@ int fimc_vidioc_queryctrl(struct file *file, void *priv, | |||
983 | { | 983 | { |
984 | struct fimc_ctx *ctx = priv; | 984 | struct fimc_ctx *ctx = priv; |
985 | struct v4l2_queryctrl *c; | 985 | struct v4l2_queryctrl *c; |
986 | int ret = -EINVAL; | ||
986 | 987 | ||
987 | c = get_ctrl(qc->id); | 988 | c = get_ctrl(qc->id); |
988 | if (c) { | 989 | if (c) { |
@@ -990,10 +991,14 @@ int fimc_vidioc_queryctrl(struct file *file, void *priv, | |||
990 | return 0; | 991 | return 0; |
991 | } | 992 | } |
992 | 993 | ||
993 | if (ctx->state & FIMC_CTX_CAP) | 994 | if (ctx->state & FIMC_CTX_CAP) { |
994 | return v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd, | 995 | if (mutex_lock_interruptible(&ctx->fimc_dev->lock)) |
996 | return -ERESTARTSYS; | ||
997 | ret = v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd, | ||
995 | core, queryctrl, qc); | 998 | core, queryctrl, qc); |
996 | return -EINVAL; | 999 | mutex_unlock(&ctx->fimc_dev->lock); |
1000 | } | ||
1001 | return ret; | ||
997 | } | 1002 | } |
998 | 1003 | ||
999 | int fimc_vidioc_g_ctrl(struct file *file, void *priv, | 1004 | int fimc_vidioc_g_ctrl(struct file *file, void *priv, |
@@ -1115,7 +1120,7 @@ static int fimc_m2m_s_ctrl(struct file *file, void *priv, | |||
1115 | return 0; | 1120 | return 0; |
1116 | } | 1121 | } |
1117 | 1122 | ||
1118 | int fimc_vidioc_cropcap(struct file *file, void *fh, | 1123 | static int fimc_m2m_cropcap(struct file *file, void *fh, |
1119 | struct v4l2_cropcap *cr) | 1124 | struct v4l2_cropcap *cr) |
1120 | { | 1125 | { |
1121 | struct fimc_frame *frame; | 1126 | struct fimc_frame *frame; |
@@ -1139,7 +1144,7 @@ int fimc_vidioc_cropcap(struct file *file, void *fh, | |||
1139 | return 0; | 1144 | return 0; |
1140 | } | 1145 | } |
1141 | 1146 | ||
1142 | int fimc_vidioc_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) | 1147 | static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr) |
1143 | { | 1148 | { |
1144 | struct fimc_frame *frame; | 1149 | struct fimc_frame *frame; |
1145 | struct fimc_ctx *ctx = file->private_data; | 1150 | struct fimc_ctx *ctx = file->private_data; |
@@ -1167,22 +1172,22 @@ int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr) | |||
1167 | struct fimc_frame *f; | 1172 | struct fimc_frame *f; |
1168 | u32 min_size, halign; | 1173 | u32 min_size, halign; |
1169 | 1174 | ||
1170 | f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ? | ||
1171 | &ctx->s_frame : &ctx->d_frame; | ||
1172 | |||
1173 | if (cr->c.top < 0 || cr->c.left < 0) { | 1175 | if (cr->c.top < 0 || cr->c.left < 0) { |
1174 | v4l2_err(&fimc->m2m.v4l2_dev, | 1176 | v4l2_err(&fimc->m2m.v4l2_dev, |
1175 | "doesn't support negative values for top & left\n"); | 1177 | "doesn't support negative values for top & left\n"); |
1176 | return -EINVAL; | 1178 | return -EINVAL; |
1177 | } | 1179 | } |
1178 | 1180 | ||
1179 | f = ctx_get_frame(ctx, cr->type); | 1181 | if (cr->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
1180 | if (IS_ERR(f)) | 1182 | f = (ctx->state & FIMC_CTX_CAP) ? &ctx->s_frame : &ctx->d_frame; |
1181 | return PTR_ERR(f); | 1183 | else if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && |
1184 | ctx->state & FIMC_CTX_M2M) | ||
1185 | f = &ctx->s_frame; | ||
1186 | else | ||
1187 | return -EINVAL; | ||
1182 | 1188 | ||
1183 | min_size = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) | 1189 | min_size = (f == &ctx->s_frame) ? |
1184 | ? fimc->variant->min_inp_pixsize | 1190 | fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize; |
1185 | : fimc->variant->min_out_pixsize; | ||
1186 | 1191 | ||
1187 | if (ctx->state & FIMC_CTX_M2M) { | 1192 | if (ctx->state & FIMC_CTX_M2M) { |
1188 | if (fimc->id == 1 && fimc->variant->pix_hoff) | 1193 | if (fimc->id == 1 && fimc->variant->pix_hoff) |
@@ -1233,6 +1238,9 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) | |||
1233 | f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ? | 1238 | f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ? |
1234 | &ctx->s_frame : &ctx->d_frame; | 1239 | &ctx->s_frame : &ctx->d_frame; |
1235 | 1240 | ||
1241 | if (mutex_lock_interruptible(&fimc->lock)) | ||
1242 | return -ERESTARTSYS; | ||
1243 | |||
1236 | spin_lock_irqsave(&ctx->slock, flags); | 1244 | spin_lock_irqsave(&ctx->slock, flags); |
1237 | if (~ctx->state & (FIMC_SRC_FMT | FIMC_DST_FMT)) { | 1245 | if (~ctx->state & (FIMC_SRC_FMT | FIMC_DST_FMT)) { |
1238 | /* Check to see if scaling ratio is within supported range */ | 1246 | /* Check to see if scaling ratio is within supported range */ |
@@ -1241,9 +1249,9 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) | |||
1241 | else | 1249 | else |
1242 | ret = fimc_check_scaler_ratio(&cr->c, &ctx->s_frame); | 1250 | ret = fimc_check_scaler_ratio(&cr->c, &ctx->s_frame); |
1243 | if (ret) { | 1251 | if (ret) { |
1244 | spin_unlock_irqrestore(&ctx->slock, flags); | ||
1245 | v4l2_err(&fimc->m2m.v4l2_dev, "Out of scaler range"); | 1252 | v4l2_err(&fimc->m2m.v4l2_dev, "Out of scaler range"); |
1246 | return -EINVAL; | 1253 | ret = -EINVAL; |
1254 | goto scr_unlock; | ||
1247 | } | 1255 | } |
1248 | } | 1256 | } |
1249 | ctx->state |= FIMC_PARAMS; | 1257 | ctx->state |= FIMC_PARAMS; |
@@ -1253,7 +1261,9 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) | |||
1253 | f->width = cr->c.width; | 1261 | f->width = cr->c.width; |
1254 | f->height = cr->c.height; | 1262 | f->height = cr->c.height; |
1255 | 1263 | ||
1264 | scr_unlock: | ||
1256 | spin_unlock_irqrestore(&ctx->slock, flags); | 1265 | spin_unlock_irqrestore(&ctx->slock, flags); |
1266 | mutex_unlock(&fimc->lock); | ||
1257 | return 0; | 1267 | return 0; |
1258 | } | 1268 | } |
1259 | 1269 | ||
@@ -1285,9 +1295,9 @@ static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = { | |||
1285 | .vidioc_g_ctrl = fimc_vidioc_g_ctrl, | 1295 | .vidioc_g_ctrl = fimc_vidioc_g_ctrl, |
1286 | .vidioc_s_ctrl = fimc_m2m_s_ctrl, | 1296 | .vidioc_s_ctrl = fimc_m2m_s_ctrl, |
1287 | 1297 | ||
1288 | .vidioc_g_crop = fimc_vidioc_g_crop, | 1298 | .vidioc_g_crop = fimc_m2m_g_crop, |
1289 | .vidioc_s_crop = fimc_m2m_s_crop, | 1299 | .vidioc_s_crop = fimc_m2m_s_crop, |
1290 | .vidioc_cropcap = fimc_vidioc_cropcap | 1300 | .vidioc_cropcap = fimc_m2m_cropcap |
1291 | 1301 | ||
1292 | }; | 1302 | }; |
1293 | 1303 | ||
@@ -1396,7 +1406,7 @@ static const struct v4l2_file_operations fimc_m2m_fops = { | |||
1396 | .open = fimc_m2m_open, | 1406 | .open = fimc_m2m_open, |
1397 | .release = fimc_m2m_release, | 1407 | .release = fimc_m2m_release, |
1398 | .poll = fimc_m2m_poll, | 1408 | .poll = fimc_m2m_poll, |
1399 | .ioctl = video_ioctl2, | 1409 | .unlocked_ioctl = video_ioctl2, |
1400 | .mmap = fimc_m2m_mmap, | 1410 | .mmap = fimc_m2m_mmap, |
1401 | }; | 1411 | }; |
1402 | 1412 | ||
@@ -1736,6 +1746,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = { | |||
1736 | .pix_hoff = 1, | 1746 | .pix_hoff = 1, |
1737 | .has_inp_rot = 1, | 1747 | .has_inp_rot = 1, |
1738 | .has_out_rot = 1, | 1748 | .has_out_rot = 1, |
1749 | .has_cistatus2 = 1, | ||
1739 | .min_inp_pixsize = 16, | 1750 | .min_inp_pixsize = 16, |
1740 | .min_out_pixsize = 16, | 1751 | .min_out_pixsize = 16, |
1741 | .hor_offs_align = 1, | 1752 | .hor_offs_align = 1, |
@@ -1745,6 +1756,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = { | |||
1745 | 1756 | ||
1746 | static struct samsung_fimc_variant fimc2_variant_s5pv310 = { | 1757 | static struct samsung_fimc_variant fimc2_variant_s5pv310 = { |
1747 | .pix_hoff = 1, | 1758 | .pix_hoff = 1, |
1759 | .has_cistatus2 = 1, | ||
1748 | .min_inp_pixsize = 16, | 1760 | .min_inp_pixsize = 16, |
1749 | .min_out_pixsize = 16, | 1761 | .min_out_pixsize = 16, |
1750 | .hor_offs_align = 1, | 1762 | .hor_offs_align = 1, |
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h index 3e1078516560..4f047d35f8ad 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.h +++ b/drivers/media/video/s5p-fimc/fimc-core.h | |||
@@ -13,13 +13,15 @@ | |||
13 | 13 | ||
14 | /*#define DEBUG*/ | 14 | /*#define DEBUG*/ |
15 | 15 | ||
16 | #include <linux/sched.h> | ||
16 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | #include <linux/videodev2.h> | ||
17 | #include <media/videobuf-core.h> | 19 | #include <media/videobuf-core.h> |
18 | #include <media/v4l2-device.h> | 20 | #include <media/v4l2-device.h> |
19 | #include <media/v4l2-mem2mem.h> | 21 | #include <media/v4l2-mem2mem.h> |
20 | #include <media/v4l2-mediabus.h> | 22 | #include <media/v4l2-mediabus.h> |
21 | #include <media/s3c_fimc.h> | 23 | #include <media/s3c_fimc.h> |
22 | #include <linux/videodev2.h> | 24 | |
23 | #include "regs-fimc.h" | 25 | #include "regs-fimc.h" |
24 | 26 | ||
25 | #define err(fmt, args...) \ | 27 | #define err(fmt, args...) \ |
@@ -369,6 +371,7 @@ struct fimc_pix_limit { | |||
369 | * @pix_hoff: indicate whether horizontal offset is in pixels or in bytes | 371 | * @pix_hoff: indicate whether horizontal offset is in pixels or in bytes |
370 | * @has_inp_rot: set if has input rotator | 372 | * @has_inp_rot: set if has input rotator |
371 | * @has_out_rot: set if has output rotator | 373 | * @has_out_rot: set if has output rotator |
374 | * @has_cistatus2: 1 if CISTATUS2 register is present in this IP revision | ||
372 | * @pix_limit: pixel size constraints for the scaler | 375 | * @pix_limit: pixel size constraints for the scaler |
373 | * @min_inp_pixsize: minimum input pixel size | 376 | * @min_inp_pixsize: minimum input pixel size |
374 | * @min_out_pixsize: minimum output pixel size | 377 | * @min_out_pixsize: minimum output pixel size |
@@ -379,6 +382,7 @@ struct samsung_fimc_variant { | |||
379 | unsigned int pix_hoff:1; | 382 | unsigned int pix_hoff:1; |
380 | unsigned int has_inp_rot:1; | 383 | unsigned int has_inp_rot:1; |
381 | unsigned int has_out_rot:1; | 384 | unsigned int has_out_rot:1; |
385 | unsigned int has_cistatus2:1; | ||
382 | struct fimc_pix_limit *pix_limit; | 386 | struct fimc_pix_limit *pix_limit; |
383 | u16 min_inp_pixsize; | 387 | u16 min_inp_pixsize; |
384 | u16 min_out_pixsize; | 388 | u16 min_out_pixsize; |
@@ -554,11 +558,19 @@ static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx, | |||
554 | return frame; | 558 | return frame; |
555 | } | 559 | } |
556 | 560 | ||
561 | /* Return an index to the buffer actually being written. */ | ||
557 | static inline u32 fimc_hw_get_frame_index(struct fimc_dev *dev) | 562 | static inline u32 fimc_hw_get_frame_index(struct fimc_dev *dev) |
558 | { | 563 | { |
559 | u32 reg = readl(dev->regs + S5P_CISTATUS); | 564 | u32 reg; |
560 | return (reg & S5P_CISTATUS_FRAMECNT_MASK) >> | 565 | |
561 | S5P_CISTATUS_FRAMECNT_SHIFT; | 566 | if (dev->variant->has_cistatus2) { |
567 | reg = readl(dev->regs + S5P_CISTATUS2) & 0x3F; | ||
568 | return reg > 0 ? --reg : reg; | ||
569 | } else { | ||
570 | reg = readl(dev->regs + S5P_CISTATUS); | ||
571 | return (reg & S5P_CISTATUS_FRAMECNT_MASK) >> | ||
572 | S5P_CISTATUS_FRAMECNT_SHIFT; | ||
573 | } | ||
562 | } | 574 | } |
563 | 575 | ||
564 | /* -----------------------------------------------------*/ | 576 | /* -----------------------------------------------------*/ |
@@ -594,10 +606,6 @@ int fimc_vidioc_g_fmt(struct file *file, void *priv, | |||
594 | struct v4l2_format *f); | 606 | struct v4l2_format *f); |
595 | int fimc_vidioc_try_fmt(struct file *file, void *priv, | 607 | int fimc_vidioc_try_fmt(struct file *file, void *priv, |
596 | struct v4l2_format *f); | 608 | struct v4l2_format *f); |
597 | int fimc_vidioc_g_crop(struct file *file, void *fh, | ||
598 | struct v4l2_crop *cr); | ||
599 | int fimc_vidioc_cropcap(struct file *file, void *fh, | ||
600 | struct v4l2_cropcap *cr); | ||
601 | int fimc_vidioc_queryctrl(struct file *file, void *priv, | 609 | int fimc_vidioc_queryctrl(struct file *file, void *priv, |
602 | struct v4l2_queryctrl *qc); | 610 | struct v4l2_queryctrl *qc); |
603 | int fimc_vidioc_g_ctrl(struct file *file, void *priv, | 611 | int fimc_vidioc_g_ctrl(struct file *file, void *priv, |
diff --git a/drivers/media/video/s5p-fimc/regs-fimc.h b/drivers/media/video/s5p-fimc/regs-fimc.h index a57daedb5b5c..57e33f84fcfa 100644 --- a/drivers/media/video/s5p-fimc/regs-fimc.h +++ b/drivers/media/video/s5p-fimc/regs-fimc.h | |||
@@ -165,6 +165,9 @@ | |||
165 | #define S5P_CISTATUS_VVALID_A (1 << 15) | 165 | #define S5P_CISTATUS_VVALID_A (1 << 15) |
166 | #define S5P_CISTATUS_VVALID_B (1 << 14) | 166 | #define S5P_CISTATUS_VVALID_B (1 << 14) |
167 | 167 | ||
168 | /* Indexes to the last and the currently processed buffer. */ | ||
169 | #define S5P_CISTATUS2 0x68 | ||
170 | |||
168 | /* Image capture control */ | 171 | /* Image capture control */ |
169 | #define S5P_CIIMGCPT 0xc0 | 172 | #define S5P_CIIMGCPT 0xc0 |
170 | #define S5P_CIIMGCPT_IMGCPTEN (1 << 31) | 173 | #define S5P_CIIMGCPT_IMGCPTEN (1 << 31) |
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c index 5c209afb0ac8..2486520582f2 100644 --- a/drivers/media/video/sh_mobile_ceu_camera.c +++ b/drivers/media/video/sh_mobile_ceu_camera.c | |||
@@ -1980,7 +1980,7 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev) | |||
1980 | * we complete the completion. | 1980 | * we complete the completion. |
1981 | */ | 1981 | */ |
1982 | 1982 | ||
1983 | if (!csi2->driver || !csi2->driver->owner) { | 1983 | if (!csi2->driver) { |
1984 | complete(&wait.completion); | 1984 | complete(&wait.completion); |
1985 | /* Either too late, or probing failed */ | 1985 | /* Either too late, or probing failed */ |
1986 | bus_unregister_notifier(&platform_bus_type, &wait.notifier); | 1986 | bus_unregister_notifier(&platform_bus_type, &wait.notifier); |
diff --git a/drivers/media/video/sh_vou.c b/drivers/media/video/sh_vou.c index 4e5a8cf76ded..07cf0c6c7c1f 100644 --- a/drivers/media/video/sh_vou.c +++ b/drivers/media/video/sh_vou.c | |||
@@ -75,6 +75,7 @@ struct sh_vou_device { | |||
75 | int pix_idx; | 75 | int pix_idx; |
76 | struct videobuf_buffer *active; | 76 | struct videobuf_buffer *active; |
77 | enum sh_vou_status status; | 77 | enum sh_vou_status status; |
78 | struct mutex fop_lock; | ||
78 | }; | 79 | }; |
79 | 80 | ||
80 | struct sh_vou_file { | 81 | struct sh_vou_file { |
@@ -235,7 +236,7 @@ static void free_buffer(struct videobuf_queue *vq, struct videobuf_buffer *vb) | |||
235 | vb->state = VIDEOBUF_NEEDS_INIT; | 236 | vb->state = VIDEOBUF_NEEDS_INIT; |
236 | } | 237 | } |
237 | 238 | ||
238 | /* Locking: caller holds vq->vb_lock mutex */ | 239 | /* Locking: caller holds fop_lock mutex */ |
239 | static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count, | 240 | static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count, |
240 | unsigned int *size) | 241 | unsigned int *size) |
241 | { | 242 | { |
@@ -257,7 +258,7 @@ static int sh_vou_buf_setup(struct videobuf_queue *vq, unsigned int *count, | |||
257 | return 0; | 258 | return 0; |
258 | } | 259 | } |
259 | 260 | ||
260 | /* Locking: caller holds vq->vb_lock mutex */ | 261 | /* Locking: caller holds fop_lock mutex */ |
261 | static int sh_vou_buf_prepare(struct videobuf_queue *vq, | 262 | static int sh_vou_buf_prepare(struct videobuf_queue *vq, |
262 | struct videobuf_buffer *vb, | 263 | struct videobuf_buffer *vb, |
263 | enum v4l2_field field) | 264 | enum v4l2_field field) |
@@ -306,7 +307,7 @@ static int sh_vou_buf_prepare(struct videobuf_queue *vq, | |||
306 | return 0; | 307 | return 0; |
307 | } | 308 | } |
308 | 309 | ||
309 | /* Locking: caller holds vq->vb_lock mutex and vq->irqlock spinlock */ | 310 | /* Locking: caller holds fop_lock mutex and vq->irqlock spinlock */ |
310 | static void sh_vou_buf_queue(struct videobuf_queue *vq, | 311 | static void sh_vou_buf_queue(struct videobuf_queue *vq, |
311 | struct videobuf_buffer *vb) | 312 | struct videobuf_buffer *vb) |
312 | { | 313 | { |
@@ -1190,7 +1191,7 @@ static int sh_vou_open(struct file *file) | |||
1190 | V4L2_BUF_TYPE_VIDEO_OUTPUT, | 1191 | V4L2_BUF_TYPE_VIDEO_OUTPUT, |
1191 | V4L2_FIELD_NONE, | 1192 | V4L2_FIELD_NONE, |
1192 | sizeof(struct videobuf_buffer), vdev, | 1193 | sizeof(struct videobuf_buffer), vdev, |
1193 | NULL); | 1194 | &vou_dev->fop_lock); |
1194 | 1195 | ||
1195 | return 0; | 1196 | return 0; |
1196 | } | 1197 | } |
@@ -1292,7 +1293,7 @@ static const struct v4l2_file_operations sh_vou_fops = { | |||
1292 | .owner = THIS_MODULE, | 1293 | .owner = THIS_MODULE, |
1293 | .open = sh_vou_open, | 1294 | .open = sh_vou_open, |
1294 | .release = sh_vou_release, | 1295 | .release = sh_vou_release, |
1295 | .ioctl = video_ioctl2, | 1296 | .unlocked_ioctl = video_ioctl2, |
1296 | .mmap = sh_vou_mmap, | 1297 | .mmap = sh_vou_mmap, |
1297 | .poll = sh_vou_poll, | 1298 | .poll = sh_vou_poll, |
1298 | }; | 1299 | }; |
@@ -1331,6 +1332,7 @@ static int __devinit sh_vou_probe(struct platform_device *pdev) | |||
1331 | 1332 | ||
1332 | INIT_LIST_HEAD(&vou_dev->queue); | 1333 | INIT_LIST_HEAD(&vou_dev->queue); |
1333 | spin_lock_init(&vou_dev->lock); | 1334 | spin_lock_init(&vou_dev->lock); |
1335 | mutex_init(&vou_dev->fop_lock); | ||
1334 | atomic_set(&vou_dev->use_count, 0); | 1336 | atomic_set(&vou_dev->use_count, 0); |
1335 | vou_dev->pdata = vou_pdata; | 1337 | vou_dev->pdata = vou_pdata; |
1336 | vou_dev->status = SH_VOU_IDLE; | 1338 | vou_dev->status = SH_VOU_IDLE; |
@@ -1388,6 +1390,7 @@ static int __devinit sh_vou_probe(struct platform_device *pdev) | |||
1388 | vdev->tvnorms |= V4L2_STD_PAL; | 1390 | vdev->tvnorms |= V4L2_STD_PAL; |
1389 | vdev->v4l2_dev = &vou_dev->v4l2_dev; | 1391 | vdev->v4l2_dev = &vou_dev->v4l2_dev; |
1390 | vdev->release = video_device_release; | 1392 | vdev->release = video_device_release; |
1393 | vdev->lock = &vou_dev->fop_lock; | ||
1391 | 1394 | ||
1392 | vou_dev->vdev = vdev; | 1395 | vou_dev->vdev = vdev; |
1393 | video_set_drvdata(vdev, vou_dev); | 1396 | video_set_drvdata(vdev, vou_dev); |
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c index 28e19daadec9..f49fbfb7dc13 100644 --- a/drivers/media/video/sn9c102/sn9c102_core.c +++ b/drivers/media/video/sn9c102/sn9c102_core.c | |||
@@ -3238,7 +3238,7 @@ static const struct v4l2_file_operations sn9c102_fops = { | |||
3238 | .owner = THIS_MODULE, | 3238 | .owner = THIS_MODULE, |
3239 | .open = sn9c102_open, | 3239 | .open = sn9c102_open, |
3240 | .release = sn9c102_release, | 3240 | .release = sn9c102_release, |
3241 | .ioctl = sn9c102_ioctl, | 3241 | .unlocked_ioctl = sn9c102_ioctl, |
3242 | .read = sn9c102_read, | 3242 | .read = sn9c102_read, |
3243 | .poll = sn9c102_poll, | 3243 | .poll = sn9c102_poll, |
3244 | .mmap = sn9c102_mmap, | 3244 | .mmap = sn9c102_mmap, |
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index 335120c2021b..052bd6dfa5a7 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c | |||
@@ -405,13 +405,13 @@ static int soc_camera_open(struct file *file) | |||
405 | ret = soc_camera_set_fmt(icd, &f); | 405 | ret = soc_camera_set_fmt(icd, &f); |
406 | if (ret < 0) | 406 | if (ret < 0) |
407 | goto esfmt; | 407 | goto esfmt; |
408 | |||
409 | ici->ops->init_videobuf(&icd->vb_vidq, icd); | ||
408 | } | 410 | } |
409 | 411 | ||
410 | file->private_data = icd; | 412 | file->private_data = icd; |
411 | dev_dbg(&icd->dev, "camera device open\n"); | 413 | dev_dbg(&icd->dev, "camera device open\n"); |
412 | 414 | ||
413 | ici->ops->init_videobuf(&icd->vb_vidq, icd); | ||
414 | |||
415 | mutex_unlock(&icd->video_lock); | 415 | mutex_unlock(&icd->video_lock); |
416 | 416 | ||
417 | return 0; | 417 | return 0; |
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c index f169f7736677..59f8a9ad3796 100644 --- a/drivers/media/video/uvc/uvc_ctrl.c +++ b/drivers/media/video/uvc/uvc_ctrl.c | |||
@@ -785,7 +785,7 @@ static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id, | |||
785 | } | 785 | } |
786 | } | 786 | } |
787 | 787 | ||
788 | struct uvc_control *uvc_find_control(struct uvc_video_chain *chain, | 788 | static struct uvc_control *uvc_find_control(struct uvc_video_chain *chain, |
789 | __u32 v4l2_id, struct uvc_control_mapping **mapping) | 789 | __u32 v4l2_id, struct uvc_control_mapping **mapping) |
790 | { | 790 | { |
791 | struct uvc_control *ctrl = NULL; | 791 | struct uvc_control *ctrl = NULL; |
@@ -944,6 +944,52 @@ done: | |||
944 | return ret; | 944 | return ret; |
945 | } | 945 | } |
946 | 946 | ||
947 | /* | ||
948 | * Mapping V4L2 controls to UVC controls can be straighforward if done well. | ||
949 | * Most of the UVC controls exist in V4L2, and can be mapped directly. Some | ||
950 | * must be grouped (for instance the Red Balance, Blue Balance and Do White | ||
951 | * Balance V4L2 controls use the White Balance Component UVC control) or | ||
952 | * otherwise translated. The approach we take here is to use a translation | ||
953 | * table for the controls that can be mapped directly, and handle the others | ||
954 | * manually. | ||
955 | */ | ||
956 | int uvc_query_v4l2_menu(struct uvc_video_chain *chain, | ||
957 | struct v4l2_querymenu *query_menu) | ||
958 | { | ||
959 | struct uvc_menu_info *menu_info; | ||
960 | struct uvc_control_mapping *mapping; | ||
961 | struct uvc_control *ctrl; | ||
962 | u32 index = query_menu->index; | ||
963 | u32 id = query_menu->id; | ||
964 | int ret; | ||
965 | |||
966 | memset(query_menu, 0, sizeof(*query_menu)); | ||
967 | query_menu->id = id; | ||
968 | query_menu->index = index; | ||
969 | |||
970 | ret = mutex_lock_interruptible(&chain->ctrl_mutex); | ||
971 | if (ret < 0) | ||
972 | return -ERESTARTSYS; | ||
973 | |||
974 | ctrl = uvc_find_control(chain, query_menu->id, &mapping); | ||
975 | if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) { | ||
976 | ret = -EINVAL; | ||
977 | goto done; | ||
978 | } | ||
979 | |||
980 | if (query_menu->index >= mapping->menu_count) { | ||
981 | ret = -EINVAL; | ||
982 | goto done; | ||
983 | } | ||
984 | |||
985 | menu_info = &mapping->menu_info[query_menu->index]; | ||
986 | strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name); | ||
987 | |||
988 | done: | ||
989 | mutex_unlock(&chain->ctrl_mutex); | ||
990 | return ret; | ||
991 | } | ||
992 | |||
947 | 993 | ||
948 | /* -------------------------------------------------------------------------- | 994 | /* -------------------------------------------------------------------------- |
949 | * Control transactions | 995 | * Control transactions |
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index ed6d5449741c..f14581bd707f 100644 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/uvc/uvc_queue.c | |||
@@ -90,6 +90,39 @@ void uvc_queue_init(struct uvc_video_queue *queue, enum v4l2_buf_type type, | |||
90 | } | 90 | } |
91 | 91 | ||
92 | /* | 92 | /* |
93 | * Free the video buffers. | ||
94 | * | ||
95 | * This function must be called with the queue lock held. | ||
96 | */ | ||
97 | static int __uvc_free_buffers(struct uvc_video_queue *queue) | ||
98 | { | ||
99 | unsigned int i; | ||
100 | |||
101 | for (i = 0; i < queue->count; ++i) { | ||
102 | if (queue->buffer[i].vma_use_count != 0) | ||
103 | return -EBUSY; | ||
104 | } | ||
105 | |||
106 | if (queue->count) { | ||
107 | vfree(queue->mem); | ||
108 | queue->count = 0; | ||
109 | } | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | int uvc_free_buffers(struct uvc_video_queue *queue) | ||
115 | { | ||
116 | int ret; | ||
117 | |||
118 | mutex_lock(&queue->mutex); | ||
119 | ret = __uvc_free_buffers(queue); | ||
120 | mutex_unlock(&queue->mutex); | ||
121 | |||
122 | return ret; | ||
123 | } | ||
124 | |||
125 | /* | ||
93 | * Allocate the video buffers. | 126 | * Allocate the video buffers. |
94 | * | 127 | * |
95 | * Pages are reserved to make sure they will not be swapped, as they will be | 128 | * Pages are reserved to make sure they will not be swapped, as they will be |
@@ -110,7 +143,7 @@ int uvc_alloc_buffers(struct uvc_video_queue *queue, unsigned int nbuffers, | |||
110 | 143 | ||
111 | mutex_lock(&queue->mutex); | 144 | mutex_lock(&queue->mutex); |
112 | 145 | ||
113 | if ((ret = uvc_free_buffers(queue)) < 0) | 146 | if ((ret = __uvc_free_buffers(queue)) < 0) |
114 | goto done; | 147 | goto done; |
115 | 148 | ||
116 | /* Bail out if no buffers should be allocated. */ | 149 | /* Bail out if no buffers should be allocated. */ |
@@ -152,28 +185,6 @@ done: | |||
152 | } | 185 | } |
153 | 186 | ||
154 | /* | 187 | /* |
155 | * Free the video buffers. | ||
156 | * | ||
157 | * This function must be called with the queue lock held. | ||
158 | */ | ||
159 | int uvc_free_buffers(struct uvc_video_queue *queue) | ||
160 | { | ||
161 | unsigned int i; | ||
162 | |||
163 | for (i = 0; i < queue->count; ++i) { | ||
164 | if (queue->buffer[i].vma_use_count != 0) | ||
165 | return -EBUSY; | ||
166 | } | ||
167 | |||
168 | if (queue->count) { | ||
169 | vfree(queue->mem); | ||
170 | queue->count = 0; | ||
171 | } | ||
172 | |||
173 | return 0; | ||
174 | } | ||
175 | |||
176 | /* | ||
177 | * Check if buffers have been allocated. | 188 | * Check if buffers have been allocated. |
178 | */ | 189 | */ |
179 | int uvc_queue_allocated(struct uvc_video_queue *queue) | 190 | int uvc_queue_allocated(struct uvc_video_queue *queue) |
@@ -369,6 +380,82 @@ done: | |||
369 | } | 380 | } |
370 | 381 | ||
371 | /* | 382 | /* |
383 | * VMA operations. | ||
384 | */ | ||
385 | static void uvc_vm_open(struct vm_area_struct *vma) | ||
386 | { | ||
387 | struct uvc_buffer *buffer = vma->vm_private_data; | ||
388 | buffer->vma_use_count++; | ||
389 | } | ||
390 | |||
391 | static void uvc_vm_close(struct vm_area_struct *vma) | ||
392 | { | ||
393 | struct uvc_buffer *buffer = vma->vm_private_data; | ||
394 | buffer->vma_use_count--; | ||
395 | } | ||
396 | |||
397 | static const struct vm_operations_struct uvc_vm_ops = { | ||
398 | .open = uvc_vm_open, | ||
399 | .close = uvc_vm_close, | ||
400 | }; | ||
401 | |||
402 | /* | ||
403 | * Memory-map a video buffer. | ||
404 | * | ||
405 | * This function implements video buffers memory mapping and is intended to be | ||
406 | * used by the device mmap handler. | ||
407 | */ | ||
408 | int uvc_queue_mmap(struct uvc_video_queue *queue, struct vm_area_struct *vma) | ||
409 | { | ||
410 | struct uvc_buffer *uninitialized_var(buffer); | ||
411 | struct page *page; | ||
412 | unsigned long addr, start, size; | ||
413 | unsigned int i; | ||
414 | int ret = 0; | ||
415 | |||
416 | start = vma->vm_start; | ||
417 | size = vma->vm_end - vma->vm_start; | ||
418 | |||
419 | mutex_lock(&queue->mutex); | ||
420 | |||
421 | for (i = 0; i < queue->count; ++i) { | ||
422 | buffer = &queue->buffer[i]; | ||
423 | if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff) | ||
424 | break; | ||
425 | } | ||
426 | |||
427 | if (i == queue->count || size != queue->buf_size) { | ||
428 | ret = -EINVAL; | ||
429 | goto done; | ||
430 | } | ||
431 | |||
432 | /* | ||
433 | * VM_IO marks the area as being an mmaped region for I/O to a | ||
434 | * device. It also prevents the region from being core dumped. | ||
435 | */ | ||
436 | vma->vm_flags |= VM_IO; | ||
437 | |||
438 | addr = (unsigned long)queue->mem + buffer->buf.m.offset; | ||
439 | while (size > 0) { | ||
440 | page = vmalloc_to_page((void *)addr); | ||
441 | if ((ret = vm_insert_page(vma, start, page)) < 0) | ||
442 | goto done; | ||
443 | |||
444 | start += PAGE_SIZE; | ||
445 | addr += PAGE_SIZE; | ||
446 | size -= PAGE_SIZE; | ||
447 | } | ||
448 | |||
449 | vma->vm_ops = &uvc_vm_ops; | ||
450 | vma->vm_private_data = buffer; | ||
451 | uvc_vm_open(vma); | ||
452 | |||
453 | done: | ||
454 | mutex_unlock(&queue->mutex); | ||
455 | return ret; | ||
456 | } | ||
457 | |||
458 | /* | ||
372 | * Poll the video queue. | 459 | * Poll the video queue. |
373 | * | 460 | * |
374 | * This function implements video queue polling and is intended to be used by | 461 | * This function implements video queue polling and is intended to be used by |
diff --git a/drivers/media/video/uvc/uvc_v4l2.c b/drivers/media/video/uvc/uvc_v4l2.c index 6d15de9b5204..8cf61e8a634f 100644 --- a/drivers/media/video/uvc/uvc_v4l2.c +++ b/drivers/media/video/uvc/uvc_v4l2.c | |||
@@ -101,40 +101,6 @@ done: | |||
101 | */ | 101 | */ |
102 | 102 | ||
103 | /* | 103 | /* |
104 | * Mapping V4L2 controls to UVC controls can be straighforward if done well. | ||
105 | * Most of the UVC controls exist in V4L2, and can be mapped directly. Some | ||
106 | * must be grouped (for instance the Red Balance, Blue Balance and Do White | ||
107 | * Balance V4L2 controls use the White Balance Component UVC control) or | ||
108 | * otherwise translated. The approach we take here is to use a translation | ||
109 | * table for the controls that can be mapped directly, and handle the others | ||
110 | * manually. | ||
111 | */ | ||
112 | static int uvc_v4l2_query_menu(struct uvc_video_chain *chain, | ||
113 | struct v4l2_querymenu *query_menu) | ||
114 | { | ||
115 | struct uvc_menu_info *menu_info; | ||
116 | struct uvc_control_mapping *mapping; | ||
117 | struct uvc_control *ctrl; | ||
118 | u32 index = query_menu->index; | ||
119 | u32 id = query_menu->id; | ||
120 | |||
121 | ctrl = uvc_find_control(chain, query_menu->id, &mapping); | ||
122 | if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) | ||
123 | return -EINVAL; | ||
124 | |||
125 | if (query_menu->index >= mapping->menu_count) | ||
126 | return -EINVAL; | ||
127 | |||
128 | memset(query_menu, 0, sizeof(*query_menu)); | ||
129 | query_menu->id = id; | ||
130 | query_menu->index = index; | ||
131 | |||
132 | menu_info = &mapping->menu_info[query_menu->index]; | ||
133 | strlcpy(query_menu->name, menu_info->name, sizeof query_menu->name); | ||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | /* | ||
138 | * Find the frame interval closest to the requested frame interval for the | 104 | * Find the frame interval closest to the requested frame interval for the |
139 | * given frame format and size. This should be done by the device as part of | 105 | * given frame format and size. This should be done by the device as part of |
140 | * the Video Probe and Commit negotiation, but some hardware don't implement | 106 | * the Video Probe and Commit negotiation, but some hardware don't implement |
@@ -260,12 +226,14 @@ static int uvc_v4l2_try_format(struct uvc_streaming *stream, | |||
260 | * developers test their webcams with the Linux driver as well as with | 226 | * developers test their webcams with the Linux driver as well as with |
261 | * the Windows driver). | 227 | * the Windows driver). |
262 | */ | 228 | */ |
229 | mutex_lock(&stream->mutex); | ||
263 | if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS) | 230 | if (stream->dev->quirks & UVC_QUIRK_PROBE_EXTRAFIELDS) |
264 | probe->dwMaxVideoFrameSize = | 231 | probe->dwMaxVideoFrameSize = |
265 | stream->ctrl.dwMaxVideoFrameSize; | 232 | stream->ctrl.dwMaxVideoFrameSize; |
266 | 233 | ||
267 | /* Probe the device. */ | 234 | /* Probe the device. */ |
268 | ret = uvc_probe_video(stream, probe); | 235 | ret = uvc_probe_video(stream, probe); |
236 | mutex_unlock(&stream->mutex); | ||
269 | if (ret < 0) | 237 | if (ret < 0) |
270 | goto done; | 238 | goto done; |
271 | 239 | ||
@@ -289,14 +257,21 @@ done: | |||
289 | static int uvc_v4l2_get_format(struct uvc_streaming *stream, | 257 | static int uvc_v4l2_get_format(struct uvc_streaming *stream, |
290 | struct v4l2_format *fmt) | 258 | struct v4l2_format *fmt) |
291 | { | 259 | { |
292 | struct uvc_format *format = stream->cur_format; | 260 | struct uvc_format *format; |
293 | struct uvc_frame *frame = stream->cur_frame; | 261 | struct uvc_frame *frame; |
262 | int ret = 0; | ||
294 | 263 | ||
295 | if (fmt->type != stream->type) | 264 | if (fmt->type != stream->type) |
296 | return -EINVAL; | 265 | return -EINVAL; |
297 | 266 | ||
298 | if (format == NULL || frame == NULL) | 267 | mutex_lock(&stream->mutex); |
299 | return -EINVAL; | 268 | format = stream->cur_format; |
269 | frame = stream->cur_frame; | ||
270 | |||
271 | if (format == NULL || frame == NULL) { | ||
272 | ret = -EINVAL; | ||
273 | goto done; | ||
274 | } | ||
300 | 275 | ||
301 | fmt->fmt.pix.pixelformat = format->fcc; | 276 | fmt->fmt.pix.pixelformat = format->fcc; |
302 | fmt->fmt.pix.width = frame->wWidth; | 277 | fmt->fmt.pix.width = frame->wWidth; |
@@ -307,7 +282,9 @@ static int uvc_v4l2_get_format(struct uvc_streaming *stream, | |||
307 | fmt->fmt.pix.colorspace = format->colorspace; | 282 | fmt->fmt.pix.colorspace = format->colorspace; |
308 | fmt->fmt.pix.priv = 0; | 283 | fmt->fmt.pix.priv = 0; |
309 | 284 | ||
310 | return 0; | 285 | done: |
286 | mutex_unlock(&stream->mutex); | ||
287 | return ret; | ||
311 | } | 288 | } |
312 | 289 | ||
313 | static int uvc_v4l2_set_format(struct uvc_streaming *stream, | 290 | static int uvc_v4l2_set_format(struct uvc_streaming *stream, |
@@ -321,18 +298,24 @@ static int uvc_v4l2_set_format(struct uvc_streaming *stream, | |||
321 | if (fmt->type != stream->type) | 298 | if (fmt->type != stream->type) |
322 | return -EINVAL; | 299 | return -EINVAL; |
323 | 300 | ||
324 | if (uvc_queue_allocated(&stream->queue)) | ||
325 | return -EBUSY; | ||
326 | |||
327 | ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame); | 301 | ret = uvc_v4l2_try_format(stream, fmt, &probe, &format, &frame); |
328 | if (ret < 0) | 302 | if (ret < 0) |
329 | return ret; | 303 | return ret; |
330 | 304 | ||
305 | mutex_lock(&stream->mutex); | ||
306 | |||
307 | if (uvc_queue_allocated(&stream->queue)) { | ||
308 | ret = -EBUSY; | ||
309 | goto done; | ||
310 | } | ||
311 | |||
331 | memcpy(&stream->ctrl, &probe, sizeof probe); | 312 | memcpy(&stream->ctrl, &probe, sizeof probe); |
332 | stream->cur_format = format; | 313 | stream->cur_format = format; |
333 | stream->cur_frame = frame; | 314 | stream->cur_frame = frame; |
334 | 315 | ||
335 | return 0; | 316 | done: |
317 | mutex_unlock(&stream->mutex); | ||
318 | return ret; | ||
336 | } | 319 | } |
337 | 320 | ||
338 | static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, | 321 | static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, |
@@ -343,7 +326,10 @@ static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, | |||
343 | if (parm->type != stream->type) | 326 | if (parm->type != stream->type) |
344 | return -EINVAL; | 327 | return -EINVAL; |
345 | 328 | ||
329 | mutex_lock(&stream->mutex); | ||
346 | numerator = stream->ctrl.dwFrameInterval; | 330 | numerator = stream->ctrl.dwFrameInterval; |
331 | mutex_unlock(&stream->mutex); | ||
332 | |||
347 | denominator = 10000000; | 333 | denominator = 10000000; |
348 | uvc_simplify_fraction(&numerator, &denominator, 8, 333); | 334 | uvc_simplify_fraction(&numerator, &denominator, 8, 333); |
349 | 335 | ||
@@ -370,7 +356,6 @@ static int uvc_v4l2_get_streamparm(struct uvc_streaming *stream, | |||
370 | static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, | 356 | static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, |
371 | struct v4l2_streamparm *parm) | 357 | struct v4l2_streamparm *parm) |
372 | { | 358 | { |
373 | struct uvc_frame *frame = stream->cur_frame; | ||
374 | struct uvc_streaming_control probe; | 359 | struct uvc_streaming_control probe; |
375 | struct v4l2_fract timeperframe; | 360 | struct v4l2_fract timeperframe; |
376 | uint32_t interval; | 361 | uint32_t interval; |
@@ -379,28 +364,36 @@ static int uvc_v4l2_set_streamparm(struct uvc_streaming *stream, | |||
379 | if (parm->type != stream->type) | 364 | if (parm->type != stream->type) |
380 | return -EINVAL; | 365 | return -EINVAL; |
381 | 366 | ||
382 | if (uvc_queue_streaming(&stream->queue)) | ||
383 | return -EBUSY; | ||
384 | |||
385 | if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) | 367 | if (parm->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) |
386 | timeperframe = parm->parm.capture.timeperframe; | 368 | timeperframe = parm->parm.capture.timeperframe; |
387 | else | 369 | else |
388 | timeperframe = parm->parm.output.timeperframe; | 370 | timeperframe = parm->parm.output.timeperframe; |
389 | 371 | ||
390 | memcpy(&probe, &stream->ctrl, sizeof probe); | ||
391 | interval = uvc_fraction_to_interval(timeperframe.numerator, | 372 | interval = uvc_fraction_to_interval(timeperframe.numerator, |
392 | timeperframe.denominator); | 373 | timeperframe.denominator); |
393 | |||
394 | uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n", | 374 | uvc_trace(UVC_TRACE_FORMAT, "Setting frame interval to %u/%u (%u).\n", |
395 | timeperframe.numerator, timeperframe.denominator, interval); | 375 | timeperframe.numerator, timeperframe.denominator, interval); |
396 | probe.dwFrameInterval = uvc_try_frame_interval(frame, interval); | 376 | |
377 | mutex_lock(&stream->mutex); | ||
378 | |||
379 | if (uvc_queue_streaming(&stream->queue)) { | ||
380 | mutex_unlock(&stream->mutex); | ||
381 | return -EBUSY; | ||
382 | } | ||
383 | |||
384 | memcpy(&probe, &stream->ctrl, sizeof probe); | ||
385 | probe.dwFrameInterval = | ||
386 | uvc_try_frame_interval(stream->cur_frame, interval); | ||
397 | 387 | ||
398 | /* Probe the device with the new settings. */ | 388 | /* Probe the device with the new settings. */ |
399 | ret = uvc_probe_video(stream, &probe); | 389 | ret = uvc_probe_video(stream, &probe); |
400 | if (ret < 0) | 390 | if (ret < 0) { |
391 | mutex_unlock(&stream->mutex); | ||
401 | return ret; | 392 | return ret; |
393 | } | ||
402 | 394 | ||
403 | memcpy(&stream->ctrl, &probe, sizeof probe); | 395 | memcpy(&stream->ctrl, &probe, sizeof probe); |
396 | mutex_unlock(&stream->mutex); | ||
404 | 397 | ||
405 | /* Return the actual frame period. */ | 398 | /* Return the actual frame period. */ |
406 | timeperframe.numerator = probe.dwFrameInterval; | 399 | timeperframe.numerator = probe.dwFrameInterval; |
@@ -528,11 +521,9 @@ static int uvc_v4l2_release(struct file *file) | |||
528 | if (uvc_has_privileges(handle)) { | 521 | if (uvc_has_privileges(handle)) { |
529 | uvc_video_enable(stream, 0); | 522 | uvc_video_enable(stream, 0); |
530 | 523 | ||
531 | mutex_lock(&stream->queue.mutex); | ||
532 | if (uvc_free_buffers(&stream->queue) < 0) | 524 | if (uvc_free_buffers(&stream->queue) < 0) |
533 | uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to " | 525 | uvc_printk(KERN_ERR, "uvc_v4l2_release: Unable to " |
534 | "free buffers.\n"); | 526 | "free buffers.\n"); |
535 | mutex_unlock(&stream->queue.mutex); | ||
536 | } | 527 | } |
537 | 528 | ||
538 | /* Release the file handle. */ | 529 | /* Release the file handle. */ |
@@ -624,7 +615,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
624 | } | 615 | } |
625 | 616 | ||
626 | case VIDIOC_QUERYMENU: | 617 | case VIDIOC_QUERYMENU: |
627 | return uvc_v4l2_query_menu(chain, arg); | 618 | return uvc_query_v4l2_menu(chain, arg); |
628 | 619 | ||
629 | case VIDIOC_G_EXT_CTRLS: | 620 | case VIDIOC_G_EXT_CTRLS: |
630 | { | 621 | { |
@@ -905,15 +896,17 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
905 | case VIDIOC_CROPCAP: | 896 | case VIDIOC_CROPCAP: |
906 | { | 897 | { |
907 | struct v4l2_cropcap *ccap = arg; | 898 | struct v4l2_cropcap *ccap = arg; |
908 | struct uvc_frame *frame = stream->cur_frame; | ||
909 | 899 | ||
910 | if (ccap->type != stream->type) | 900 | if (ccap->type != stream->type) |
911 | return -EINVAL; | 901 | return -EINVAL; |
912 | 902 | ||
913 | ccap->bounds.left = 0; | 903 | ccap->bounds.left = 0; |
914 | ccap->bounds.top = 0; | 904 | ccap->bounds.top = 0; |
915 | ccap->bounds.width = frame->wWidth; | 905 | |
916 | ccap->bounds.height = frame->wHeight; | 906 | mutex_lock(&stream->mutex); |
907 | ccap->bounds.width = stream->cur_frame->wWidth; | ||
908 | ccap->bounds.height = stream->cur_frame->wHeight; | ||
909 | mutex_unlock(&stream->mutex); | ||
917 | 910 | ||
918 | ccap->defrect = ccap->bounds; | 911 | ccap->defrect = ccap->bounds; |
919 | 912 | ||
@@ -930,8 +923,6 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
930 | case VIDIOC_REQBUFS: | 923 | case VIDIOC_REQBUFS: |
931 | { | 924 | { |
932 | struct v4l2_requestbuffers *rb = arg; | 925 | struct v4l2_requestbuffers *rb = arg; |
933 | unsigned int bufsize = | ||
934 | stream->ctrl.dwMaxVideoFrameSize; | ||
935 | 926 | ||
936 | if (rb->type != stream->type || | 927 | if (rb->type != stream->type || |
937 | rb->memory != V4L2_MEMORY_MMAP) | 928 | rb->memory != V4L2_MEMORY_MMAP) |
@@ -940,7 +931,10 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
940 | if ((ret = uvc_acquire_privileges(handle)) < 0) | 931 | if ((ret = uvc_acquire_privileges(handle)) < 0) |
941 | return ret; | 932 | return ret; |
942 | 933 | ||
943 | ret = uvc_alloc_buffers(&stream->queue, rb->count, bufsize); | 934 | mutex_lock(&stream->mutex); |
935 | ret = uvc_alloc_buffers(&stream->queue, rb->count, | ||
936 | stream->ctrl.dwMaxVideoFrameSize); | ||
937 | mutex_unlock(&stream->mutex); | ||
944 | if (ret < 0) | 938 | if (ret < 0) |
945 | return ret; | 939 | return ret; |
946 | 940 | ||
@@ -988,7 +982,9 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg) | |||
988 | if (!uvc_has_privileges(handle)) | 982 | if (!uvc_has_privileges(handle)) |
989 | return -EBUSY; | 983 | return -EBUSY; |
990 | 984 | ||
985 | mutex_lock(&stream->mutex); | ||
991 | ret = uvc_video_enable(stream, 1); | 986 | ret = uvc_video_enable(stream, 1); |
987 | mutex_unlock(&stream->mutex); | ||
992 | if (ret < 0) | 988 | if (ret < 0) |
993 | return ret; | 989 | return ret; |
994 | break; | 990 | break; |
@@ -1068,79 +1064,14 @@ static ssize_t uvc_v4l2_read(struct file *file, char __user *data, | |||
1068 | return -EINVAL; | 1064 | return -EINVAL; |
1069 | } | 1065 | } |
1070 | 1066 | ||
1071 | /* | ||
1072 | * VMA operations. | ||
1073 | */ | ||
1074 | static void uvc_vm_open(struct vm_area_struct *vma) | ||
1075 | { | ||
1076 | struct uvc_buffer *buffer = vma->vm_private_data; | ||
1077 | buffer->vma_use_count++; | ||
1078 | } | ||
1079 | |||
1080 | static void uvc_vm_close(struct vm_area_struct *vma) | ||
1081 | { | ||
1082 | struct uvc_buffer *buffer = vma->vm_private_data; | ||
1083 | buffer->vma_use_count--; | ||
1084 | } | ||
1085 | |||
1086 | static const struct vm_operations_struct uvc_vm_ops = { | ||
1087 | .open = uvc_vm_open, | ||
1088 | .close = uvc_vm_close, | ||
1089 | }; | ||
1090 | |||
1091 | static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma) | 1067 | static int uvc_v4l2_mmap(struct file *file, struct vm_area_struct *vma) |
1092 | { | 1068 | { |
1093 | struct uvc_fh *handle = file->private_data; | 1069 | struct uvc_fh *handle = file->private_data; |
1094 | struct uvc_streaming *stream = handle->stream; | 1070 | struct uvc_streaming *stream = handle->stream; |
1095 | struct uvc_video_queue *queue = &stream->queue; | ||
1096 | struct uvc_buffer *uninitialized_var(buffer); | ||
1097 | struct page *page; | ||
1098 | unsigned long addr, start, size; | ||
1099 | unsigned int i; | ||
1100 | int ret = 0; | ||
1101 | 1071 | ||
1102 | uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n"); | 1072 | uvc_trace(UVC_TRACE_CALLS, "uvc_v4l2_mmap\n"); |
1103 | 1073 | ||
1104 | start = vma->vm_start; | 1074 | return uvc_queue_mmap(&stream->queue, vma); |
1105 | size = vma->vm_end - vma->vm_start; | ||
1106 | |||
1107 | mutex_lock(&queue->mutex); | ||
1108 | |||
1109 | for (i = 0; i < queue->count; ++i) { | ||
1110 | buffer = &queue->buffer[i]; | ||
1111 | if ((buffer->buf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff) | ||
1112 | break; | ||
1113 | } | ||
1114 | |||
1115 | if (i == queue->count || size != queue->buf_size) { | ||
1116 | ret = -EINVAL; | ||
1117 | goto done; | ||
1118 | } | ||
1119 | |||
1120 | /* | ||
1121 | * VM_IO marks the area as being an mmaped region for I/O to a | ||
1122 | * device. It also prevents the region from being core dumped. | ||
1123 | */ | ||
1124 | vma->vm_flags |= VM_IO; | ||
1125 | |||
1126 | addr = (unsigned long)queue->mem + buffer->buf.m.offset; | ||
1127 | while (size > 0) { | ||
1128 | page = vmalloc_to_page((void *)addr); | ||
1129 | if ((ret = vm_insert_page(vma, start, page)) < 0) | ||
1130 | goto done; | ||
1131 | |||
1132 | start += PAGE_SIZE; | ||
1133 | addr += PAGE_SIZE; | ||
1134 | size -= PAGE_SIZE; | ||
1135 | } | ||
1136 | |||
1137 | vma->vm_ops = &uvc_vm_ops; | ||
1138 | vma->vm_private_data = buffer; | ||
1139 | uvc_vm_open(vma); | ||
1140 | |||
1141 | done: | ||
1142 | mutex_unlock(&queue->mutex); | ||
1143 | return ret; | ||
1144 | } | 1075 | } |
1145 | 1076 | ||
1146 | static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait) | 1077 | static unsigned int uvc_v4l2_poll(struct file *file, poll_table *wait) |
@@ -1157,7 +1088,7 @@ const struct v4l2_file_operations uvc_fops = { | |||
1157 | .owner = THIS_MODULE, | 1088 | .owner = THIS_MODULE, |
1158 | .open = uvc_v4l2_open, | 1089 | .open = uvc_v4l2_open, |
1159 | .release = uvc_v4l2_release, | 1090 | .release = uvc_v4l2_release, |
1160 | .ioctl = uvc_v4l2_ioctl, | 1091 | .unlocked_ioctl = uvc_v4l2_ioctl, |
1161 | .read = uvc_v4l2_read, | 1092 | .read = uvc_v4l2_read, |
1162 | .mmap = uvc_v4l2_mmap, | 1093 | .mmap = uvc_v4l2_mmap, |
1163 | .poll = uvc_v4l2_poll, | 1094 | .poll = uvc_v4l2_poll, |
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index 5555f0102838..5673d673504b 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c | |||
@@ -293,8 +293,6 @@ int uvc_probe_video(struct uvc_streaming *stream, | |||
293 | unsigned int i; | 293 | unsigned int i; |
294 | int ret; | 294 | int ret; |
295 | 295 | ||
296 | mutex_lock(&stream->mutex); | ||
297 | |||
298 | /* Perform probing. The device should adjust the requested values | 296 | /* Perform probing. The device should adjust the requested values |
299 | * according to its capabilities. However, some devices, namely the | 297 | * according to its capabilities. However, some devices, namely the |
300 | * first generation UVC Logitech webcams, don't implement the Video | 298 | * first generation UVC Logitech webcams, don't implement the Video |
@@ -346,7 +344,6 @@ int uvc_probe_video(struct uvc_streaming *stream, | |||
346 | } | 344 | } |
347 | 345 | ||
348 | done: | 346 | done: |
349 | mutex_unlock(&stream->mutex); | ||
350 | return ret; | 347 | return ret; |
351 | } | 348 | } |
352 | 349 | ||
diff --git a/drivers/media/video/uvc/uvcvideo.h b/drivers/media/video/uvc/uvcvideo.h index d97cf6d6a4f9..45f01e7e13d2 100644 --- a/drivers/media/video/uvc/uvcvideo.h +++ b/drivers/media/video/uvc/uvcvideo.h | |||
@@ -436,7 +436,9 @@ struct uvc_streaming { | |||
436 | struct uvc_streaming_control ctrl; | 436 | struct uvc_streaming_control ctrl; |
437 | struct uvc_format *cur_format; | 437 | struct uvc_format *cur_format; |
438 | struct uvc_frame *cur_frame; | 438 | struct uvc_frame *cur_frame; |
439 | 439 | /* Protect access to ctrl, cur_format, cur_frame and hardware video | |
440 | * probe control. | ||
441 | */ | ||
440 | struct mutex mutex; | 442 | struct mutex mutex; |
441 | 443 | ||
442 | unsigned int frozen : 1; | 444 | unsigned int frozen : 1; |
@@ -574,6 +576,8 @@ extern int uvc_queue_enable(struct uvc_video_queue *queue, int enable); | |||
574 | extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect); | 576 | extern void uvc_queue_cancel(struct uvc_video_queue *queue, int disconnect); |
575 | extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, | 577 | extern struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, |
576 | struct uvc_buffer *buf); | 578 | struct uvc_buffer *buf); |
579 | extern int uvc_queue_mmap(struct uvc_video_queue *queue, | ||
580 | struct vm_area_struct *vma); | ||
577 | extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue, | 581 | extern unsigned int uvc_queue_poll(struct uvc_video_queue *queue, |
578 | struct file *file, poll_table *wait); | 582 | struct file *file, poll_table *wait); |
579 | extern int uvc_queue_allocated(struct uvc_video_queue *queue); | 583 | extern int uvc_queue_allocated(struct uvc_video_queue *queue); |
@@ -606,10 +610,10 @@ extern int uvc_status_suspend(struct uvc_device *dev); | |||
606 | extern int uvc_status_resume(struct uvc_device *dev); | 610 | extern int uvc_status_resume(struct uvc_device *dev); |
607 | 611 | ||
608 | /* Controls */ | 612 | /* Controls */ |
609 | extern struct uvc_control *uvc_find_control(struct uvc_video_chain *chain, | ||
610 | __u32 v4l2_id, struct uvc_control_mapping **mapping); | ||
611 | extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, | 613 | extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, |
612 | struct v4l2_queryctrl *v4l2_ctrl); | 614 | struct v4l2_queryctrl *v4l2_ctrl); |
615 | extern int uvc_query_v4l2_menu(struct uvc_video_chain *chain, | ||
616 | struct v4l2_querymenu *query_menu); | ||
613 | 617 | ||
614 | extern int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, | 618 | extern int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, |
615 | const struct uvc_control_mapping *mapping); | 619 | const struct uvc_control_mapping *mapping); |
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 03f7f4670e9b..359e23290a7e 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c | |||
@@ -186,12 +186,12 @@ static ssize_t v4l2_read(struct file *filp, char __user *buf, | |||
186 | size_t sz, loff_t *off) | 186 | size_t sz, loff_t *off) |
187 | { | 187 | { |
188 | struct video_device *vdev = video_devdata(filp); | 188 | struct video_device *vdev = video_devdata(filp); |
189 | int ret = -EIO; | 189 | int ret = -ENODEV; |
190 | 190 | ||
191 | if (!vdev->fops->read) | 191 | if (!vdev->fops->read) |
192 | return -EINVAL; | 192 | return -EINVAL; |
193 | if (vdev->lock) | 193 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) |
194 | mutex_lock(vdev->lock); | 194 | return -ERESTARTSYS; |
195 | if (video_is_registered(vdev)) | 195 | if (video_is_registered(vdev)) |
196 | ret = vdev->fops->read(filp, buf, sz, off); | 196 | ret = vdev->fops->read(filp, buf, sz, off); |
197 | if (vdev->lock) | 197 | if (vdev->lock) |
@@ -203,12 +203,12 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf, | |||
203 | size_t sz, loff_t *off) | 203 | size_t sz, loff_t *off) |
204 | { | 204 | { |
205 | struct video_device *vdev = video_devdata(filp); | 205 | struct video_device *vdev = video_devdata(filp); |
206 | int ret = -EIO; | 206 | int ret = -ENODEV; |
207 | 207 | ||
208 | if (!vdev->fops->write) | 208 | if (!vdev->fops->write) |
209 | return -EINVAL; | 209 | return -EINVAL; |
210 | if (vdev->lock) | 210 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) |
211 | mutex_lock(vdev->lock); | 211 | return -ERESTARTSYS; |
212 | if (video_is_registered(vdev)) | 212 | if (video_is_registered(vdev)) |
213 | ret = vdev->fops->write(filp, buf, sz, off); | 213 | ret = vdev->fops->write(filp, buf, sz, off); |
214 | if (vdev->lock) | 214 | if (vdev->lock) |
@@ -219,10 +219,10 @@ static ssize_t v4l2_write(struct file *filp, const char __user *buf, | |||
219 | static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll) | 219 | static unsigned int v4l2_poll(struct file *filp, struct poll_table_struct *poll) |
220 | { | 220 | { |
221 | struct video_device *vdev = video_devdata(filp); | 221 | struct video_device *vdev = video_devdata(filp); |
222 | int ret = DEFAULT_POLLMASK; | 222 | int ret = POLLERR | POLLHUP; |
223 | 223 | ||
224 | if (!vdev->fops->poll) | 224 | if (!vdev->fops->poll) |
225 | return ret; | 225 | return DEFAULT_POLLMASK; |
226 | if (vdev->lock) | 226 | if (vdev->lock) |
227 | mutex_lock(vdev->lock); | 227 | mutex_lock(vdev->lock); |
228 | if (video_is_registered(vdev)) | 228 | if (video_is_registered(vdev)) |
@@ -238,20 +238,45 @@ static long v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | |||
238 | int ret = -ENODEV; | 238 | int ret = -ENODEV; |
239 | 239 | ||
240 | if (vdev->fops->unlocked_ioctl) { | 240 | if (vdev->fops->unlocked_ioctl) { |
241 | if (vdev->lock) | 241 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) |
242 | mutex_lock(vdev->lock); | 242 | return -ERESTARTSYS; |
243 | if (video_is_registered(vdev)) | 243 | if (video_is_registered(vdev)) |
244 | ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); | 244 | ret = vdev->fops->unlocked_ioctl(filp, cmd, arg); |
245 | if (vdev->lock) | 245 | if (vdev->lock) |
246 | mutex_unlock(vdev->lock); | 246 | mutex_unlock(vdev->lock); |
247 | } else if (vdev->fops->ioctl) { | 247 | } else if (vdev->fops->ioctl) { |
248 | /* TODO: convert all drivers to unlocked_ioctl */ | 248 | /* This code path is a replacement for the BKL. It is a major |
249 | * hack but it will have to do for those drivers that are not | ||
250 | * yet converted to use unlocked_ioctl. | ||
251 | * | ||
252 | * There are two options: if the driver implements struct | ||
253 | * v4l2_device, then the lock defined there is used to | ||
254 | * serialize the ioctls. Otherwise the v4l2 core lock defined | ||
255 | * below is used. This lock is really bad since it serializes | ||
256 | * completely independent devices. | ||
257 | * | ||
258 | * Both variants suffer from the same problem: if the driver | ||
259 | * sleeps, then it blocks all ioctls since the lock is still | ||
260 | * held. This is very common for VIDIOC_DQBUF since that | ||
261 | * normally waits for a frame to arrive. As a result any other | ||
262 | * ioctl calls will proceed very, very slowly since each call | ||
263 | * will have to wait for the VIDIOC_QBUF to finish. Things that | ||
264 | * should take 0.01s may now take 10-20 seconds. | ||
265 | * | ||
266 | * The workaround is to *not* take the lock for VIDIOC_DQBUF. | ||
267 | * This actually works OK for videobuf-based drivers, since | ||
268 | * videobuf will take its own internal lock. | ||
269 | */ | ||
249 | static DEFINE_MUTEX(v4l2_ioctl_mutex); | 270 | static DEFINE_MUTEX(v4l2_ioctl_mutex); |
271 | struct mutex *m = vdev->v4l2_dev ? | ||
272 | &vdev->v4l2_dev->ioctl_lock : &v4l2_ioctl_mutex; | ||
250 | 273 | ||
251 | mutex_lock(&v4l2_ioctl_mutex); | 274 | if (cmd != VIDIOC_DQBUF && mutex_lock_interruptible(m)) |
275 | return -ERESTARTSYS; | ||
252 | if (video_is_registered(vdev)) | 276 | if (video_is_registered(vdev)) |
253 | ret = vdev->fops->ioctl(filp, cmd, arg); | 277 | ret = vdev->fops->ioctl(filp, cmd, arg); |
254 | mutex_unlock(&v4l2_ioctl_mutex); | 278 | if (cmd != VIDIOC_DQBUF) |
279 | mutex_unlock(m); | ||
255 | } else | 280 | } else |
256 | ret = -ENOTTY; | 281 | ret = -ENOTTY; |
257 | 282 | ||
@@ -265,8 +290,8 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm) | |||
265 | 290 | ||
266 | if (!vdev->fops->mmap) | 291 | if (!vdev->fops->mmap) |
267 | return ret; | 292 | return ret; |
268 | if (vdev->lock) | 293 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) |
269 | mutex_lock(vdev->lock); | 294 | return -ERESTARTSYS; |
270 | if (video_is_registered(vdev)) | 295 | if (video_is_registered(vdev)) |
271 | ret = vdev->fops->mmap(filp, vm); | 296 | ret = vdev->fops->mmap(filp, vm); |
272 | if (vdev->lock) | 297 | if (vdev->lock) |
@@ -284,7 +309,7 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
284 | mutex_lock(&videodev_lock); | 309 | mutex_lock(&videodev_lock); |
285 | vdev = video_devdata(filp); | 310 | vdev = video_devdata(filp); |
286 | /* return ENODEV if the video device has already been removed. */ | 311 | /* return ENODEV if the video device has already been removed. */ |
287 | if (vdev == NULL) { | 312 | if (vdev == NULL || !video_is_registered(vdev)) { |
288 | mutex_unlock(&videodev_lock); | 313 | mutex_unlock(&videodev_lock); |
289 | return -ENODEV; | 314 | return -ENODEV; |
290 | } | 315 | } |
@@ -292,8 +317,10 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
292 | video_get(vdev); | 317 | video_get(vdev); |
293 | mutex_unlock(&videodev_lock); | 318 | mutex_unlock(&videodev_lock); |
294 | if (vdev->fops->open) { | 319 | if (vdev->fops->open) { |
295 | if (vdev->lock) | 320 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) { |
296 | mutex_lock(vdev->lock); | 321 | ret = -ERESTARTSYS; |
322 | goto err; | ||
323 | } | ||
297 | if (video_is_registered(vdev)) | 324 | if (video_is_registered(vdev)) |
298 | ret = vdev->fops->open(filp); | 325 | ret = vdev->fops->open(filp); |
299 | else | 326 | else |
@@ -302,6 +329,7 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
302 | mutex_unlock(vdev->lock); | 329 | mutex_unlock(vdev->lock); |
303 | } | 330 | } |
304 | 331 | ||
332 | err: | ||
305 | /* decrease the refcount in case of an error */ | 333 | /* decrease the refcount in case of an error */ |
306 | if (ret) | 334 | if (ret) |
307 | video_put(vdev); | 335 | video_put(vdev); |
@@ -596,7 +624,12 @@ void video_unregister_device(struct video_device *vdev) | |||
596 | if (!vdev || !video_is_registered(vdev)) | 624 | if (!vdev || !video_is_registered(vdev)) |
597 | return; | 625 | return; |
598 | 626 | ||
627 | mutex_lock(&videodev_lock); | ||
628 | /* This must be in a critical section to prevent a race with v4l2_open. | ||
629 | * Once this bit has been cleared video_get may never be called again. | ||
630 | */ | ||
599 | clear_bit(V4L2_FL_REGISTERED, &vdev->flags); | 631 | clear_bit(V4L2_FL_REGISTERED, &vdev->flags); |
632 | mutex_unlock(&videodev_lock); | ||
600 | device_unregister(&vdev->dev); | 633 | device_unregister(&vdev->dev); |
601 | } | 634 | } |
602 | EXPORT_SYMBOL(video_unregister_device); | 635 | EXPORT_SYMBOL(video_unregister_device); |
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c index 0b08f96b74a5..7fe6f92af480 100644 --- a/drivers/media/video/v4l2-device.c +++ b/drivers/media/video/v4l2-device.c | |||
@@ -35,6 +35,7 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev) | |||
35 | 35 | ||
36 | INIT_LIST_HEAD(&v4l2_dev->subdevs); | 36 | INIT_LIST_HEAD(&v4l2_dev->subdevs); |
37 | spin_lock_init(&v4l2_dev->lock); | 37 | spin_lock_init(&v4l2_dev->lock); |
38 | mutex_init(&v4l2_dev->ioctl_lock); | ||
38 | v4l2_dev->dev = dev; | 39 | v4l2_dev->dev = dev; |
39 | if (dev == NULL) { | 40 | if (dev == NULL) { |
40 | /* If dev == NULL, then name must be filled in by the caller */ | 41 | /* If dev == NULL, then name must be filled in by the caller */ |
diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c index 635420d8d84a..019ee206cbee 100644 --- a/drivers/media/video/w9966.c +++ b/drivers/media/video/w9966.c | |||
@@ -815,7 +815,7 @@ out: | |||
815 | 815 | ||
816 | static const struct v4l2_file_operations w9966_fops = { | 816 | static const struct v4l2_file_operations w9966_fops = { |
817 | .owner = THIS_MODULE, | 817 | .owner = THIS_MODULE, |
818 | .ioctl = video_ioctl2, | 818 | .unlocked_ioctl = video_ioctl2, |
819 | .read = w9966_v4l_read, | 819 | .read = w9966_v4l_read, |
820 | }; | 820 | }; |
821 | 821 | ||
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c index 135525649086..fe8ef6419f83 100644 --- a/drivers/media/video/wm8775.c +++ b/drivers/media/video/wm8775.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <media/v4l2-device.h> | 35 | #include <media/v4l2-device.h> |
36 | #include <media/v4l2-chip-ident.h> | 36 | #include <media/v4l2-chip-ident.h> |
37 | #include <media/v4l2-ctrls.h> | 37 | #include <media/v4l2-ctrls.h> |
38 | #include <media/wm8775.h> | ||
39 | 38 | ||
40 | MODULE_DESCRIPTION("wm8775 driver"); | 39 | MODULE_DESCRIPTION("wm8775 driver"); |
41 | MODULE_AUTHOR("Ulf Eklund, Hans Verkuil"); | 40 | MODULE_AUTHOR("Ulf Eklund, Hans Verkuil"); |
@@ -51,16 +50,10 @@ enum { | |||
51 | TOT_REGS | 50 | TOT_REGS |
52 | }; | 51 | }; |
53 | 52 | ||
54 | #define ALC_HOLD 0x85 /* R17: use zero cross detection, ALC hold time 42.6 ms */ | ||
55 | #define ALC_EN 0x100 /* R17: ALC enable */ | ||
56 | |||
57 | struct wm8775_state { | 53 | struct wm8775_state { |
58 | struct v4l2_subdev sd; | 54 | struct v4l2_subdev sd; |
59 | struct v4l2_ctrl_handler hdl; | 55 | struct v4l2_ctrl_handler hdl; |
60 | struct v4l2_ctrl *mute; | 56 | struct v4l2_ctrl *mute; |
61 | struct v4l2_ctrl *vol; | ||
62 | struct v4l2_ctrl *bal; | ||
63 | struct v4l2_ctrl *loud; | ||
64 | u8 input; /* Last selected input (0-0xf) */ | 57 | u8 input; /* Last selected input (0-0xf) */ |
65 | }; | 58 | }; |
66 | 59 | ||
@@ -92,30 +85,6 @@ static int wm8775_write(struct v4l2_subdev *sd, int reg, u16 val) | |||
92 | return -1; | 85 | return -1; |
93 | } | 86 | } |
94 | 87 | ||
95 | static void wm8775_set_audio(struct v4l2_subdev *sd, int quietly) | ||
96 | { | ||
97 | struct wm8775_state *state = to_state(sd); | ||
98 | u8 vol_l, vol_r; | ||
99 | int muted = 0 != state->mute->val; | ||
100 | u16 volume = (u16)state->vol->val; | ||
101 | u16 balance = (u16)state->bal->val; | ||
102 | |||
103 | /* normalize ( 65535 to 0 -> 255 to 0 (+24dB to -103dB) ) */ | ||
104 | vol_l = (min(65536 - balance, 32768) * volume) >> 23; | ||
105 | vol_r = (min(balance, (u16)32768) * volume) >> 23; | ||
106 | |||
107 | /* Mute */ | ||
108 | if (muted || quietly) | ||
109 | wm8775_write(sd, R21, 0x0c0 | state->input); | ||
110 | |||
111 | wm8775_write(sd, R14, vol_l | 0x100); /* 0x100= Left channel ADC zero cross enable */ | ||
112 | wm8775_write(sd, R15, vol_r | 0x100); /* 0x100= Right channel ADC zero cross enable */ | ||
113 | |||
114 | /* Un-mute */ | ||
115 | if (!muted) | ||
116 | wm8775_write(sd, R21, state->input); | ||
117 | } | ||
118 | |||
119 | static int wm8775_s_routing(struct v4l2_subdev *sd, | 88 | static int wm8775_s_routing(struct v4l2_subdev *sd, |
120 | u32 input, u32 output, u32 config) | 89 | u32 input, u32 output, u32 config) |
121 | { | 90 | { |
@@ -133,26 +102,25 @@ static int wm8775_s_routing(struct v4l2_subdev *sd, | |||
133 | state->input = input; | 102 | state->input = input; |
134 | if (!v4l2_ctrl_g_ctrl(state->mute)) | 103 | if (!v4l2_ctrl_g_ctrl(state->mute)) |
135 | return 0; | 104 | return 0; |
136 | if (!v4l2_ctrl_g_ctrl(state->vol)) | 105 | wm8775_write(sd, R21, 0x0c0); |
137 | return 0; | 106 | wm8775_write(sd, R14, 0x1d4); |
138 | if (!v4l2_ctrl_g_ctrl(state->bal)) | 107 | wm8775_write(sd, R15, 0x1d4); |
139 | return 0; | 108 | wm8775_write(sd, R21, 0x100 + state->input); |
140 | wm8775_set_audio(sd, 1); | ||
141 | return 0; | 109 | return 0; |
142 | } | 110 | } |
143 | 111 | ||
144 | static int wm8775_s_ctrl(struct v4l2_ctrl *ctrl) | 112 | static int wm8775_s_ctrl(struct v4l2_ctrl *ctrl) |
145 | { | 113 | { |
146 | struct v4l2_subdev *sd = to_sd(ctrl); | 114 | struct v4l2_subdev *sd = to_sd(ctrl); |
115 | struct wm8775_state *state = to_state(sd); | ||
147 | 116 | ||
148 | switch (ctrl->id) { | 117 | switch (ctrl->id) { |
149 | case V4L2_CID_AUDIO_MUTE: | 118 | case V4L2_CID_AUDIO_MUTE: |
150 | case V4L2_CID_AUDIO_VOLUME: | 119 | wm8775_write(sd, R21, 0x0c0); |
151 | case V4L2_CID_AUDIO_BALANCE: | 120 | wm8775_write(sd, R14, 0x1d4); |
152 | wm8775_set_audio(sd, 0); | 121 | wm8775_write(sd, R15, 0x1d4); |
153 | return 0; | 122 | if (!ctrl->val) |
154 | case V4L2_CID_AUDIO_LOUDNESS: | 123 | wm8775_write(sd, R21, 0x100 + state->input); |
155 | wm8775_write(sd, R17, (ctrl->val ? ALC_EN : 0) | ALC_HOLD); | ||
156 | return 0; | 124 | return 0; |
157 | } | 125 | } |
158 | return -EINVAL; | 126 | return -EINVAL; |
@@ -176,7 +144,16 @@ static int wm8775_log_status(struct v4l2_subdev *sd) | |||
176 | 144 | ||
177 | static int wm8775_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq) | 145 | static int wm8775_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq) |
178 | { | 146 | { |
179 | wm8775_set_audio(sd, 0); | 147 | struct wm8775_state *state = to_state(sd); |
148 | |||
149 | /* If I remove this, then it can happen that I have no | ||
150 | sound the first time I tune from static to a valid channel. | ||
151 | It's difficult to reproduce and is almost certainly related | ||
152 | to the zero cross detect circuit. */ | ||
153 | wm8775_write(sd, R21, 0x0c0); | ||
154 | wm8775_write(sd, R14, 0x1d4); | ||
155 | wm8775_write(sd, R15, 0x1d4); | ||
156 | wm8775_write(sd, R21, 0x100 + state->input); | ||
180 | return 0; | 157 | return 0; |
181 | } | 158 | } |
182 | 159 | ||
@@ -226,7 +203,6 @@ static int wm8775_probe(struct i2c_client *client, | |||
226 | { | 203 | { |
227 | struct wm8775_state *state; | 204 | struct wm8775_state *state; |
228 | struct v4l2_subdev *sd; | 205 | struct v4l2_subdev *sd; |
229 | int err; | ||
230 | 206 | ||
231 | /* Check if the adapter supports the needed features */ | 207 | /* Check if the adapter supports the needed features */ |
232 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 208 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
@@ -240,21 +216,15 @@ static int wm8775_probe(struct i2c_client *client, | |||
240 | return -ENOMEM; | 216 | return -ENOMEM; |
241 | sd = &state->sd; | 217 | sd = &state->sd; |
242 | v4l2_i2c_subdev_init(sd, client, &wm8775_ops); | 218 | v4l2_i2c_subdev_init(sd, client, &wm8775_ops); |
243 | sd->grp_id = WM8775_GID; /* subdev group id */ | ||
244 | state->input = 2; | 219 | state->input = 2; |
245 | 220 | ||
246 | v4l2_ctrl_handler_init(&state->hdl, 4); | 221 | v4l2_ctrl_handler_init(&state->hdl, 1); |
247 | state->mute = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops, | 222 | state->mute = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops, |
248 | V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); | 223 | V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); |
249 | state->vol = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops, | ||
250 | V4L2_CID_AUDIO_VOLUME, 0, 65535, (65535+99)/100, 0xCF00); /* 0dB*/ | ||
251 | state->bal = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops, | ||
252 | V4L2_CID_AUDIO_BALANCE, 0, 65535, (65535+99)/100, 32768); | ||
253 | state->loud = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops, | ||
254 | V4L2_CID_AUDIO_LOUDNESS, 0, 1, 1, 1); | ||
255 | sd->ctrl_handler = &state->hdl; | 224 | sd->ctrl_handler = &state->hdl; |
256 | err = state->hdl.error; | 225 | if (state->hdl.error) { |
257 | if (err) { | 226 | int err = state->hdl.error; |
227 | |||
258 | v4l2_ctrl_handler_free(&state->hdl); | 228 | v4l2_ctrl_handler_free(&state->hdl); |
259 | kfree(state); | 229 | kfree(state); |
260 | return err; | 230 | return err; |
@@ -266,25 +236,29 @@ static int wm8775_probe(struct i2c_client *client, | |||
266 | wm8775_write(sd, R23, 0x000); | 236 | wm8775_write(sd, R23, 0x000); |
267 | /* Disable zero cross detect timeout */ | 237 | /* Disable zero cross detect timeout */ |
268 | wm8775_write(sd, R7, 0x000); | 238 | wm8775_write(sd, R7, 0x000); |
269 | /* HPF enable, I2S mode, 24-bit */ | 239 | /* Left justified, 24-bit mode */ |
270 | wm8775_write(sd, R11, 0x022); | 240 | wm8775_write(sd, R11, 0x021); |
271 | /* Master mode, clock ratio 256fs */ | 241 | /* Master mode, clock ratio 256fs */ |
272 | wm8775_write(sd, R12, 0x102); | 242 | wm8775_write(sd, R12, 0x102); |
273 | /* Powered up */ | 243 | /* Powered up */ |
274 | wm8775_write(sd, R13, 0x000); | 244 | wm8775_write(sd, R13, 0x000); |
275 | /* ALC stereo, ALC target level -5dB FS, ALC max gain +8dB */ | 245 | /* ADC gain +2.5dB, enable zero cross */ |
276 | wm8775_write(sd, R16, 0x1bb); | 246 | wm8775_write(sd, R14, 0x1d4); |
277 | /* Set ALC mode and hold time */ | 247 | /* ADC gain +2.5dB, enable zero cross */ |
278 | wm8775_write(sd, R17, (state->loud->val ? ALC_EN : 0) | ALC_HOLD); | 248 | wm8775_write(sd, R15, 0x1d4); |
249 | /* ALC Stereo, ALC target level -1dB FS max gain +8dB */ | ||
250 | wm8775_write(sd, R16, 0x1bf); | ||
251 | /* Enable gain control, use zero cross detection, | ||
252 | ALC hold time 42.6 ms */ | ||
253 | wm8775_write(sd, R17, 0x185); | ||
279 | /* ALC gain ramp up delay 34 s, ALC gain ramp down delay 33 ms */ | 254 | /* ALC gain ramp up delay 34 s, ALC gain ramp down delay 33 ms */ |
280 | wm8775_write(sd, R18, 0x0a2); | 255 | wm8775_write(sd, R18, 0x0a2); |
281 | /* Enable noise gate, threshold -72dBfs */ | 256 | /* Enable noise gate, threshold -72dBfs */ |
282 | wm8775_write(sd, R19, 0x005); | 257 | wm8775_write(sd, R19, 0x005); |
283 | /* Transient window 4ms, ALC min gain -5dB */ | 258 | /* Transient window 4ms, lower PGA gain limit -1dB */ |
284 | wm8775_write(sd, R20, 0x0fb); | 259 | wm8775_write(sd, R20, 0x07a); |
285 | 260 | /* LRBOTH = 1, use input 2. */ | |
286 | wm8775_set_audio(sd, 1); /* set volume/mute/mux */ | 261 | wm8775_write(sd, R21, 0x102); |
287 | |||
288 | return 0; | 262 | return 0; |
289 | } | 263 | } |
290 | 264 | ||
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index dbe1c93c1af3..d9640a623ff4 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
@@ -303,7 +303,7 @@ static irqreturn_t ab8500_irq(int irq, void *dev) | |||
303 | continue; | 303 | continue; |
304 | 304 | ||
305 | do { | 305 | do { |
306 | int bit = __ffs(status); | 306 | int bit = __ffs(value); |
307 | int line = i * 8 + bit; | 307 | int line = i * 8 + bit; |
308 | 308 | ||
309 | handle_nested_irq(ab8500->irq_base + line); | 309 | handle_nested_irq(ab8500->irq_base + line); |
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c index 7d2563fc15c6..76cadcf3b1fe 100644 --- a/drivers/mfd/wm831x-core.c +++ b/drivers/mfd/wm831x-core.c | |||
@@ -1455,7 +1455,11 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
1455 | dev_err(wm831x->dev, "Failed to read parent ID: %d\n", ret); | 1455 | dev_err(wm831x->dev, "Failed to read parent ID: %d\n", ret); |
1456 | goto err; | 1456 | goto err; |
1457 | } | 1457 | } |
1458 | if (ret != 0x6204) { | 1458 | switch (ret) { |
1459 | case 0x6204: | ||
1460 | case 0x6246: | ||
1461 | break; | ||
1462 | default: | ||
1459 | dev_err(wm831x->dev, "Device is not a WM831x: ID %x\n", ret); | 1463 | dev_err(wm831x->dev, "Device is not a WM831x: ID %x\n", ret); |
1460 | ret = -EINVAL; | 1464 | ret = -EINVAL; |
1461 | goto err; | 1465 | goto err; |
@@ -1620,7 +1624,7 @@ int wm831x_device_init(struct wm831x *wm831x, unsigned long id, int irq) | |||
1620 | case WM8325: | 1624 | case WM8325: |
1621 | ret = mfd_add_devices(wm831x->dev, -1, | 1625 | ret = mfd_add_devices(wm831x->dev, -1, |
1622 | wm8320_devs, ARRAY_SIZE(wm8320_devs), | 1626 | wm8320_devs, ARRAY_SIZE(wm8320_devs), |
1623 | NULL, 0); | 1627 | NULL, wm831x->irq_base); |
1624 | break; | 1628 | break; |
1625 | 1629 | ||
1626 | default: | 1630 | default: |
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 31ae07a36576..57dcf8fa774a 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c | |||
@@ -1773,6 +1773,7 @@ int mmc_pm_notify(struct notifier_block *notify_block, | |||
1773 | 1773 | ||
1774 | case PM_POST_SUSPEND: | 1774 | case PM_POST_SUSPEND: |
1775 | case PM_POST_HIBERNATION: | 1775 | case PM_POST_HIBERNATION: |
1776 | case PM_POST_RESTORE: | ||
1776 | 1777 | ||
1777 | spin_lock_irqsave(&host->lock, flags); | 1778 | spin_lock_irqsave(&host->lock, flags); |
1778 | host->rescan_disable = 0; | 1779 | host->rescan_disable = 0; |
diff --git a/drivers/mmc/host/at91_mci.c b/drivers/mmc/host/at91_mci.c index 591ab540b407..d3e6a962f423 100644 --- a/drivers/mmc/host/at91_mci.c +++ b/drivers/mmc/host/at91_mci.c | |||
@@ -69,6 +69,7 @@ | |||
69 | #include <linux/highmem.h> | 69 | #include <linux/highmem.h> |
70 | 70 | ||
71 | #include <linux/mmc/host.h> | 71 | #include <linux/mmc/host.h> |
72 | #include <linux/mmc/sdio.h> | ||
72 | 73 | ||
73 | #include <asm/io.h> | 74 | #include <asm/io.h> |
74 | #include <asm/irq.h> | 75 | #include <asm/irq.h> |
@@ -493,10 +494,14 @@ static void at91_mci_send_command(struct at91mci_host *host, struct mmc_command | |||
493 | else if (data->flags & MMC_DATA_WRITE) | 494 | else if (data->flags & MMC_DATA_WRITE) |
494 | cmdr |= AT91_MCI_TRCMD_START; | 495 | cmdr |= AT91_MCI_TRCMD_START; |
495 | 496 | ||
496 | if (data->flags & MMC_DATA_STREAM) | 497 | if (cmd->opcode == SD_IO_RW_EXTENDED) { |
497 | cmdr |= AT91_MCI_TRTYP_STREAM; | 498 | cmdr |= AT91_MCI_TRTYP_SDIO_BLOCK; |
498 | if (data->blocks > 1) | 499 | } else { |
499 | cmdr |= AT91_MCI_TRTYP_MULTIPLE; | 500 | if (data->flags & MMC_DATA_STREAM) |
501 | cmdr |= AT91_MCI_TRTYP_STREAM; | ||
502 | if (data->blocks > 1) | ||
503 | cmdr |= AT91_MCI_TRTYP_MULTIPLE; | ||
504 | } | ||
500 | } | 505 | } |
501 | else { | 506 | else { |
502 | block_length = 0; | 507 | block_length = 0; |
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 301351a5d838..ad2a7a032cdf 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/stat.h> | 26 | #include <linux/stat.h> |
27 | 27 | ||
28 | #include <linux/mmc/host.h> | 28 | #include <linux/mmc/host.h> |
29 | #include <linux/mmc/sdio.h> | ||
29 | 30 | ||
30 | #include <mach/atmel-mci.h> | 31 | #include <mach/atmel-mci.h> |
31 | #include <linux/atmel-mci.h> | 32 | #include <linux/atmel-mci.h> |
@@ -532,12 +533,17 @@ static u32 atmci_prepare_command(struct mmc_host *mmc, | |||
532 | data = cmd->data; | 533 | data = cmd->data; |
533 | if (data) { | 534 | if (data) { |
534 | cmdr |= MCI_CMDR_START_XFER; | 535 | cmdr |= MCI_CMDR_START_XFER; |
535 | if (data->flags & MMC_DATA_STREAM) | 536 | |
536 | cmdr |= MCI_CMDR_STREAM; | 537 | if (cmd->opcode == SD_IO_RW_EXTENDED) { |
537 | else if (data->blocks > 1) | 538 | cmdr |= MCI_CMDR_SDIO_BLOCK; |
538 | cmdr |= MCI_CMDR_MULTI_BLOCK; | 539 | } else { |
539 | else | 540 | if (data->flags & MMC_DATA_STREAM) |
540 | cmdr |= MCI_CMDR_BLOCK; | 541 | cmdr |= MCI_CMDR_STREAM; |
542 | else if (data->blocks > 1) | ||
543 | cmdr |= MCI_CMDR_MULTI_BLOCK; | ||
544 | else | ||
545 | cmdr |= MCI_CMDR_BLOCK; | ||
546 | } | ||
541 | 547 | ||
542 | if (data->flags & MMC_DATA_READ) | 548 | if (data->flags & MMC_DATA_READ) |
543 | cmdr |= MCI_CMDR_TRDIR_READ; | 549 | cmdr |= MCI_CMDR_TRDIR_READ; |
diff --git a/drivers/mtd/maps/pxa2xx-flash.c b/drivers/mtd/maps/pxa2xx-flash.c index dd90880048cf..d8ae634d347e 100644 --- a/drivers/mtd/maps/pxa2xx-flash.c +++ b/drivers/mtd/maps/pxa2xx-flash.c | |||
@@ -51,7 +51,7 @@ struct pxa2xx_flash_info { | |||
51 | static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; | 51 | static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; |
52 | 52 | ||
53 | 53 | ||
54 | static int __init pxa2xx_flash_probe(struct platform_device *pdev) | 54 | static int __devinit pxa2xx_flash_probe(struct platform_device *pdev) |
55 | { | 55 | { |
56 | struct flash_platform_data *flash = pdev->dev.platform_data; | 56 | struct flash_platform_data *flash = pdev->dev.platform_data; |
57 | struct pxa2xx_flash_info *info; | 57 | struct pxa2xx_flash_info *info; |
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index cd41c58b5bbd..15682ec8530e 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
@@ -7,7 +7,6 @@ | |||
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | */ | 9 | */ |
10 | #define CONFIG_MTD_NAND_OMAP_HWECC | ||
11 | 10 | ||
12 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
13 | #include <linux/dma-mapping.h> | 12 | #include <linux/dma-mapping.h> |
diff --git a/drivers/net/atl1c/atl1c_main.c b/drivers/net/atl1c/atl1c_main.c index 09b099bfab2b..bdf11d89a499 100644 --- a/drivers/net/atl1c/atl1c_main.c +++ b/drivers/net/atl1c/atl1c_main.c | |||
@@ -702,6 +702,7 @@ static int __devinit atl1c_sw_init(struct atl1c_adapter *adapter) | |||
702 | 702 | ||
703 | 703 | ||
704 | adapter->wol = 0; | 704 | adapter->wol = 0; |
705 | device_set_wakeup_enable(&pdev->dev, false); | ||
705 | adapter->link_speed = SPEED_0; | 706 | adapter->link_speed = SPEED_0; |
706 | adapter->link_duplex = FULL_DUPLEX; | 707 | adapter->link_duplex = FULL_DUPLEX; |
707 | adapter->num_rx_queues = AT_DEF_RECEIVE_QUEUE; | 708 | adapter->num_rx_queues = AT_DEF_RECEIVE_QUEUE; |
@@ -2444,8 +2445,9 @@ static int atl1c_close(struct net_device *netdev) | |||
2444 | return 0; | 2445 | return 0; |
2445 | } | 2446 | } |
2446 | 2447 | ||
2447 | static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state) | 2448 | static int atl1c_suspend(struct device *dev) |
2448 | { | 2449 | { |
2450 | struct pci_dev *pdev = to_pci_dev(dev); | ||
2449 | struct net_device *netdev = pci_get_drvdata(pdev); | 2451 | struct net_device *netdev = pci_get_drvdata(pdev); |
2450 | struct atl1c_adapter *adapter = netdev_priv(netdev); | 2452 | struct atl1c_adapter *adapter = netdev_priv(netdev); |
2451 | struct atl1c_hw *hw = &adapter->hw; | 2453 | struct atl1c_hw *hw = &adapter->hw; |
@@ -2454,7 +2456,6 @@ static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2454 | u32 wol_ctrl_data = 0; | 2456 | u32 wol_ctrl_data = 0; |
2455 | u16 mii_intr_status_data = 0; | 2457 | u16 mii_intr_status_data = 0; |
2456 | u32 wufc = adapter->wol; | 2458 | u32 wufc = adapter->wol; |
2457 | int retval = 0; | ||
2458 | 2459 | ||
2459 | atl1c_disable_l0s_l1(hw); | 2460 | atl1c_disable_l0s_l1(hw); |
2460 | if (netif_running(netdev)) { | 2461 | if (netif_running(netdev)) { |
@@ -2462,9 +2463,6 @@ static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2462 | atl1c_down(adapter); | 2463 | atl1c_down(adapter); |
2463 | } | 2464 | } |
2464 | netif_device_detach(netdev); | 2465 | netif_device_detach(netdev); |
2465 | retval = pci_save_state(pdev); | ||
2466 | if (retval) | ||
2467 | return retval; | ||
2468 | 2466 | ||
2469 | if (wufc) | 2467 | if (wufc) |
2470 | if (atl1c_phy_power_saving(hw) != 0) | 2468 | if (atl1c_phy_power_saving(hw) != 0) |
@@ -2525,12 +2523,8 @@ static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2525 | AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl_data); | 2523 | AT_WRITE_REG(hw, REG_WOL_CTRL, wol_ctrl_data); |
2526 | AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data); | 2524 | AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data); |
2527 | 2525 | ||
2528 | /* pcie patch */ | ||
2529 | device_set_wakeup_enable(&pdev->dev, 1); | ||
2530 | |||
2531 | AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT | | 2526 | AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_DEFAULT | |
2532 | GPHY_CTRL_EXT_RESET); | 2527 | GPHY_CTRL_EXT_RESET); |
2533 | pci_prepare_to_sleep(pdev); | ||
2534 | } else { | 2528 | } else { |
2535 | AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_POWER_SAVING); | 2529 | AT_WRITE_REG(hw, REG_GPHY_CTRL, GPHY_CTRL_POWER_SAVING); |
2536 | master_ctrl_data |= MASTER_CTRL_CLK_SEL_DIS; | 2530 | master_ctrl_data |= MASTER_CTRL_CLK_SEL_DIS; |
@@ -2540,25 +2534,17 @@ static int atl1c_suspend(struct pci_dev *pdev, pm_message_t state) | |||
2540 | AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data); | 2534 | AT_WRITE_REG(hw, REG_MAC_CTRL, mac_ctrl_data); |
2541 | AT_WRITE_REG(hw, REG_WOL_CTRL, 0); | 2535 | AT_WRITE_REG(hw, REG_WOL_CTRL, 0); |
2542 | hw->phy_configured = false; /* re-init PHY when resume */ | 2536 | hw->phy_configured = false; /* re-init PHY when resume */ |
2543 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 0); | ||
2544 | } | 2537 | } |
2545 | 2538 | ||
2546 | pci_disable_device(pdev); | ||
2547 | pci_set_power_state(pdev, pci_choose_state(pdev, state)); | ||
2548 | |||
2549 | return 0; | 2539 | return 0; |
2550 | } | 2540 | } |
2551 | 2541 | ||
2552 | static int atl1c_resume(struct pci_dev *pdev) | 2542 | static int atl1c_resume(struct device *dev) |
2553 | { | 2543 | { |
2544 | struct pci_dev *pdev = to_pci_dev(dev); | ||
2554 | struct net_device *netdev = pci_get_drvdata(pdev); | 2545 | struct net_device *netdev = pci_get_drvdata(pdev); |
2555 | struct atl1c_adapter *adapter = netdev_priv(netdev); | 2546 | struct atl1c_adapter *adapter = netdev_priv(netdev); |
2556 | 2547 | ||
2557 | pci_set_power_state(pdev, PCI_D0); | ||
2558 | pci_restore_state(pdev); | ||
2559 | pci_enable_wake(pdev, PCI_D3hot, 0); | ||
2560 | pci_enable_wake(pdev, PCI_D3cold, 0); | ||
2561 | |||
2562 | AT_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0); | 2548 | AT_WRITE_REG(&adapter->hw, REG_WOL_CTRL, 0); |
2563 | atl1c_reset_pcie(&adapter->hw, ATL1C_PCIE_L0S_L1_DISABLE | | 2549 | atl1c_reset_pcie(&adapter->hw, ATL1C_PCIE_L0S_L1_DISABLE | |
2564 | ATL1C_PCIE_PHY_RESET); | 2550 | ATL1C_PCIE_PHY_RESET); |
@@ -2582,7 +2568,12 @@ static int atl1c_resume(struct pci_dev *pdev) | |||
2582 | 2568 | ||
2583 | static void atl1c_shutdown(struct pci_dev *pdev) | 2569 | static void atl1c_shutdown(struct pci_dev *pdev) |
2584 | { | 2570 | { |
2585 | atl1c_suspend(pdev, PMSG_SUSPEND); | 2571 | struct net_device *netdev = pci_get_drvdata(pdev); |
2572 | struct atl1c_adapter *adapter = netdev_priv(netdev); | ||
2573 | |||
2574 | atl1c_suspend(&pdev->dev); | ||
2575 | pci_wake_from_d3(pdev, adapter->wol); | ||
2576 | pci_set_power_state(pdev, PCI_D3hot); | ||
2586 | } | 2577 | } |
2587 | 2578 | ||
2588 | static const struct net_device_ops atl1c_netdev_ops = { | 2579 | static const struct net_device_ops atl1c_netdev_ops = { |
@@ -2886,16 +2877,16 @@ static struct pci_error_handlers atl1c_err_handler = { | |||
2886 | .resume = atl1c_io_resume, | 2877 | .resume = atl1c_io_resume, |
2887 | }; | 2878 | }; |
2888 | 2879 | ||
2880 | static SIMPLE_DEV_PM_OPS(atl1c_pm_ops, atl1c_suspend, atl1c_resume); | ||
2881 | |||
2889 | static struct pci_driver atl1c_driver = { | 2882 | static struct pci_driver atl1c_driver = { |
2890 | .name = atl1c_driver_name, | 2883 | .name = atl1c_driver_name, |
2891 | .id_table = atl1c_pci_tbl, | 2884 | .id_table = atl1c_pci_tbl, |
2892 | .probe = atl1c_probe, | 2885 | .probe = atl1c_probe, |
2893 | .remove = __devexit_p(atl1c_remove), | 2886 | .remove = __devexit_p(atl1c_remove), |
2894 | /* Power Managment Hooks */ | ||
2895 | .suspend = atl1c_suspend, | ||
2896 | .resume = atl1c_resume, | ||
2897 | .shutdown = atl1c_shutdown, | 2887 | .shutdown = atl1c_shutdown, |
2898 | .err_handler = &atl1c_err_handler | 2888 | .err_handler = &atl1c_err_handler, |
2889 | .driver.pm = &atl1c_pm_ops, | ||
2899 | }; | 2890 | }; |
2900 | 2891 | ||
2901 | /* | 2892 | /* |
diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c index 53363108994e..3acf5123a6ef 100644 --- a/drivers/net/atlx/atl1.c +++ b/drivers/net/atlx/atl1.c | |||
@@ -3504,6 +3504,8 @@ static int atl1_set_ringparam(struct net_device *netdev, | |||
3504 | struct atl1_rfd_ring rfd_old, rfd_new; | 3504 | struct atl1_rfd_ring rfd_old, rfd_new; |
3505 | struct atl1_rrd_ring rrd_old, rrd_new; | 3505 | struct atl1_rrd_ring rrd_old, rrd_new; |
3506 | struct atl1_ring_header rhdr_old, rhdr_new; | 3506 | struct atl1_ring_header rhdr_old, rhdr_new; |
3507 | struct atl1_smb smb; | ||
3508 | struct atl1_cmb cmb; | ||
3507 | int err; | 3509 | int err; |
3508 | 3510 | ||
3509 | tpd_old = adapter->tpd_ring; | 3511 | tpd_old = adapter->tpd_ring; |
@@ -3544,11 +3546,19 @@ static int atl1_set_ringparam(struct net_device *netdev, | |||
3544 | adapter->rrd_ring = rrd_old; | 3546 | adapter->rrd_ring = rrd_old; |
3545 | adapter->tpd_ring = tpd_old; | 3547 | adapter->tpd_ring = tpd_old; |
3546 | adapter->ring_header = rhdr_old; | 3548 | adapter->ring_header = rhdr_old; |
3549 | /* | ||
3550 | * Save SMB and CMB, since atl1_free_ring_resources | ||
3551 | * will clear them. | ||
3552 | */ | ||
3553 | smb = adapter->smb; | ||
3554 | cmb = adapter->cmb; | ||
3547 | atl1_free_ring_resources(adapter); | 3555 | atl1_free_ring_resources(adapter); |
3548 | adapter->rfd_ring = rfd_new; | 3556 | adapter->rfd_ring = rfd_new; |
3549 | adapter->rrd_ring = rrd_new; | 3557 | adapter->rrd_ring = rrd_new; |
3550 | adapter->tpd_ring = tpd_new; | 3558 | adapter->tpd_ring = tpd_new; |
3551 | adapter->ring_header = rhdr_new; | 3559 | adapter->ring_header = rhdr_new; |
3560 | adapter->smb = smb; | ||
3561 | adapter->cmb = cmb; | ||
3552 | 3562 | ||
3553 | err = atl1_up(adapter); | 3563 | err = atl1_up(adapter); |
3554 | if (err) | 3564 | if (err) |
diff --git a/drivers/net/b44.c b/drivers/net/b44.c index c6e86315b3f8..2e2b76258ab4 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c | |||
@@ -381,11 +381,11 @@ static void b44_set_flow_ctrl(struct b44 *bp, u32 local, u32 remote) | |||
381 | __b44_set_flow_ctrl(bp, pause_enab); | 381 | __b44_set_flow_ctrl(bp, pause_enab); |
382 | } | 382 | } |
383 | 383 | ||
384 | #ifdef SSB_DRIVER_MIPS | 384 | #ifdef CONFIG_BCM47XX |
385 | extern char *nvram_get(char *name); | 385 | #include <asm/mach-bcm47xx/nvram.h> |
386 | static void b44_wap54g10_workaround(struct b44 *bp) | 386 | static void b44_wap54g10_workaround(struct b44 *bp) |
387 | { | 387 | { |
388 | const char *str; | 388 | char buf[20]; |
389 | u32 val; | 389 | u32 val; |
390 | int err; | 390 | int err; |
391 | 391 | ||
@@ -394,10 +394,9 @@ static void b44_wap54g10_workaround(struct b44 *bp) | |||
394 | * see https://dev.openwrt.org/ticket/146 | 394 | * see https://dev.openwrt.org/ticket/146 |
395 | * check and reset bit "isolate" | 395 | * check and reset bit "isolate" |
396 | */ | 396 | */ |
397 | str = nvram_get("boardnum"); | 397 | if (nvram_getenv("boardnum", buf, sizeof(buf)) < 0) |
398 | if (!str) | ||
399 | return; | 398 | return; |
400 | if (simple_strtoul(str, NULL, 0) == 2) { | 399 | if (simple_strtoul(buf, NULL, 0) == 2) { |
401 | err = __b44_readphy(bp, 0, MII_BMCR, &val); | 400 | err = __b44_readphy(bp, 0, MII_BMCR, &val); |
402 | if (err) | 401 | if (err) |
403 | goto error; | 402 | goto error; |
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 4594a28b1f66..d64313b7090e 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h | |||
@@ -234,7 +234,7 @@ struct be_adapter { | |||
234 | u8 __iomem *db; /* Door Bell */ | 234 | u8 __iomem *db; /* Door Bell */ |
235 | u8 __iomem *pcicfg; /* PCI config space */ | 235 | u8 __iomem *pcicfg; /* PCI config space */ |
236 | 236 | ||
237 | spinlock_t mbox_lock; /* For serializing mbox cmds to BE card */ | 237 | struct mutex mbox_lock; /* For serializing mbox cmds to BE card */ |
238 | struct be_dma_mem mbox_mem; | 238 | struct be_dma_mem mbox_mem; |
239 | /* Mbox mem is adjusted to align to 16 bytes. The allocated addr | 239 | /* Mbox mem is adjusted to align to 16 bytes. The allocated addr |
240 | * is stored for freeing purpose */ | 240 | * is stored for freeing purpose */ |
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index 36eca1ce75d4..1c8c79c9d214 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
@@ -462,7 +462,8 @@ int be_cmd_fw_init(struct be_adapter *adapter) | |||
462 | u8 *wrb; | 462 | u8 *wrb; |
463 | int status; | 463 | int status; |
464 | 464 | ||
465 | spin_lock(&adapter->mbox_lock); | 465 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
466 | return -1; | ||
466 | 467 | ||
467 | wrb = (u8 *)wrb_from_mbox(adapter); | 468 | wrb = (u8 *)wrb_from_mbox(adapter); |
468 | *wrb++ = 0xFF; | 469 | *wrb++ = 0xFF; |
@@ -476,7 +477,7 @@ int be_cmd_fw_init(struct be_adapter *adapter) | |||
476 | 477 | ||
477 | status = be_mbox_notify_wait(adapter); | 478 | status = be_mbox_notify_wait(adapter); |
478 | 479 | ||
479 | spin_unlock(&adapter->mbox_lock); | 480 | mutex_unlock(&adapter->mbox_lock); |
480 | return status; | 481 | return status; |
481 | } | 482 | } |
482 | 483 | ||
@@ -491,7 +492,8 @@ int be_cmd_fw_clean(struct be_adapter *adapter) | |||
491 | if (adapter->eeh_err) | 492 | if (adapter->eeh_err) |
492 | return -EIO; | 493 | return -EIO; |
493 | 494 | ||
494 | spin_lock(&adapter->mbox_lock); | 495 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
496 | return -1; | ||
495 | 497 | ||
496 | wrb = (u8 *)wrb_from_mbox(adapter); | 498 | wrb = (u8 *)wrb_from_mbox(adapter); |
497 | *wrb++ = 0xFF; | 499 | *wrb++ = 0xFF; |
@@ -505,7 +507,7 @@ int be_cmd_fw_clean(struct be_adapter *adapter) | |||
505 | 507 | ||
506 | status = be_mbox_notify_wait(adapter); | 508 | status = be_mbox_notify_wait(adapter); |
507 | 509 | ||
508 | spin_unlock(&adapter->mbox_lock); | 510 | mutex_unlock(&adapter->mbox_lock); |
509 | return status; | 511 | return status; |
510 | } | 512 | } |
511 | int be_cmd_eq_create(struct be_adapter *adapter, | 513 | int be_cmd_eq_create(struct be_adapter *adapter, |
@@ -516,7 +518,8 @@ int be_cmd_eq_create(struct be_adapter *adapter, | |||
516 | struct be_dma_mem *q_mem = &eq->dma_mem; | 518 | struct be_dma_mem *q_mem = &eq->dma_mem; |
517 | int status; | 519 | int status; |
518 | 520 | ||
519 | spin_lock(&adapter->mbox_lock); | 521 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
522 | return -1; | ||
520 | 523 | ||
521 | wrb = wrb_from_mbox(adapter); | 524 | wrb = wrb_from_mbox(adapter); |
522 | req = embedded_payload(wrb); | 525 | req = embedded_payload(wrb); |
@@ -546,7 +549,7 @@ int be_cmd_eq_create(struct be_adapter *adapter, | |||
546 | eq->created = true; | 549 | eq->created = true; |
547 | } | 550 | } |
548 | 551 | ||
549 | spin_unlock(&adapter->mbox_lock); | 552 | mutex_unlock(&adapter->mbox_lock); |
550 | return status; | 553 | return status; |
551 | } | 554 | } |
552 | 555 | ||
@@ -558,7 +561,8 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, | |||
558 | struct be_cmd_req_mac_query *req; | 561 | struct be_cmd_req_mac_query *req; |
559 | int status; | 562 | int status; |
560 | 563 | ||
561 | spin_lock(&adapter->mbox_lock); | 564 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
565 | return -1; | ||
562 | 566 | ||
563 | wrb = wrb_from_mbox(adapter); | 567 | wrb = wrb_from_mbox(adapter); |
564 | req = embedded_payload(wrb); | 568 | req = embedded_payload(wrb); |
@@ -583,7 +587,7 @@ int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, | |||
583 | memcpy(mac_addr, resp->mac.addr, ETH_ALEN); | 587 | memcpy(mac_addr, resp->mac.addr, ETH_ALEN); |
584 | } | 588 | } |
585 | 589 | ||
586 | spin_unlock(&adapter->mbox_lock); | 590 | mutex_unlock(&adapter->mbox_lock); |
587 | return status; | 591 | return status; |
588 | } | 592 | } |
589 | 593 | ||
@@ -667,7 +671,8 @@ int be_cmd_cq_create(struct be_adapter *adapter, | |||
667 | void *ctxt; | 671 | void *ctxt; |
668 | int status; | 672 | int status; |
669 | 673 | ||
670 | spin_lock(&adapter->mbox_lock); | 674 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
675 | return -1; | ||
671 | 676 | ||
672 | wrb = wrb_from_mbox(adapter); | 677 | wrb = wrb_from_mbox(adapter); |
673 | req = embedded_payload(wrb); | 678 | req = embedded_payload(wrb); |
@@ -701,7 +706,7 @@ int be_cmd_cq_create(struct be_adapter *adapter, | |||
701 | cq->created = true; | 706 | cq->created = true; |
702 | } | 707 | } |
703 | 708 | ||
704 | spin_unlock(&adapter->mbox_lock); | 709 | mutex_unlock(&adapter->mbox_lock); |
705 | 710 | ||
706 | return status; | 711 | return status; |
707 | } | 712 | } |
@@ -724,7 +729,8 @@ int be_cmd_mccq_create(struct be_adapter *adapter, | |||
724 | void *ctxt; | 729 | void *ctxt; |
725 | int status; | 730 | int status; |
726 | 731 | ||
727 | spin_lock(&adapter->mbox_lock); | 732 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
733 | return -1; | ||
728 | 734 | ||
729 | wrb = wrb_from_mbox(adapter); | 735 | wrb = wrb_from_mbox(adapter); |
730 | req = embedded_payload(wrb); | 736 | req = embedded_payload(wrb); |
@@ -754,7 +760,7 @@ int be_cmd_mccq_create(struct be_adapter *adapter, | |||
754 | mccq->id = le16_to_cpu(resp->id); | 760 | mccq->id = le16_to_cpu(resp->id); |
755 | mccq->created = true; | 761 | mccq->created = true; |
756 | } | 762 | } |
757 | spin_unlock(&adapter->mbox_lock); | 763 | mutex_unlock(&adapter->mbox_lock); |
758 | 764 | ||
759 | return status; | 765 | return status; |
760 | } | 766 | } |
@@ -769,7 +775,8 @@ int be_cmd_txq_create(struct be_adapter *adapter, | |||
769 | void *ctxt; | 775 | void *ctxt; |
770 | int status; | 776 | int status; |
771 | 777 | ||
772 | spin_lock(&adapter->mbox_lock); | 778 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
779 | return -1; | ||
773 | 780 | ||
774 | wrb = wrb_from_mbox(adapter); | 781 | wrb = wrb_from_mbox(adapter); |
775 | req = embedded_payload(wrb); | 782 | req = embedded_payload(wrb); |
@@ -801,7 +808,7 @@ int be_cmd_txq_create(struct be_adapter *adapter, | |||
801 | txq->created = true; | 808 | txq->created = true; |
802 | } | 809 | } |
803 | 810 | ||
804 | spin_unlock(&adapter->mbox_lock); | 811 | mutex_unlock(&adapter->mbox_lock); |
805 | 812 | ||
806 | return status; | 813 | return status; |
807 | } | 814 | } |
@@ -816,7 +823,8 @@ int be_cmd_rxq_create(struct be_adapter *adapter, | |||
816 | struct be_dma_mem *q_mem = &rxq->dma_mem; | 823 | struct be_dma_mem *q_mem = &rxq->dma_mem; |
817 | int status; | 824 | int status; |
818 | 825 | ||
819 | spin_lock(&adapter->mbox_lock); | 826 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
827 | return -1; | ||
820 | 828 | ||
821 | wrb = wrb_from_mbox(adapter); | 829 | wrb = wrb_from_mbox(adapter); |
822 | req = embedded_payload(wrb); | 830 | req = embedded_payload(wrb); |
@@ -843,7 +851,7 @@ int be_cmd_rxq_create(struct be_adapter *adapter, | |||
843 | *rss_id = resp->rss_id; | 851 | *rss_id = resp->rss_id; |
844 | } | 852 | } |
845 | 853 | ||
846 | spin_unlock(&adapter->mbox_lock); | 854 | mutex_unlock(&adapter->mbox_lock); |
847 | 855 | ||
848 | return status; | 856 | return status; |
849 | } | 857 | } |
@@ -862,7 +870,8 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, | |||
862 | if (adapter->eeh_err) | 870 | if (adapter->eeh_err) |
863 | return -EIO; | 871 | return -EIO; |
864 | 872 | ||
865 | spin_lock(&adapter->mbox_lock); | 873 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
874 | return -1; | ||
866 | 875 | ||
867 | wrb = wrb_from_mbox(adapter); | 876 | wrb = wrb_from_mbox(adapter); |
868 | req = embedded_payload(wrb); | 877 | req = embedded_payload(wrb); |
@@ -899,7 +908,7 @@ int be_cmd_q_destroy(struct be_adapter *adapter, struct be_queue_info *q, | |||
899 | 908 | ||
900 | status = be_mbox_notify_wait(adapter); | 909 | status = be_mbox_notify_wait(adapter); |
901 | 910 | ||
902 | spin_unlock(&adapter->mbox_lock); | 911 | mutex_unlock(&adapter->mbox_lock); |
903 | 912 | ||
904 | return status; | 913 | return status; |
905 | } | 914 | } |
@@ -915,7 +924,8 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, | |||
915 | struct be_cmd_req_if_create *req; | 924 | struct be_cmd_req_if_create *req; |
916 | int status; | 925 | int status; |
917 | 926 | ||
918 | spin_lock(&adapter->mbox_lock); | 927 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
928 | return -1; | ||
919 | 929 | ||
920 | wrb = wrb_from_mbox(adapter); | 930 | wrb = wrb_from_mbox(adapter); |
921 | req = embedded_payload(wrb); | 931 | req = embedded_payload(wrb); |
@@ -941,7 +951,7 @@ int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags, u32 en_flags, | |||
941 | *pmac_id = le32_to_cpu(resp->pmac_id); | 951 | *pmac_id = le32_to_cpu(resp->pmac_id); |
942 | } | 952 | } |
943 | 953 | ||
944 | spin_unlock(&adapter->mbox_lock); | 954 | mutex_unlock(&adapter->mbox_lock); |
945 | return status; | 955 | return status; |
946 | } | 956 | } |
947 | 957 | ||
@@ -955,7 +965,8 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id) | |||
955 | if (adapter->eeh_err) | 965 | if (adapter->eeh_err) |
956 | return -EIO; | 966 | return -EIO; |
957 | 967 | ||
958 | spin_lock(&adapter->mbox_lock); | 968 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
969 | return -1; | ||
959 | 970 | ||
960 | wrb = wrb_from_mbox(adapter); | 971 | wrb = wrb_from_mbox(adapter); |
961 | req = embedded_payload(wrb); | 972 | req = embedded_payload(wrb); |
@@ -970,7 +981,7 @@ int be_cmd_if_destroy(struct be_adapter *adapter, u32 interface_id) | |||
970 | 981 | ||
971 | status = be_mbox_notify_wait(adapter); | 982 | status = be_mbox_notify_wait(adapter); |
972 | 983 | ||
973 | spin_unlock(&adapter->mbox_lock); | 984 | mutex_unlock(&adapter->mbox_lock); |
974 | 985 | ||
975 | return status; | 986 | return status; |
976 | } | 987 | } |
@@ -1060,7 +1071,8 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver) | |||
1060 | struct be_cmd_req_get_fw_version *req; | 1071 | struct be_cmd_req_get_fw_version *req; |
1061 | int status; | 1072 | int status; |
1062 | 1073 | ||
1063 | spin_lock(&adapter->mbox_lock); | 1074 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
1075 | return -1; | ||
1064 | 1076 | ||
1065 | wrb = wrb_from_mbox(adapter); | 1077 | wrb = wrb_from_mbox(adapter); |
1066 | req = embedded_payload(wrb); | 1078 | req = embedded_payload(wrb); |
@@ -1077,7 +1089,7 @@ int be_cmd_get_fw_ver(struct be_adapter *adapter, char *fw_ver) | |||
1077 | strncpy(fw_ver, resp->firmware_version_string, FW_VER_LEN); | 1089 | strncpy(fw_ver, resp->firmware_version_string, FW_VER_LEN); |
1078 | } | 1090 | } |
1079 | 1091 | ||
1080 | spin_unlock(&adapter->mbox_lock); | 1092 | mutex_unlock(&adapter->mbox_lock); |
1081 | return status; | 1093 | return status; |
1082 | } | 1094 | } |
1083 | 1095 | ||
@@ -1235,7 +1247,7 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, | |||
1235 | 1247 | ||
1236 | i = 0; | 1248 | i = 0; |
1237 | netdev_for_each_mc_addr(ha, netdev) | 1249 | netdev_for_each_mc_addr(ha, netdev) |
1238 | memcpy(req->mac[i].byte, ha->addr, ETH_ALEN); | 1250 | memcpy(req->mac[i++].byte, ha->addr, ETH_ALEN); |
1239 | } else { | 1251 | } else { |
1240 | req->promiscuous = 1; | 1252 | req->promiscuous = 1; |
1241 | } | 1253 | } |
@@ -1322,7 +1334,8 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, | |||
1322 | struct be_cmd_req_query_fw_cfg *req; | 1334 | struct be_cmd_req_query_fw_cfg *req; |
1323 | int status; | 1335 | int status; |
1324 | 1336 | ||
1325 | spin_lock(&adapter->mbox_lock); | 1337 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
1338 | return -1; | ||
1326 | 1339 | ||
1327 | wrb = wrb_from_mbox(adapter); | 1340 | wrb = wrb_from_mbox(adapter); |
1328 | req = embedded_payload(wrb); | 1341 | req = embedded_payload(wrb); |
@@ -1341,7 +1354,7 @@ int be_cmd_query_fw_cfg(struct be_adapter *adapter, u32 *port_num, | |||
1341 | *caps = le32_to_cpu(resp->function_caps); | 1354 | *caps = le32_to_cpu(resp->function_caps); |
1342 | } | 1355 | } |
1343 | 1356 | ||
1344 | spin_unlock(&adapter->mbox_lock); | 1357 | mutex_unlock(&adapter->mbox_lock); |
1345 | return status; | 1358 | return status; |
1346 | } | 1359 | } |
1347 | 1360 | ||
@@ -1352,7 +1365,8 @@ int be_cmd_reset_function(struct be_adapter *adapter) | |||
1352 | struct be_cmd_req_hdr *req; | 1365 | struct be_cmd_req_hdr *req; |
1353 | int status; | 1366 | int status; |
1354 | 1367 | ||
1355 | spin_lock(&adapter->mbox_lock); | 1368 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
1369 | return -1; | ||
1356 | 1370 | ||
1357 | wrb = wrb_from_mbox(adapter); | 1371 | wrb = wrb_from_mbox(adapter); |
1358 | req = embedded_payload(wrb); | 1372 | req = embedded_payload(wrb); |
@@ -1365,7 +1379,7 @@ int be_cmd_reset_function(struct be_adapter *adapter) | |||
1365 | 1379 | ||
1366 | status = be_mbox_notify_wait(adapter); | 1380 | status = be_mbox_notify_wait(adapter); |
1367 | 1381 | ||
1368 | spin_unlock(&adapter->mbox_lock); | 1382 | mutex_unlock(&adapter->mbox_lock); |
1369 | return status; | 1383 | return status; |
1370 | } | 1384 | } |
1371 | 1385 | ||
@@ -1376,7 +1390,8 @@ int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, u16 table_size) | |||
1376 | u32 myhash[10]; | 1390 | u32 myhash[10]; |
1377 | int status; | 1391 | int status; |
1378 | 1392 | ||
1379 | spin_lock(&adapter->mbox_lock); | 1393 | if (mutex_lock_interruptible(&adapter->mbox_lock)) |
1394 | return -1; | ||
1380 | 1395 | ||
1381 | wrb = wrb_from_mbox(adapter); | 1396 | wrb = wrb_from_mbox(adapter); |
1382 | req = embedded_payload(wrb); | 1397 | req = embedded_payload(wrb); |
@@ -1396,7 +1411,7 @@ int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable, u16 table_size) | |||
1396 | 1411 | ||
1397 | status = be_mbox_notify_wait(adapter); | 1412 | status = be_mbox_notify_wait(adapter); |
1398 | 1413 | ||
1399 | spin_unlock(&adapter->mbox_lock); | 1414 | mutex_unlock(&adapter->mbox_lock); |
1400 | return status; | 1415 | return status; |
1401 | } | 1416 | } |
1402 | 1417 | ||
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 93354eee2cfd..fd251b59b7f9 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
@@ -2677,7 +2677,7 @@ static int be_ctrl_init(struct be_adapter *adapter) | |||
2677 | } | 2677 | } |
2678 | memset(mc_cmd_mem->va, 0, mc_cmd_mem->size); | 2678 | memset(mc_cmd_mem->va, 0, mc_cmd_mem->size); |
2679 | 2679 | ||
2680 | spin_lock_init(&adapter->mbox_lock); | 2680 | mutex_init(&adapter->mbox_lock); |
2681 | spin_lock_init(&adapter->mcc_lock); | 2681 | spin_lock_init(&adapter->mcc_lock); |
2682 | spin_lock_init(&adapter->mcc_cq_lock); | 2682 | spin_lock_init(&adapter->mcc_cq_lock); |
2683 | 2683 | ||
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h index 863e73a85fbe..d255428122fc 100644 --- a/drivers/net/bnx2x/bnx2x.h +++ b/drivers/net/bnx2x/bnx2x.h | |||
@@ -20,8 +20,8 @@ | |||
20 | * (you will need to reboot afterwards) */ | 20 | * (you will need to reboot afterwards) */ |
21 | /* #define BNX2X_STOP_ON_ERROR */ | 21 | /* #define BNX2X_STOP_ON_ERROR */ |
22 | 22 | ||
23 | #define DRV_MODULE_VERSION "1.60.00-4" | 23 | #define DRV_MODULE_VERSION "1.60.01-0" |
24 | #define DRV_MODULE_RELDATE "2010/11/01" | 24 | #define DRV_MODULE_RELDATE "2010/11/12" |
25 | #define BNX2X_BC_VER 0x040200 | 25 | #define BNX2X_BC_VER 0x040200 |
26 | 26 | ||
27 | #define BNX2X_MULTI_QUEUE | 27 | #define BNX2X_MULTI_QUEUE |
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c b/drivers/net/bnx2x/bnx2x_cmn.c index 94d5f59d5a6f..0af361e4e3d1 100644 --- a/drivers/net/bnx2x/bnx2x_cmn.c +++ b/drivers/net/bnx2x/bnx2x_cmn.c | |||
@@ -1782,15 +1782,15 @@ exit_lbl: | |||
1782 | } | 1782 | } |
1783 | #endif | 1783 | #endif |
1784 | 1784 | ||
1785 | static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, | 1785 | static inline void bnx2x_set_pbd_gso_e2(struct sk_buff *skb, u32 *parsing_data, |
1786 | struct eth_tx_parse_bd_e2 *pbd, | 1786 | u32 xmit_type) |
1787 | u32 xmit_type) | ||
1788 | { | 1787 | { |
1789 | pbd->parsing_data |= cpu_to_le16(skb_shinfo(skb)->gso_size) << | 1788 | *parsing_data |= (skb_shinfo(skb)->gso_size << |
1790 | ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT; | 1789 | ETH_TX_PARSE_BD_E2_LSO_MSS_SHIFT) & |
1790 | ETH_TX_PARSE_BD_E2_LSO_MSS; | ||
1791 | if ((xmit_type & XMIT_GSO_V6) && | 1791 | if ((xmit_type & XMIT_GSO_V6) && |
1792 | (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPV6)) | 1792 | (ipv6_hdr(skb)->nexthdr == NEXTHDR_IPV6)) |
1793 | pbd->parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR; | 1793 | *parsing_data |= ETH_TX_PARSE_BD_E2_IPV6_WITH_EXT_HDR; |
1794 | } | 1794 | } |
1795 | 1795 | ||
1796 | /** | 1796 | /** |
@@ -1835,15 +1835,15 @@ static inline void bnx2x_set_pbd_gso(struct sk_buff *skb, | |||
1835 | * @return header len | 1835 | * @return header len |
1836 | */ | 1836 | */ |
1837 | static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb, | 1837 | static inline u8 bnx2x_set_pbd_csum_e2(struct bnx2x *bp, struct sk_buff *skb, |
1838 | struct eth_tx_parse_bd_e2 *pbd, | 1838 | u32 *parsing_data, u32 xmit_type) |
1839 | u32 xmit_type) | ||
1840 | { | 1839 | { |
1841 | pbd->parsing_data |= cpu_to_le16(tcp_hdrlen(skb)/4) << | 1840 | *parsing_data |= ((tcp_hdrlen(skb)/4) << |
1842 | ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT; | 1841 | ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW_SHIFT) & |
1842 | ETH_TX_PARSE_BD_E2_TCP_HDR_LENGTH_DW; | ||
1843 | 1843 | ||
1844 | pbd->parsing_data |= cpu_to_le16(((unsigned char *)tcp_hdr(skb) - | 1844 | *parsing_data |= ((((u8 *)tcp_hdr(skb) - skb->data) / 2) << |
1845 | skb->data) / 2) << | 1845 | ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT) & |
1846 | ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W_SHIFT; | 1846 | ETH_TX_PARSE_BD_E2_TCP_HDR_START_OFFSET_W; |
1847 | 1847 | ||
1848 | return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data; | 1848 | return skb_transport_header(skb) + tcp_hdrlen(skb) - skb->data; |
1849 | } | 1849 | } |
@@ -1912,6 +1912,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1912 | struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL; | 1912 | struct eth_tx_bd *tx_data_bd, *total_pkt_bd = NULL; |
1913 | struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; | 1913 | struct eth_tx_parse_bd_e1x *pbd_e1x = NULL; |
1914 | struct eth_tx_parse_bd_e2 *pbd_e2 = NULL; | 1914 | struct eth_tx_parse_bd_e2 *pbd_e2 = NULL; |
1915 | u32 pbd_e2_parsing_data = 0; | ||
1915 | u16 pkt_prod, bd_prod; | 1916 | u16 pkt_prod, bd_prod; |
1916 | int nbd, fp_index; | 1917 | int nbd, fp_index; |
1917 | dma_addr_t mapping; | 1918 | dma_addr_t mapping; |
@@ -2033,8 +2034,9 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2033 | memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2)); | 2034 | memset(pbd_e2, 0, sizeof(struct eth_tx_parse_bd_e2)); |
2034 | /* Set PBD in checksum offload case */ | 2035 | /* Set PBD in checksum offload case */ |
2035 | if (xmit_type & XMIT_CSUM) | 2036 | if (xmit_type & XMIT_CSUM) |
2036 | hlen = bnx2x_set_pbd_csum_e2(bp, | 2037 | hlen = bnx2x_set_pbd_csum_e2(bp, skb, |
2037 | skb, pbd_e2, xmit_type); | 2038 | &pbd_e2_parsing_data, |
2039 | xmit_type); | ||
2038 | } else { | 2040 | } else { |
2039 | pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x; | 2041 | pbd_e1x = &fp->tx_desc_ring[bd_prod].parse_bd_e1x; |
2040 | memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); | 2042 | memset(pbd_e1x, 0, sizeof(struct eth_tx_parse_bd_e1x)); |
@@ -2076,10 +2078,18 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2076 | bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd, | 2078 | bd_prod = bnx2x_tx_split(bp, fp, tx_buf, &tx_start_bd, |
2077 | hlen, bd_prod, ++nbd); | 2079 | hlen, bd_prod, ++nbd); |
2078 | if (CHIP_IS_E2(bp)) | 2080 | if (CHIP_IS_E2(bp)) |
2079 | bnx2x_set_pbd_gso_e2(skb, pbd_e2, xmit_type); | 2081 | bnx2x_set_pbd_gso_e2(skb, &pbd_e2_parsing_data, |
2082 | xmit_type); | ||
2080 | else | 2083 | else |
2081 | bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type); | 2084 | bnx2x_set_pbd_gso(skb, pbd_e1x, xmit_type); |
2082 | } | 2085 | } |
2086 | |||
2087 | /* Set the PBD's parsing_data field if not zero | ||
2088 | * (for the chips newer than 57711). | ||
2089 | */ | ||
2090 | if (pbd_e2_parsing_data) | ||
2091 | pbd_e2->parsing_data = cpu_to_le32(pbd_e2_parsing_data); | ||
2092 | |||
2083 | tx_data_bd = (struct eth_tx_bd *)tx_start_bd; | 2093 | tx_data_bd = (struct eth_tx_bd *)tx_start_bd; |
2084 | 2094 | ||
2085 | /* Handle fragmented skb */ | 2095 | /* Handle fragmented skb */ |
diff --git a/drivers/net/bnx2x/bnx2x_init_ops.h b/drivers/net/bnx2x/bnx2x_init_ops.h index a306b0e46b61..66df29fcf751 100644 --- a/drivers/net/bnx2x/bnx2x_init_ops.h +++ b/drivers/net/bnx2x/bnx2x_init_ops.h | |||
@@ -838,7 +838,7 @@ static void bnx2x_qm_init_ptr_table(struct bnx2x *bp, int qm_cid_count, | |||
838 | /**************************************************************************** | 838 | /**************************************************************************** |
839 | * SRC initializations | 839 | * SRC initializations |
840 | ****************************************************************************/ | 840 | ****************************************************************************/ |
841 | 841 | #ifdef BCM_CNIC | |
842 | /* called during init func stage */ | 842 | /* called during init func stage */ |
843 | static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2, | 843 | static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2, |
844 | dma_addr_t t2_mapping, int src_cid_count) | 844 | dma_addr_t t2_mapping, int src_cid_count) |
@@ -862,5 +862,5 @@ static void bnx2x_src_init_t2(struct bnx2x *bp, struct src_ent *t2, | |||
862 | U64_HI((u64)t2_mapping + | 862 | U64_HI((u64)t2_mapping + |
863 | (src_cid_count-1) * sizeof(struct src_ent))); | 863 | (src_cid_count-1) * sizeof(struct src_ent))); |
864 | } | 864 | } |
865 | 865 | #endif | |
866 | #endif /* BNX2X_INIT_OPS_H */ | 866 | #endif /* BNX2X_INIT_OPS_H */ |
diff --git a/drivers/net/bonding/bond_ipv6.c b/drivers/net/bonding/bond_ipv6.c index 121b073a6c3f..84fbd4ebd778 100644 --- a/drivers/net/bonding/bond_ipv6.c +++ b/drivers/net/bonding/bond_ipv6.c | |||
@@ -88,7 +88,12 @@ static void bond_na_send(struct net_device *slave_dev, | |||
88 | } | 88 | } |
89 | 89 | ||
90 | if (vlan_id) { | 90 | if (vlan_id) { |
91 | skb = vlan_put_tag(skb, vlan_id); | 91 | /* The Ethernet header is not present yet, so it is |
92 | * too early to insert a VLAN tag. Force use of an | ||
93 | * out-of-line tag here and let dev_hard_start_xmit() | ||
94 | * insert it if the slave hardware can't. | ||
95 | */ | ||
96 | skb = __vlan_hwaccel_put_tag(skb, vlan_id); | ||
92 | if (!skb) { | 97 | if (!skb) { |
93 | pr_err("failed to insert VLAN tag\n"); | 98 | pr_err("failed to insert VLAN tag\n"); |
94 | return; | 99 | return; |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 71a169740d05..3b16c34ed86e 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -171,7 +171,7 @@ MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on link | |||
171 | /*----------------------------- Global variables ----------------------------*/ | 171 | /*----------------------------- Global variables ----------------------------*/ |
172 | 172 | ||
173 | #ifdef CONFIG_NET_POLL_CONTROLLER | 173 | #ifdef CONFIG_NET_POLL_CONTROLLER |
174 | cpumask_var_t netpoll_block_tx; | 174 | atomic_t netpoll_block_tx = ATOMIC_INIT(0); |
175 | #endif | 175 | #endif |
176 | 176 | ||
177 | static const char * const version = | 177 | static const char * const version = |
@@ -418,36 +418,11 @@ struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr) | |||
418 | * @bond: bond device that got this skb for tx. | 418 | * @bond: bond device that got this skb for tx. |
419 | * @skb: hw accel VLAN tagged skb to transmit | 419 | * @skb: hw accel VLAN tagged skb to transmit |
420 | * @slave_dev: slave that is supposed to xmit this skbuff | 420 | * @slave_dev: slave that is supposed to xmit this skbuff |
421 | * | ||
422 | * When the bond gets an skb to transmit that is | ||
423 | * already hardware accelerated VLAN tagged, and it | ||
424 | * needs to relay this skb to a slave that is not | ||
425 | * hw accel capable, the skb needs to be "unaccelerated", | ||
426 | * i.e. strip the hwaccel tag and re-insert it as part | ||
427 | * of the payload. | ||
428 | */ | 421 | */ |
429 | int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, | 422 | int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, |
430 | struct net_device *slave_dev) | 423 | struct net_device *slave_dev) |
431 | { | 424 | { |
432 | unsigned short uninitialized_var(vlan_id); | 425 | skb->dev = slave_dev; |
433 | |||
434 | /* Test vlan_list not vlgrp to catch and handle 802.1p tags */ | ||
435 | if (!list_empty(&bond->vlan_list) && | ||
436 | !(slave_dev->features & NETIF_F_HW_VLAN_TX) && | ||
437 | vlan_get_tag(skb, &vlan_id) == 0) { | ||
438 | skb->dev = slave_dev; | ||
439 | skb = vlan_put_tag(skb, vlan_id); | ||
440 | if (!skb) { | ||
441 | /* vlan_put_tag() frees the skb in case of error, | ||
442 | * so return success here so the calling functions | ||
443 | * won't attempt to free is again. | ||
444 | */ | ||
445 | return 0; | ||
446 | } | ||
447 | } else { | ||
448 | skb->dev = slave_dev; | ||
449 | } | ||
450 | |||
451 | skb->priority = 1; | 426 | skb->priority = 1; |
452 | #ifdef CONFIG_NET_POLL_CONTROLLER | 427 | #ifdef CONFIG_NET_POLL_CONTROLLER |
453 | if (unlikely(bond->dev->priv_flags & IFF_IN_NETPOLL)) { | 428 | if (unlikely(bond->dev->priv_flags & IFF_IN_NETPOLL)) { |
@@ -1203,11 +1178,13 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) | |||
1203 | bond_do_fail_over_mac(bond, new_active, | 1178 | bond_do_fail_over_mac(bond, new_active, |
1204 | old_active); | 1179 | old_active); |
1205 | 1180 | ||
1206 | bond->send_grat_arp = bond->params.num_grat_arp; | 1181 | if (netif_running(bond->dev)) { |
1207 | bond_send_gratuitous_arp(bond); | 1182 | bond->send_grat_arp = bond->params.num_grat_arp; |
1183 | bond_send_gratuitous_arp(bond); | ||
1208 | 1184 | ||
1209 | bond->send_unsol_na = bond->params.num_unsol_na; | 1185 | bond->send_unsol_na = bond->params.num_unsol_na; |
1210 | bond_send_unsolicited_na(bond); | 1186 | bond_send_unsolicited_na(bond); |
1187 | } | ||
1211 | 1188 | ||
1212 | write_unlock_bh(&bond->curr_slave_lock); | 1189 | write_unlock_bh(&bond->curr_slave_lock); |
1213 | read_unlock(&bond->lock); | 1190 | read_unlock(&bond->lock); |
@@ -1221,8 +1198,9 @@ void bond_change_active_slave(struct bonding *bond, struct slave *new_active) | |||
1221 | 1198 | ||
1222 | /* resend IGMP joins since active slave has changed or | 1199 | /* resend IGMP joins since active slave has changed or |
1223 | * all were sent on curr_active_slave */ | 1200 | * all were sent on curr_active_slave */ |
1224 | if ((USES_PRIMARY(bond->params.mode) && new_active) || | 1201 | if (((USES_PRIMARY(bond->params.mode) && new_active) || |
1225 | bond->params.mode == BOND_MODE_ROUNDROBIN) { | 1202 | bond->params.mode == BOND_MODE_ROUNDROBIN) && |
1203 | netif_running(bond->dev)) { | ||
1226 | bond->igmp_retrans = bond->params.resend_igmp; | 1204 | bond->igmp_retrans = bond->params.resend_igmp; |
1227 | queue_delayed_work(bond->wq, &bond->mcast_work, 0); | 1205 | queue_delayed_work(bond->wq, &bond->mcast_work, 0); |
1228 | } | 1206 | } |
@@ -1576,7 +1554,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | |||
1576 | 1554 | ||
1577 | /* If this is the first slave, then we need to set the master's hardware | 1555 | /* If this is the first slave, then we need to set the master's hardware |
1578 | * address to be the same as the slave's. */ | 1556 | * address to be the same as the slave's. */ |
1579 | if (bond->slave_cnt == 0) | 1557 | if (is_zero_ether_addr(bond->dev->dev_addr)) |
1580 | memcpy(bond->dev->dev_addr, slave_dev->dev_addr, | 1558 | memcpy(bond->dev->dev_addr, slave_dev->dev_addr, |
1581 | slave_dev->addr_len); | 1559 | slave_dev->addr_len); |
1582 | 1560 | ||
@@ -5299,13 +5277,6 @@ static int __init bonding_init(void) | |||
5299 | if (res) | 5277 | if (res) |
5300 | goto out; | 5278 | goto out; |
5301 | 5279 | ||
5302 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
5303 | if (!alloc_cpumask_var(&netpoll_block_tx, GFP_KERNEL)) { | ||
5304 | res = -ENOMEM; | ||
5305 | goto out; | ||
5306 | } | ||
5307 | #endif | ||
5308 | |||
5309 | res = register_pernet_subsys(&bond_net_ops); | 5280 | res = register_pernet_subsys(&bond_net_ops); |
5310 | if (res) | 5281 | if (res) |
5311 | goto out; | 5282 | goto out; |
@@ -5334,9 +5305,6 @@ err: | |||
5334 | rtnl_link_unregister(&bond_link_ops); | 5305 | rtnl_link_unregister(&bond_link_ops); |
5335 | err_link: | 5306 | err_link: |
5336 | unregister_pernet_subsys(&bond_net_ops); | 5307 | unregister_pernet_subsys(&bond_net_ops); |
5337 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
5338 | free_cpumask_var(netpoll_block_tx); | ||
5339 | #endif | ||
5340 | goto out; | 5308 | goto out; |
5341 | 5309 | ||
5342 | } | 5310 | } |
@@ -5353,7 +5321,10 @@ static void __exit bonding_exit(void) | |||
5353 | unregister_pernet_subsys(&bond_net_ops); | 5321 | unregister_pernet_subsys(&bond_net_ops); |
5354 | 5322 | ||
5355 | #ifdef CONFIG_NET_POLL_CONTROLLER | 5323 | #ifdef CONFIG_NET_POLL_CONTROLLER |
5356 | free_cpumask_var(netpoll_block_tx); | 5324 | /* |
5325 | * Make sure we don't have an imbalance on our netpoll blocking | ||
5326 | */ | ||
5327 | WARN_ON(atomic_read(&netpoll_block_tx)); | ||
5357 | #endif | 5328 | #endif |
5358 | } | 5329 | } |
5359 | 5330 | ||
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index 4eedb12df6ca..4feeb2d650a4 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -119,26 +119,22 @@ | |||
119 | 119 | ||
120 | 120 | ||
121 | #ifdef CONFIG_NET_POLL_CONTROLLER | 121 | #ifdef CONFIG_NET_POLL_CONTROLLER |
122 | extern cpumask_var_t netpoll_block_tx; | 122 | extern atomic_t netpoll_block_tx; |
123 | 123 | ||
124 | static inline void block_netpoll_tx(void) | 124 | static inline void block_netpoll_tx(void) |
125 | { | 125 | { |
126 | preempt_disable(); | 126 | atomic_inc(&netpoll_block_tx); |
127 | BUG_ON(cpumask_test_and_set_cpu(smp_processor_id(), | ||
128 | netpoll_block_tx)); | ||
129 | } | 127 | } |
130 | 128 | ||
131 | static inline void unblock_netpoll_tx(void) | 129 | static inline void unblock_netpoll_tx(void) |
132 | { | 130 | { |
133 | BUG_ON(!cpumask_test_and_clear_cpu(smp_processor_id(), | 131 | atomic_dec(&netpoll_block_tx); |
134 | netpoll_block_tx)); | ||
135 | preempt_enable(); | ||
136 | } | 132 | } |
137 | 133 | ||
138 | static inline int is_netpoll_tx_blocked(struct net_device *dev) | 134 | static inline int is_netpoll_tx_blocked(struct net_device *dev) |
139 | { | 135 | { |
140 | if (unlikely(dev->priv_flags & IFF_IN_NETPOLL)) | 136 | if (unlikely(dev->priv_flags & IFF_IN_NETPOLL)) |
141 | return cpumask_test_cpu(smp_processor_id(), netpoll_block_tx); | 137 | return atomic_read(&netpoll_block_tx); |
142 | return 0; | 138 | return 0; |
143 | } | 139 | } |
144 | #else | 140 | #else |
@@ -273,11 +269,11 @@ static inline struct slave *bond_get_slave_by_dev(struct bonding *bond, struct n | |||
273 | 269 | ||
274 | bond_for_each_slave(bond, slave, i) { | 270 | bond_for_each_slave(bond, slave, i) { |
275 | if (slave->dev == slave_dev) { | 271 | if (slave->dev == slave_dev) { |
276 | break; | 272 | return slave; |
277 | } | 273 | } |
278 | } | 274 | } |
279 | 275 | ||
280 | return slave; | 276 | return 0; |
281 | } | 277 | } |
282 | 278 | ||
283 | static inline struct bonding *bond_get_bond_by_slave(struct slave *slave) | 279 | static inline struct bonding *bond_get_bond_by_slave(struct slave *slave) |
diff --git a/drivers/net/caif/caif_shm_u5500.c b/drivers/net/caif/caif_shm_u5500.c index 1cd90da86f13..32b1c6fb2de1 100644 --- a/drivers/net/caif/caif_shm_u5500.c +++ b/drivers/net/caif/caif_shm_u5500.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * License terms: GNU General Public License (GPL) version 2 | 5 | * License terms: GNU General Public License (GPL) version 2 |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #define pr_fmt(fmt) KBUILD_MODNAME ":" __func__ "():" fmt | 8 | #define pr_fmt(fmt) KBUILD_MODNAME ":" fmt |
9 | 9 | ||
10 | #include <linux/version.h> | 10 | #include <linux/version.h> |
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
diff --git a/drivers/net/caif/caif_shmcore.c b/drivers/net/caif/caif_shmcore.c index 19f9c0656667..80511167f35b 100644 --- a/drivers/net/caif/caif_shmcore.c +++ b/drivers/net/caif/caif_shmcore.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * License terms: GNU General Public License (GPL) version 2 | 6 | * License terms: GNU General Public License (GPL) version 2 |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #define pr_fmt(fmt) KBUILD_MODNAME ":" __func__ "():" fmt | 9 | #define pr_fmt(fmt) KBUILD_MODNAME ":" fmt |
10 | 10 | ||
11 | #include <linux/spinlock.h> | 11 | #include <linux/spinlock.h> |
12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
diff --git a/drivers/net/cnic.c b/drivers/net/cnic.c index 92bac19ad60a..6dff32196c92 100644 --- a/drivers/net/cnic.c +++ b/drivers/net/cnic.c | |||
@@ -940,7 +940,7 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages) | |||
940 | &udev->l2_ring_map, | 940 | &udev->l2_ring_map, |
941 | GFP_KERNEL | __GFP_COMP); | 941 | GFP_KERNEL | __GFP_COMP); |
942 | if (!udev->l2_ring) | 942 | if (!udev->l2_ring) |
943 | return -ENOMEM; | 943 | goto err_udev; |
944 | 944 | ||
945 | udev->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size; | 945 | udev->l2_buf_size = (cp->l2_rx_ring_size + 1) * cp->l2_single_buf_size; |
946 | udev->l2_buf_size = PAGE_ALIGN(udev->l2_buf_size); | 946 | udev->l2_buf_size = PAGE_ALIGN(udev->l2_buf_size); |
@@ -948,7 +948,7 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages) | |||
948 | &udev->l2_buf_map, | 948 | &udev->l2_buf_map, |
949 | GFP_KERNEL | __GFP_COMP); | 949 | GFP_KERNEL | __GFP_COMP); |
950 | if (!udev->l2_buf) | 950 | if (!udev->l2_buf) |
951 | return -ENOMEM; | 951 | goto err_dma; |
952 | 952 | ||
953 | write_lock(&cnic_dev_lock); | 953 | write_lock(&cnic_dev_lock); |
954 | list_add(&udev->list, &cnic_udev_list); | 954 | list_add(&udev->list, &cnic_udev_list); |
@@ -959,6 +959,12 @@ static int cnic_alloc_uio_rings(struct cnic_dev *dev, int pages) | |||
959 | cp->udev = udev; | 959 | cp->udev = udev; |
960 | 960 | ||
961 | return 0; | 961 | return 0; |
962 | err_dma: | ||
963 | dma_free_coherent(&udev->pdev->dev, udev->l2_ring_size, | ||
964 | udev->l2_ring, udev->l2_ring_map); | ||
965 | err_udev: | ||
966 | kfree(udev); | ||
967 | return -ENOMEM; | ||
962 | } | 968 | } |
963 | 969 | ||
964 | static int cnic_init_uio(struct cnic_dev *dev) | 970 | static int cnic_init_uio(struct cnic_dev *dev) |
diff --git a/drivers/net/cxgb4/t4_hw.c b/drivers/net/cxgb4/t4_hw.c index bb813d94aea8..e97521c801ea 100644 --- a/drivers/net/cxgb4/t4_hw.c +++ b/drivers/net/cxgb4/t4_hw.c | |||
@@ -2408,7 +2408,7 @@ int t4_alloc_mac_filt(struct adapter *adap, unsigned int mbox, | |||
2408 | if (index < NEXACT_MAC) | 2408 | if (index < NEXACT_MAC) |
2409 | ret++; | 2409 | ret++; |
2410 | else if (hash) | 2410 | else if (hash) |
2411 | *hash |= (1 << hash_mac_addr(addr[i])); | 2411 | *hash |= (1ULL << hash_mac_addr(addr[i])); |
2412 | } | 2412 | } |
2413 | return ret; | 2413 | return ret; |
2414 | } | 2414 | } |
diff --git a/drivers/net/cxgb4vf/cxgb4vf_main.c b/drivers/net/cxgb4vf/cxgb4vf_main.c index d887a76cd39d..6bf464afa90e 100644 --- a/drivers/net/cxgb4vf/cxgb4vf_main.c +++ b/drivers/net/cxgb4vf/cxgb4vf_main.c | |||
@@ -2269,6 +2269,7 @@ static void __devinit cfg_queues(struct adapter *adapter) | |||
2269 | { | 2269 | { |
2270 | struct sge *s = &adapter->sge; | 2270 | struct sge *s = &adapter->sge; |
2271 | int q10g, n10g, qidx, pidx, qs; | 2271 | int q10g, n10g, qidx, pidx, qs; |
2272 | size_t iqe_size; | ||
2272 | 2273 | ||
2273 | /* | 2274 | /* |
2274 | * We should not be called till we know how many Queue Sets we can | 2275 | * We should not be called till we know how many Queue Sets we can |
@@ -2313,6 +2314,13 @@ static void __devinit cfg_queues(struct adapter *adapter) | |||
2313 | s->ethqsets = qidx; | 2314 | s->ethqsets = qidx; |
2314 | 2315 | ||
2315 | /* | 2316 | /* |
2317 | * The Ingress Queue Entry Size for our various Response Queues needs | ||
2318 | * to be big enough to accommodate the largest message we can receive | ||
2319 | * from the chip/firmware; which is 64 bytes ... | ||
2320 | */ | ||
2321 | iqe_size = 64; | ||
2322 | |||
2323 | /* | ||
2316 | * Set up default Queue Set parameters ... Start off with the | 2324 | * Set up default Queue Set parameters ... Start off with the |
2317 | * shortest interrupt holdoff timer. | 2325 | * shortest interrupt holdoff timer. |
2318 | */ | 2326 | */ |
@@ -2320,7 +2328,7 @@ static void __devinit cfg_queues(struct adapter *adapter) | |||
2320 | struct sge_eth_rxq *rxq = &s->ethrxq[qs]; | 2328 | struct sge_eth_rxq *rxq = &s->ethrxq[qs]; |
2321 | struct sge_eth_txq *txq = &s->ethtxq[qs]; | 2329 | struct sge_eth_txq *txq = &s->ethtxq[qs]; |
2322 | 2330 | ||
2323 | init_rspq(&rxq->rspq, 0, 0, 1024, L1_CACHE_BYTES); | 2331 | init_rspq(&rxq->rspq, 0, 0, 1024, iqe_size); |
2324 | rxq->fl.size = 72; | 2332 | rxq->fl.size = 72; |
2325 | txq->q.size = 1024; | 2333 | txq->q.size = 1024; |
2326 | } | 2334 | } |
@@ -2329,8 +2337,7 @@ static void __devinit cfg_queues(struct adapter *adapter) | |||
2329 | * The firmware event queue is used for link state changes and | 2337 | * The firmware event queue is used for link state changes and |
2330 | * notifications of TX DMA completions. | 2338 | * notifications of TX DMA completions. |
2331 | */ | 2339 | */ |
2332 | init_rspq(&s->fw_evtq, SGE_TIMER_RSTRT_CNTR, 0, 512, | 2340 | init_rspq(&s->fw_evtq, SGE_TIMER_RSTRT_CNTR, 0, 512, iqe_size); |
2333 | L1_CACHE_BYTES); | ||
2334 | 2341 | ||
2335 | /* | 2342 | /* |
2336 | * The forwarded interrupt queue is used when we're in MSI interrupt | 2343 | * The forwarded interrupt queue is used when we're in MSI interrupt |
@@ -2346,7 +2353,7 @@ static void __devinit cfg_queues(struct adapter *adapter) | |||
2346 | * any time ... | 2353 | * any time ... |
2347 | */ | 2354 | */ |
2348 | init_rspq(&s->intrq, SGE_TIMER_RSTRT_CNTR, 0, MSIX_ENTRIES + 1, | 2355 | init_rspq(&s->intrq, SGE_TIMER_RSTRT_CNTR, 0, MSIX_ENTRIES + 1, |
2349 | L1_CACHE_BYTES); | 2356 | iqe_size); |
2350 | } | 2357 | } |
2351 | 2358 | ||
2352 | /* | 2359 | /* |
diff --git a/drivers/net/ehea/ehea_ethtool.c b/drivers/net/ehea/ehea_ethtool.c index 75b099ce49c9..d6cf502906cf 100644 --- a/drivers/net/ehea/ehea_ethtool.c +++ b/drivers/net/ehea/ehea_ethtool.c | |||
@@ -261,6 +261,20 @@ static void ehea_get_ethtool_stats(struct net_device *dev, | |||
261 | 261 | ||
262 | } | 262 | } |
263 | 263 | ||
264 | static int ehea_set_flags(struct net_device *dev, u32 data) | ||
265 | { | ||
266 | /* Avoid changing the VLAN flags */ | ||
267 | if ((data & (ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN)) != | ||
268 | (ethtool_op_get_flags(dev) & (ETH_FLAG_RXVLAN | | ||
269 | ETH_FLAG_TXVLAN))){ | ||
270 | return -EINVAL; | ||
271 | } | ||
272 | |||
273 | return ethtool_op_set_flags(dev, data, ETH_FLAG_LRO | ||
274 | | ETH_FLAG_TXVLAN | ||
275 | | ETH_FLAG_RXVLAN); | ||
276 | } | ||
277 | |||
264 | const struct ethtool_ops ehea_ethtool_ops = { | 278 | const struct ethtool_ops ehea_ethtool_ops = { |
265 | .get_settings = ehea_get_settings, | 279 | .get_settings = ehea_get_settings, |
266 | .get_drvinfo = ehea_get_drvinfo, | 280 | .get_drvinfo = ehea_get_drvinfo, |
@@ -273,6 +287,8 @@ const struct ethtool_ops ehea_ethtool_ops = { | |||
273 | .get_ethtool_stats = ehea_get_ethtool_stats, | 287 | .get_ethtool_stats = ehea_get_ethtool_stats, |
274 | .get_rx_csum = ehea_get_rx_csum, | 288 | .get_rx_csum = ehea_get_rx_csum, |
275 | .set_settings = ehea_set_settings, | 289 | .set_settings = ehea_set_settings, |
290 | .get_flags = ethtool_op_get_flags, | ||
291 | .set_flags = ehea_set_flags, | ||
276 | .nway_reset = ehea_nway_reset, /* Restart autonegotiation */ | 292 | .nway_reset = ehea_nway_reset, /* Restart autonegotiation */ |
277 | }; | 293 | }; |
278 | 294 | ||
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 3d0af08483a1..b95f087cd5a9 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c | |||
@@ -683,7 +683,7 @@ static void ehea_proc_skb(struct ehea_port_res *pr, struct ehea_cqe *cqe, | |||
683 | int vlan_extracted = ((cqe->status & EHEA_CQE_VLAN_TAG_XTRACT) && | 683 | int vlan_extracted = ((cqe->status & EHEA_CQE_VLAN_TAG_XTRACT) && |
684 | pr->port->vgrp); | 684 | pr->port->vgrp); |
685 | 685 | ||
686 | if (use_lro) { | 686 | if (skb->dev->features & NETIF_F_LRO) { |
687 | if (vlan_extracted) | 687 | if (vlan_extracted) |
688 | lro_vlan_hwaccel_receive_skb(&pr->lro_mgr, skb, | 688 | lro_vlan_hwaccel_receive_skb(&pr->lro_mgr, skb, |
689 | pr->port->vgrp, | 689 | pr->port->vgrp, |
@@ -787,7 +787,7 @@ static int ehea_proc_rwqes(struct net_device *dev, | |||
787 | } | 787 | } |
788 | cqe = ehea_poll_rq1(qp, &wqe_index); | 788 | cqe = ehea_poll_rq1(qp, &wqe_index); |
789 | } | 789 | } |
790 | if (use_lro) | 790 | if (dev->features & NETIF_F_LRO) |
791 | lro_flush_all(&pr->lro_mgr); | 791 | lro_flush_all(&pr->lro_mgr); |
792 | 792 | ||
793 | pr->rx_packets += processed; | 793 | pr->rx_packets += processed; |
@@ -3278,6 +3278,9 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter, | |||
3278 | | NETIF_F_LLTX; | 3278 | | NETIF_F_LLTX; |
3279 | dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT; | 3279 | dev->watchdog_timeo = EHEA_WATCH_DOG_TIMEOUT; |
3280 | 3280 | ||
3281 | if (use_lro) | ||
3282 | dev->features |= NETIF_F_LRO; | ||
3283 | |||
3281 | INIT_WORK(&port->reset_task, ehea_reset_port); | 3284 | INIT_WORK(&port->reset_task, ehea_reset_port); |
3282 | 3285 | ||
3283 | ret = register_netdev(dev); | 3286 | ret = register_netdev(dev); |
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c index a466ef91dd43..aa28b270c045 100644 --- a/drivers/net/enic/enic_main.c +++ b/drivers/net/enic/enic_main.c | |||
@@ -1962,7 +1962,8 @@ static void enic_poll_controller(struct net_device *netdev) | |||
1962 | case VNIC_DEV_INTR_MODE_MSIX: | 1962 | case VNIC_DEV_INTR_MODE_MSIX: |
1963 | for (i = 0; i < enic->rq_count; i++) { | 1963 | for (i = 0; i < enic->rq_count; i++) { |
1964 | intr = enic_msix_rq_intr(enic, i); | 1964 | intr = enic_msix_rq_intr(enic, i); |
1965 | enic_isr_msix_rq(enic->msix_entry[intr].vector, enic); | 1965 | enic_isr_msix_rq(enic->msix_entry[intr].vector, |
1966 | &enic->napi[i]); | ||
1966 | } | 1967 | } |
1967 | intr = enic_msix_wq_intr(enic, i); | 1968 | intr = enic_msix_wq_intr(enic, i); |
1968 | enic_isr_msix_wq(enic->msix_entry[intr].vector, enic); | 1969 | enic_isr_msix_wq(enic->msix_entry[intr].vector, enic); |
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c index aa56963ad558..c353bf3113cc 100644 --- a/drivers/net/epic100.c +++ b/drivers/net/epic100.c | |||
@@ -935,7 +935,7 @@ static void epic_init_ring(struct net_device *dev) | |||
935 | 935 | ||
936 | /* Fill in the Rx buffers. Handle allocation failure gracefully. */ | 936 | /* Fill in the Rx buffers. Handle allocation failure gracefully. */ |
937 | for (i = 0; i < RX_RING_SIZE; i++) { | 937 | for (i = 0; i < RX_RING_SIZE; i++) { |
938 | struct sk_buff *skb = dev_alloc_skb(ep->rx_buf_sz); | 938 | struct sk_buff *skb = dev_alloc_skb(ep->rx_buf_sz + 2); |
939 | ep->rx_skbuff[i] = skb; | 939 | ep->rx_skbuff[i] = skb; |
940 | if (skb == NULL) | 940 | if (skb == NULL) |
941 | break; | 941 | break; |
@@ -1233,7 +1233,7 @@ static int epic_rx(struct net_device *dev, int budget) | |||
1233 | entry = ep->dirty_rx % RX_RING_SIZE; | 1233 | entry = ep->dirty_rx % RX_RING_SIZE; |
1234 | if (ep->rx_skbuff[entry] == NULL) { | 1234 | if (ep->rx_skbuff[entry] == NULL) { |
1235 | struct sk_buff *skb; | 1235 | struct sk_buff *skb; |
1236 | skb = ep->rx_skbuff[entry] = dev_alloc_skb(ep->rx_buf_sz); | 1236 | skb = ep->rx_skbuff[entry] = dev_alloc_skb(ep->rx_buf_sz + 2); |
1237 | if (skb == NULL) | 1237 | if (skb == NULL) |
1238 | break; | 1238 | break; |
1239 | skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ | 1239 | skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ |
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c index 9a6485892b3d..80d25ed53344 100644 --- a/drivers/net/hamachi.c +++ b/drivers/net/hamachi.c | |||
@@ -1202,7 +1202,7 @@ static void hamachi_init_ring(struct net_device *dev) | |||
1202 | } | 1202 | } |
1203 | /* Fill in the Rx buffers. Handle allocation failure gracefully. */ | 1203 | /* Fill in the Rx buffers. Handle allocation failure gracefully. */ |
1204 | for (i = 0; i < RX_RING_SIZE; i++) { | 1204 | for (i = 0; i < RX_RING_SIZE; i++) { |
1205 | struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz); | 1205 | struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz + 2); |
1206 | hmp->rx_skbuff[i] = skb; | 1206 | hmp->rx_skbuff[i] = skb; |
1207 | if (skb == NULL) | 1207 | if (skb == NULL) |
1208 | break; | 1208 | break; |
@@ -1669,7 +1669,7 @@ static int hamachi_rx(struct net_device *dev) | |||
1669 | entry = hmp->dirty_rx % RX_RING_SIZE; | 1669 | entry = hmp->dirty_rx % RX_RING_SIZE; |
1670 | desc = &(hmp->rx_ring[entry]); | 1670 | desc = &(hmp->rx_ring[entry]); |
1671 | if (hmp->rx_skbuff[entry] == NULL) { | 1671 | if (hmp->rx_skbuff[entry] == NULL) { |
1672 | struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz); | 1672 | struct sk_buff *skb = dev_alloc_skb(hmp->rx_buf_sz + 2); |
1673 | 1673 | ||
1674 | hmp->rx_skbuff[entry] = skb; | 1674 | hmp->rx_skbuff[entry] = skb; |
1675 | if (skb == NULL) | 1675 | if (skb == NULL) |
diff --git a/drivers/net/ifb.c b/drivers/net/ifb.c index ab9f675c5b8b..fe337bd121aa 100644 --- a/drivers/net/ifb.c +++ b/drivers/net/ifb.c | |||
@@ -104,6 +104,8 @@ static void ri_tasklet(unsigned long dev) | |||
104 | rcu_read_unlock(); | 104 | rcu_read_unlock(); |
105 | dev_kfree_skb(skb); | 105 | dev_kfree_skb(skb); |
106 | stats->tx_dropped++; | 106 | stats->tx_dropped++; |
107 | if (skb_queue_len(&dp->tq) != 0) | ||
108 | goto resched; | ||
107 | break; | 109 | break; |
108 | } | 110 | } |
109 | rcu_read_unlock(); | 111 | rcu_read_unlock(); |
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c index fbad4d819608..eee0b298bd36 100644 --- a/drivers/net/ixgbe/ixgbe_main.c +++ b/drivers/net/ixgbe/ixgbe_main.c | |||
@@ -4771,6 +4771,9 @@ void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter) | |||
4771 | adapter->rx_ring[i] = NULL; | 4771 | adapter->rx_ring[i] = NULL; |
4772 | } | 4772 | } |
4773 | 4773 | ||
4774 | adapter->num_tx_queues = 0; | ||
4775 | adapter->num_rx_queues = 0; | ||
4776 | |||
4774 | ixgbe_free_q_vectors(adapter); | 4777 | ixgbe_free_q_vectors(adapter); |
4775 | ixgbe_reset_interrupt_capability(adapter); | 4778 | ixgbe_reset_interrupt_capability(adapter); |
4776 | } | 4779 | } |
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 8a4d19e5de06..f1047dd8a526 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c | |||
@@ -690,6 +690,7 @@ static void block_output(struct net_device *dev, int count, | |||
690 | static struct pcmcia_device_id axnet_ids[] = { | 690 | static struct pcmcia_device_id axnet_ids[] = { |
691 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x016c, 0x0081), | 691 | PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x016c, 0x0081), |
692 | PCMCIA_DEVICE_MANF_CARD(0x018a, 0x0301), | 692 | PCMCIA_DEVICE_MANF_CARD(0x018a, 0x0301), |
693 | PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328), | ||
693 | PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0301), | 694 | PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0301), |
694 | PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0303), | 695 | PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0303), |
695 | PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0309), | 696 | PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0309), |
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index d05c44692f08..2c158910f7ea 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c | |||
@@ -1493,7 +1493,6 @@ static struct pcmcia_device_id pcnet_ids[] = { | |||
1493 | PCMCIA_DEVICE_MANF_CARD(0x0149, 0x4530), | 1493 | PCMCIA_DEVICE_MANF_CARD(0x0149, 0x4530), |
1494 | PCMCIA_DEVICE_MANF_CARD(0x0149, 0xc1ab), | 1494 | PCMCIA_DEVICE_MANF_CARD(0x0149, 0xc1ab), |
1495 | PCMCIA_DEVICE_MANF_CARD(0x0186, 0x0110), | 1495 | PCMCIA_DEVICE_MANF_CARD(0x0186, 0x0110), |
1496 | PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x2328), | ||
1497 | PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x8041), | 1496 | PCMCIA_DEVICE_MANF_CARD(0x01bf, 0x8041), |
1498 | PCMCIA_DEVICE_MANF_CARD(0x0213, 0x2452), | 1497 | PCMCIA_DEVICE_MANF_CARD(0x0213, 0x2452), |
1499 | PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0300), | 1498 | PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0300), |
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index cb3d13e4e074..35fda5ac8120 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig | |||
@@ -64,7 +64,7 @@ config BCM63XX_PHY | |||
64 | config ICPLUS_PHY | 64 | config ICPLUS_PHY |
65 | tristate "Drivers for ICPlus PHYs" | 65 | tristate "Drivers for ICPlus PHYs" |
66 | ---help--- | 66 | ---help--- |
67 | Currently supports the IP175C PHY. | 67 | Currently supports the IP175C and IP1001 PHYs. |
68 | 68 | ||
69 | config REALTEK_PHY | 69 | config REALTEK_PHY |
70 | tristate "Drivers for Realtek PHYs" | 70 | tristate "Drivers for Realtek PHYs" |
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c index c1d2d251fe8b..9a09e24c30bc 100644 --- a/drivers/net/phy/icplus.c +++ b/drivers/net/phy/icplus.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include <asm/irq.h> | 30 | #include <asm/irq.h> |
31 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
32 | 32 | ||
33 | MODULE_DESCRIPTION("ICPlus IP175C PHY driver"); | 33 | MODULE_DESCRIPTION("ICPlus IP175C/IC1001 PHY drivers"); |
34 | MODULE_AUTHOR("Michael Barkowski"); | 34 | MODULE_AUTHOR("Michael Barkowski"); |
35 | MODULE_LICENSE("GPL"); | 35 | MODULE_LICENSE("GPL"); |
36 | 36 | ||
@@ -89,6 +89,33 @@ static int ip175c_config_init(struct phy_device *phydev) | |||
89 | return 0; | 89 | return 0; |
90 | } | 90 | } |
91 | 91 | ||
92 | static int ip1001_config_init(struct phy_device *phydev) | ||
93 | { | ||
94 | int err, value; | ||
95 | |||
96 | /* Software Reset PHY */ | ||
97 | value = phy_read(phydev, MII_BMCR); | ||
98 | value |= BMCR_RESET; | ||
99 | err = phy_write(phydev, MII_BMCR, value); | ||
100 | if (err < 0) | ||
101 | return err; | ||
102 | |||
103 | do { | ||
104 | value = phy_read(phydev, MII_BMCR); | ||
105 | } while (value & BMCR_RESET); | ||
106 | |||
107 | /* Additional delay (2ns) used to adjust RX clock phase | ||
108 | * at GMII/ RGMII interface */ | ||
109 | value = phy_read(phydev, 16); | ||
110 | value |= 0x3; | ||
111 | |||
112 | err = phy_write(phydev, 16, value); | ||
113 | if (err < 0) | ||
114 | return err; | ||
115 | |||
116 | return err; | ||
117 | } | ||
118 | |||
92 | static int ip175c_read_status(struct phy_device *phydev) | 119 | static int ip175c_read_status(struct phy_device *phydev) |
93 | { | 120 | { |
94 | if (phydev->addr == 4) /* WAN port */ | 121 | if (phydev->addr == 4) /* WAN port */ |
@@ -121,21 +148,43 @@ static struct phy_driver ip175c_driver = { | |||
121 | .driver = { .owner = THIS_MODULE,}, | 148 | .driver = { .owner = THIS_MODULE,}, |
122 | }; | 149 | }; |
123 | 150 | ||
124 | static int __init ip175c_init(void) | 151 | static struct phy_driver ip1001_driver = { |
152 | .phy_id = 0x02430d90, | ||
153 | .name = "ICPlus IP1001", | ||
154 | .phy_id_mask = 0x0ffffff0, | ||
155 | .features = PHY_GBIT_FEATURES | SUPPORTED_Pause | | ||
156 | SUPPORTED_Asym_Pause, | ||
157 | .config_init = &ip1001_config_init, | ||
158 | .config_aneg = &genphy_config_aneg, | ||
159 | .read_status = &genphy_read_status, | ||
160 | .suspend = genphy_suspend, | ||
161 | .resume = genphy_resume, | ||
162 | .driver = { .owner = THIS_MODULE,}, | ||
163 | }; | ||
164 | |||
165 | static int __init icplus_init(void) | ||
125 | { | 166 | { |
167 | int ret = 0; | ||
168 | |||
169 | ret = phy_driver_register(&ip1001_driver); | ||
170 | if (ret < 0) | ||
171 | return -ENODEV; | ||
172 | |||
126 | return phy_driver_register(&ip175c_driver); | 173 | return phy_driver_register(&ip175c_driver); |
127 | } | 174 | } |
128 | 175 | ||
129 | static void __exit ip175c_exit(void) | 176 | static void __exit icplus_exit(void) |
130 | { | 177 | { |
178 | phy_driver_unregister(&ip1001_driver); | ||
131 | phy_driver_unregister(&ip175c_driver); | 179 | phy_driver_unregister(&ip175c_driver); |
132 | } | 180 | } |
133 | 181 | ||
134 | module_init(ip175c_init); | 182 | module_init(icplus_init); |
135 | module_exit(ip175c_exit); | 183 | module_exit(icplus_exit); |
136 | 184 | ||
137 | static struct mdio_device_id __maybe_unused icplus_tbl[] = { | 185 | static struct mdio_device_id __maybe_unused icplus_tbl[] = { |
138 | { 0x02430d80, 0x0ffffff0 }, | 186 | { 0x02430d80, 0x0ffffff0 }, |
187 | { 0x02430d90, 0x0ffffff0 }, | ||
139 | { } | 188 | { } |
140 | }; | 189 | }; |
141 | 190 | ||
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index 39659976a1ac..89294b43c4a9 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c | |||
@@ -1285,6 +1285,11 @@ ppp_push(struct ppp *ppp) | |||
1285 | } | 1285 | } |
1286 | 1286 | ||
1287 | #ifdef CONFIG_PPP_MULTILINK | 1287 | #ifdef CONFIG_PPP_MULTILINK |
1288 | static bool mp_protocol_compress __read_mostly = true; | ||
1289 | module_param(mp_protocol_compress, bool, S_IRUGO | S_IWUSR); | ||
1290 | MODULE_PARM_DESC(mp_protocol_compress, | ||
1291 | "compress protocol id in multilink fragments"); | ||
1292 | |||
1288 | /* | 1293 | /* |
1289 | * Divide a packet to be transmitted into fragments and | 1294 | * Divide a packet to be transmitted into fragments and |
1290 | * send them out the individual links. | 1295 | * send them out the individual links. |
@@ -1347,10 +1352,10 @@ static int ppp_mp_explode(struct ppp *ppp, struct sk_buff *skb) | |||
1347 | if (nfree == 0 || nfree < navail / 2) | 1352 | if (nfree == 0 || nfree < navail / 2) |
1348 | return 0; /* can't take now, leave it in xmit_pending */ | 1353 | return 0; /* can't take now, leave it in xmit_pending */ |
1349 | 1354 | ||
1350 | /* Do protocol field compression (XXX this should be optional) */ | 1355 | /* Do protocol field compression */ |
1351 | p = skb->data; | 1356 | p = skb->data; |
1352 | len = skb->len; | 1357 | len = skb->len; |
1353 | if (*p == 0) { | 1358 | if (*p == 0 && mp_protocol_compress) { |
1354 | ++p; | 1359 | ++p; |
1355 | --len; | 1360 | --len; |
1356 | } | 1361 | } |
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index d72fb0519a2a..78c0e3c9b2b5 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c | |||
@@ -948,7 +948,7 @@ static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb) | |||
948 | 948 | ||
949 | abort: | 949 | abort: |
950 | kfree_skb(skb); | 950 | kfree_skb(skb); |
951 | return 0; | 951 | return 1; |
952 | } | 952 | } |
953 | 953 | ||
954 | /************************************************************************ | 954 | /************************************************************************ |
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index 22821398fc63..9787dff90d3f 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h | |||
@@ -2083,6 +2083,7 @@ struct ql_adapter { | |||
2083 | u32 mailbox_in; | 2083 | u32 mailbox_in; |
2084 | u32 mailbox_out; | 2084 | u32 mailbox_out; |
2085 | struct mbox_params idc_mbc; | 2085 | struct mbox_params idc_mbc; |
2086 | struct mutex mpi_mutex; | ||
2086 | 2087 | ||
2087 | int tx_ring_size; | 2088 | int tx_ring_size; |
2088 | int rx_ring_size; | 2089 | int rx_ring_size; |
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 528eaef5308f..2555b1d34f34 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c | |||
@@ -4629,6 +4629,7 @@ static int __devinit ql_init_device(struct pci_dev *pdev, | |||
4629 | INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work); | 4629 | INIT_DELAYED_WORK(&qdev->mpi_idc_work, ql_mpi_idc_work); |
4630 | INIT_DELAYED_WORK(&qdev->mpi_core_to_log, ql_mpi_core_to_log); | 4630 | INIT_DELAYED_WORK(&qdev->mpi_core_to_log, ql_mpi_core_to_log); |
4631 | init_completion(&qdev->ide_completion); | 4631 | init_completion(&qdev->ide_completion); |
4632 | mutex_init(&qdev->mpi_mutex); | ||
4632 | 4633 | ||
4633 | if (!cards_found) { | 4634 | if (!cards_found) { |
4634 | dev_info(&pdev->dev, "%s\n", DRV_STRING); | 4635 | dev_info(&pdev->dev, "%s\n", DRV_STRING); |
diff --git a/drivers/net/qlge/qlge_mpi.c b/drivers/net/qlge/qlge_mpi.c index 0e7c7c7ee164..a2e919bcb3c6 100644 --- a/drivers/net/qlge/qlge_mpi.c +++ b/drivers/net/qlge/qlge_mpi.c | |||
@@ -534,6 +534,7 @@ static int ql_mailbox_command(struct ql_adapter *qdev, struct mbox_params *mbcp) | |||
534 | int status; | 534 | int status; |
535 | unsigned long count; | 535 | unsigned long count; |
536 | 536 | ||
537 | mutex_lock(&qdev->mpi_mutex); | ||
537 | 538 | ||
538 | /* Begin polled mode for MPI */ | 539 | /* Begin polled mode for MPI */ |
539 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16)); | 540 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16)); |
@@ -603,6 +604,7 @@ done: | |||
603 | end: | 604 | end: |
604 | /* End polled mode for MPI */ | 605 | /* End polled mode for MPI */ |
605 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI); | 606 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI); |
607 | mutex_unlock(&qdev->mpi_mutex); | ||
606 | return status; | 608 | return status; |
607 | } | 609 | } |
608 | 610 | ||
@@ -1099,9 +1101,7 @@ int ql_wait_fifo_empty(struct ql_adapter *qdev) | |||
1099 | static int ql_set_port_cfg(struct ql_adapter *qdev) | 1101 | static int ql_set_port_cfg(struct ql_adapter *qdev) |
1100 | { | 1102 | { |
1101 | int status; | 1103 | int status; |
1102 | rtnl_lock(); | ||
1103 | status = ql_mb_set_port_cfg(qdev); | 1104 | status = ql_mb_set_port_cfg(qdev); |
1104 | rtnl_unlock(); | ||
1105 | if (status) | 1105 | if (status) |
1106 | return status; | 1106 | return status; |
1107 | status = ql_idc_wait(qdev); | 1107 | status = ql_idc_wait(qdev); |
@@ -1122,9 +1122,7 @@ void ql_mpi_port_cfg_work(struct work_struct *work) | |||
1122 | container_of(work, struct ql_adapter, mpi_port_cfg_work.work); | 1122 | container_of(work, struct ql_adapter, mpi_port_cfg_work.work); |
1123 | int status; | 1123 | int status; |
1124 | 1124 | ||
1125 | rtnl_lock(); | ||
1126 | status = ql_mb_get_port_cfg(qdev); | 1125 | status = ql_mb_get_port_cfg(qdev); |
1127 | rtnl_unlock(); | ||
1128 | if (status) { | 1126 | if (status) { |
1129 | netif_err(qdev, drv, qdev->ndev, | 1127 | netif_err(qdev, drv, qdev->ndev, |
1130 | "Bug: Failed to get port config data.\n"); | 1128 | "Bug: Failed to get port config data.\n"); |
@@ -1167,7 +1165,6 @@ void ql_mpi_idc_work(struct work_struct *work) | |||
1167 | u32 aen; | 1165 | u32 aen; |
1168 | int timeout; | 1166 | int timeout; |
1169 | 1167 | ||
1170 | rtnl_lock(); | ||
1171 | aen = mbcp->mbox_out[1] >> 16; | 1168 | aen = mbcp->mbox_out[1] >> 16; |
1172 | timeout = (mbcp->mbox_out[1] >> 8) & 0xf; | 1169 | timeout = (mbcp->mbox_out[1] >> 8) & 0xf; |
1173 | 1170 | ||
@@ -1231,7 +1228,6 @@ void ql_mpi_idc_work(struct work_struct *work) | |||
1231 | } | 1228 | } |
1232 | break; | 1229 | break; |
1233 | } | 1230 | } |
1234 | rtnl_unlock(); | ||
1235 | } | 1231 | } |
1236 | 1232 | ||
1237 | void ql_mpi_work(struct work_struct *work) | 1233 | void ql_mpi_work(struct work_struct *work) |
@@ -1242,7 +1238,7 @@ void ql_mpi_work(struct work_struct *work) | |||
1242 | struct mbox_params *mbcp = &mbc; | 1238 | struct mbox_params *mbcp = &mbc; |
1243 | int err = 0; | 1239 | int err = 0; |
1244 | 1240 | ||
1245 | rtnl_lock(); | 1241 | mutex_lock(&qdev->mpi_mutex); |
1246 | /* Begin polled mode for MPI */ | 1242 | /* Begin polled mode for MPI */ |
1247 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16)); | 1243 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16)); |
1248 | 1244 | ||
@@ -1259,7 +1255,7 @@ void ql_mpi_work(struct work_struct *work) | |||
1259 | 1255 | ||
1260 | /* End polled mode for MPI */ | 1256 | /* End polled mode for MPI */ |
1261 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI); | 1257 | ql_write32(qdev, INTR_MASK, (INTR_MASK_PI << 16) | INTR_MASK_PI); |
1262 | rtnl_unlock(); | 1258 | mutex_unlock(&qdev->mpi_mutex); |
1263 | ql_enable_completion_interrupt(qdev, 0); | 1259 | ql_enable_completion_interrupt(qdev, 0); |
1264 | } | 1260 | } |
1265 | 1261 | ||
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index 7d33ef4bcb4a..53b13deade95 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -744,26 +744,36 @@ static void rtl8169_xmii_reset_enable(void __iomem *ioaddr) | |||
744 | mdio_write(ioaddr, MII_BMCR, val & 0xffff); | 744 | mdio_write(ioaddr, MII_BMCR, val & 0xffff); |
745 | } | 745 | } |
746 | 746 | ||
747 | static void rtl8169_check_link_status(struct net_device *dev, | 747 | static void __rtl8169_check_link_status(struct net_device *dev, |
748 | struct rtl8169_private *tp, | 748 | struct rtl8169_private *tp, |
749 | void __iomem *ioaddr) | 749 | void __iomem *ioaddr, |
750 | bool pm) | ||
750 | { | 751 | { |
751 | unsigned long flags; | 752 | unsigned long flags; |
752 | 753 | ||
753 | spin_lock_irqsave(&tp->lock, flags); | 754 | spin_lock_irqsave(&tp->lock, flags); |
754 | if (tp->link_ok(ioaddr)) { | 755 | if (tp->link_ok(ioaddr)) { |
755 | /* This is to cancel a scheduled suspend if there's one. */ | 756 | /* This is to cancel a scheduled suspend if there's one. */ |
756 | pm_request_resume(&tp->pci_dev->dev); | 757 | if (pm) |
758 | pm_request_resume(&tp->pci_dev->dev); | ||
757 | netif_carrier_on(dev); | 759 | netif_carrier_on(dev); |
758 | netif_info(tp, ifup, dev, "link up\n"); | 760 | netif_info(tp, ifup, dev, "link up\n"); |
759 | } else { | 761 | } else { |
760 | netif_carrier_off(dev); | 762 | netif_carrier_off(dev); |
761 | netif_info(tp, ifdown, dev, "link down\n"); | 763 | netif_info(tp, ifdown, dev, "link down\n"); |
762 | pm_schedule_suspend(&tp->pci_dev->dev, 100); | 764 | if (pm) |
765 | pm_schedule_suspend(&tp->pci_dev->dev, 100); | ||
763 | } | 766 | } |
764 | spin_unlock_irqrestore(&tp->lock, flags); | 767 | spin_unlock_irqrestore(&tp->lock, flags); |
765 | } | 768 | } |
766 | 769 | ||
770 | static void rtl8169_check_link_status(struct net_device *dev, | ||
771 | struct rtl8169_private *tp, | ||
772 | void __iomem *ioaddr) | ||
773 | { | ||
774 | __rtl8169_check_link_status(dev, tp, ioaddr, false); | ||
775 | } | ||
776 | |||
767 | #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST) | 777 | #define WAKE_ANY (WAKE_PHY | WAKE_MAGIC | WAKE_UCAST | WAKE_BCAST | WAKE_MCAST) |
768 | 778 | ||
769 | static u32 __rtl8169_get_wol(struct rtl8169_private *tp) | 779 | static u32 __rtl8169_get_wol(struct rtl8169_private *tp) |
@@ -4600,7 +4610,7 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) | |||
4600 | } | 4610 | } |
4601 | 4611 | ||
4602 | if (status & LinkChg) | 4612 | if (status & LinkChg) |
4603 | rtl8169_check_link_status(dev, tp, ioaddr); | 4613 | __rtl8169_check_link_status(dev, tp, ioaddr, true); |
4604 | 4614 | ||
4605 | /* We need to see the lastest version of tp->intr_mask to | 4615 | /* We need to see the lastest version of tp->intr_mask to |
4606 | * avoid ignoring an MSI interrupt and having to wait for | 4616 | * avoid ignoring an MSI interrupt and having to wait for |
@@ -4890,11 +4900,7 @@ static int rtl8169_runtime_idle(struct device *device) | |||
4890 | struct net_device *dev = pci_get_drvdata(pdev); | 4900 | struct net_device *dev = pci_get_drvdata(pdev); |
4891 | struct rtl8169_private *tp = netdev_priv(dev); | 4901 | struct rtl8169_private *tp = netdev_priv(dev); |
4892 | 4902 | ||
4893 | if (!tp->TxDescArray) | 4903 | return tp->TxDescArray ? -EBUSY : 0; |
4894 | return 0; | ||
4895 | |||
4896 | rtl8169_check_link_status(dev, tp, tp->mmio_addr); | ||
4897 | return -EBUSY; | ||
4898 | } | 4904 | } |
4899 | 4905 | ||
4900 | static const struct dev_pm_ops rtl8169_pm_ops = { | 4906 | static const struct dev_pm_ops rtl8169_pm_ops = { |
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c index 05df20e47976..fb83cdd94643 100644 --- a/drivers/net/sfc/efx.c +++ b/drivers/net/sfc/efx.c | |||
@@ -197,7 +197,9 @@ MODULE_PARM_DESC(debug, "Bitmapped debugging message enable value"); | |||
197 | 197 | ||
198 | static void efx_remove_channels(struct efx_nic *efx); | 198 | static void efx_remove_channels(struct efx_nic *efx); |
199 | static void efx_remove_port(struct efx_nic *efx); | 199 | static void efx_remove_port(struct efx_nic *efx); |
200 | static void efx_init_napi(struct efx_nic *efx); | ||
200 | static void efx_fini_napi(struct efx_nic *efx); | 201 | static void efx_fini_napi(struct efx_nic *efx); |
202 | static void efx_fini_napi_channel(struct efx_channel *channel); | ||
201 | static void efx_fini_struct(struct efx_nic *efx); | 203 | static void efx_fini_struct(struct efx_nic *efx); |
202 | static void efx_start_all(struct efx_nic *efx); | 204 | static void efx_start_all(struct efx_nic *efx); |
203 | static void efx_stop_all(struct efx_nic *efx); | 205 | static void efx_stop_all(struct efx_nic *efx); |
@@ -335,8 +337,10 @@ void efx_process_channel_now(struct efx_channel *channel) | |||
335 | 337 | ||
336 | /* Disable interrupts and wait for ISRs to complete */ | 338 | /* Disable interrupts and wait for ISRs to complete */ |
337 | efx_nic_disable_interrupts(efx); | 339 | efx_nic_disable_interrupts(efx); |
338 | if (efx->legacy_irq) | 340 | if (efx->legacy_irq) { |
339 | synchronize_irq(efx->legacy_irq); | 341 | synchronize_irq(efx->legacy_irq); |
342 | efx->legacy_irq_enabled = false; | ||
343 | } | ||
340 | if (channel->irq) | 344 | if (channel->irq) |
341 | synchronize_irq(channel->irq); | 345 | synchronize_irq(channel->irq); |
342 | 346 | ||
@@ -351,6 +355,8 @@ void efx_process_channel_now(struct efx_channel *channel) | |||
351 | efx_channel_processed(channel); | 355 | efx_channel_processed(channel); |
352 | 356 | ||
353 | napi_enable(&channel->napi_str); | 357 | napi_enable(&channel->napi_str); |
358 | if (efx->legacy_irq) | ||
359 | efx->legacy_irq_enabled = true; | ||
354 | efx_nic_enable_interrupts(efx); | 360 | efx_nic_enable_interrupts(efx); |
355 | } | 361 | } |
356 | 362 | ||
@@ -426,6 +432,7 @@ efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel) | |||
426 | 432 | ||
427 | *channel = *old_channel; | 433 | *channel = *old_channel; |
428 | 434 | ||
435 | channel->napi_dev = NULL; | ||
429 | memset(&channel->eventq, 0, sizeof(channel->eventq)); | 436 | memset(&channel->eventq, 0, sizeof(channel->eventq)); |
430 | 437 | ||
431 | rx_queue = &channel->rx_queue; | 438 | rx_queue = &channel->rx_queue; |
@@ -736,9 +743,13 @@ efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries) | |||
736 | if (rc) | 743 | if (rc) |
737 | goto rollback; | 744 | goto rollback; |
738 | 745 | ||
746 | efx_init_napi(efx); | ||
747 | |||
739 | /* Destroy old channels */ | 748 | /* Destroy old channels */ |
740 | for (i = 0; i < efx->n_channels; i++) | 749 | for (i = 0; i < efx->n_channels; i++) { |
750 | efx_fini_napi_channel(other_channel[i]); | ||
741 | efx_remove_channel(other_channel[i]); | 751 | efx_remove_channel(other_channel[i]); |
752 | } | ||
742 | out: | 753 | out: |
743 | /* Free unused channel structures */ | 754 | /* Free unused channel structures */ |
744 | for (i = 0; i < efx->n_channels; i++) | 755 | for (i = 0; i < efx->n_channels; i++) |
@@ -1400,6 +1411,8 @@ static void efx_start_all(struct efx_nic *efx) | |||
1400 | efx_start_channel(channel); | 1411 | efx_start_channel(channel); |
1401 | } | 1412 | } |
1402 | 1413 | ||
1414 | if (efx->legacy_irq) | ||
1415 | efx->legacy_irq_enabled = true; | ||
1403 | efx_nic_enable_interrupts(efx); | 1416 | efx_nic_enable_interrupts(efx); |
1404 | 1417 | ||
1405 | /* Switch to event based MCDI completions after enabling interrupts. | 1418 | /* Switch to event based MCDI completions after enabling interrupts. |
@@ -1460,8 +1473,10 @@ static void efx_stop_all(struct efx_nic *efx) | |||
1460 | 1473 | ||
1461 | /* Disable interrupts and wait for ISR to complete */ | 1474 | /* Disable interrupts and wait for ISR to complete */ |
1462 | efx_nic_disable_interrupts(efx); | 1475 | efx_nic_disable_interrupts(efx); |
1463 | if (efx->legacy_irq) | 1476 | if (efx->legacy_irq) { |
1464 | synchronize_irq(efx->legacy_irq); | 1477 | synchronize_irq(efx->legacy_irq); |
1478 | efx->legacy_irq_enabled = false; | ||
1479 | } | ||
1465 | efx_for_each_channel(channel, efx) { | 1480 | efx_for_each_channel(channel, efx) { |
1466 | if (channel->irq) | 1481 | if (channel->irq) |
1467 | synchronize_irq(channel->irq); | 1482 | synchronize_irq(channel->irq); |
@@ -1593,7 +1608,7 @@ static int efx_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd) | |||
1593 | * | 1608 | * |
1594 | **************************************************************************/ | 1609 | **************************************************************************/ |
1595 | 1610 | ||
1596 | static int efx_init_napi(struct efx_nic *efx) | 1611 | static void efx_init_napi(struct efx_nic *efx) |
1597 | { | 1612 | { |
1598 | struct efx_channel *channel; | 1613 | struct efx_channel *channel; |
1599 | 1614 | ||
@@ -1602,18 +1617,21 @@ static int efx_init_napi(struct efx_nic *efx) | |||
1602 | netif_napi_add(channel->napi_dev, &channel->napi_str, | 1617 | netif_napi_add(channel->napi_dev, &channel->napi_str, |
1603 | efx_poll, napi_weight); | 1618 | efx_poll, napi_weight); |
1604 | } | 1619 | } |
1605 | return 0; | 1620 | } |
1621 | |||
1622 | static void efx_fini_napi_channel(struct efx_channel *channel) | ||
1623 | { | ||
1624 | if (channel->napi_dev) | ||
1625 | netif_napi_del(&channel->napi_str); | ||
1626 | channel->napi_dev = NULL; | ||
1606 | } | 1627 | } |
1607 | 1628 | ||
1608 | static void efx_fini_napi(struct efx_nic *efx) | 1629 | static void efx_fini_napi(struct efx_nic *efx) |
1609 | { | 1630 | { |
1610 | struct efx_channel *channel; | 1631 | struct efx_channel *channel; |
1611 | 1632 | ||
1612 | efx_for_each_channel(channel, efx) { | 1633 | efx_for_each_channel(channel, efx) |
1613 | if (channel->napi_dev) | 1634 | efx_fini_napi_channel(channel); |
1614 | netif_napi_del(&channel->napi_str); | ||
1615 | channel->napi_dev = NULL; | ||
1616 | } | ||
1617 | } | 1635 | } |
1618 | 1636 | ||
1619 | /************************************************************************** | 1637 | /************************************************************************** |
@@ -2335,9 +2353,7 @@ static int efx_pci_probe_main(struct efx_nic *efx) | |||
2335 | if (rc) | 2353 | if (rc) |
2336 | goto fail1; | 2354 | goto fail1; |
2337 | 2355 | ||
2338 | rc = efx_init_napi(efx); | 2356 | efx_init_napi(efx); |
2339 | if (rc) | ||
2340 | goto fail2; | ||
2341 | 2357 | ||
2342 | rc = efx->type->init(efx); | 2358 | rc = efx->type->init(efx); |
2343 | if (rc) { | 2359 | if (rc) { |
@@ -2368,7 +2384,6 @@ static int efx_pci_probe_main(struct efx_nic *efx) | |||
2368 | efx->type->fini(efx); | 2384 | efx->type->fini(efx); |
2369 | fail3: | 2385 | fail3: |
2370 | efx_fini_napi(efx); | 2386 | efx_fini_napi(efx); |
2371 | fail2: | ||
2372 | efx_remove_all(efx); | 2387 | efx_remove_all(efx); |
2373 | fail1: | 2388 | fail1: |
2374 | return rc; | 2389 | return rc; |
diff --git a/drivers/net/sfc/net_driver.h b/drivers/net/sfc/net_driver.h index 0a7e26d73b52..b137c889152b 100644 --- a/drivers/net/sfc/net_driver.h +++ b/drivers/net/sfc/net_driver.h | |||
@@ -621,6 +621,7 @@ struct efx_filter_state; | |||
621 | * @pci_dev: The PCI device | 621 | * @pci_dev: The PCI device |
622 | * @type: Controller type attributes | 622 | * @type: Controller type attributes |
623 | * @legacy_irq: IRQ number | 623 | * @legacy_irq: IRQ number |
624 | * @legacy_irq_enabled: Are IRQs enabled on NIC (INT_EN_KER register)? | ||
624 | * @workqueue: Workqueue for port reconfigures and the HW monitor. | 625 | * @workqueue: Workqueue for port reconfigures and the HW monitor. |
625 | * Work items do not hold and must not acquire RTNL. | 626 | * Work items do not hold and must not acquire RTNL. |
626 | * @workqueue_name: Name of workqueue | 627 | * @workqueue_name: Name of workqueue |
@@ -709,6 +710,7 @@ struct efx_nic { | |||
709 | struct pci_dev *pci_dev; | 710 | struct pci_dev *pci_dev; |
710 | const struct efx_nic_type *type; | 711 | const struct efx_nic_type *type; |
711 | int legacy_irq; | 712 | int legacy_irq; |
713 | bool legacy_irq_enabled; | ||
712 | struct workqueue_struct *workqueue; | 714 | struct workqueue_struct *workqueue; |
713 | char workqueue_name[16]; | 715 | char workqueue_name[16]; |
714 | struct work_struct reset_work; | 716 | struct work_struct reset_work; |
diff --git a/drivers/net/sfc/nic.c b/drivers/net/sfc/nic.c index 41c36b9a4244..67cb0c96838c 100644 --- a/drivers/net/sfc/nic.c +++ b/drivers/net/sfc/nic.c | |||
@@ -1418,6 +1418,12 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id) | |||
1418 | u32 queues; | 1418 | u32 queues; |
1419 | int syserr; | 1419 | int syserr; |
1420 | 1420 | ||
1421 | /* Could this be ours? If interrupts are disabled then the | ||
1422 | * channel state may not be valid. | ||
1423 | */ | ||
1424 | if (!efx->legacy_irq_enabled) | ||
1425 | return result; | ||
1426 | |||
1421 | /* Read the ISR which also ACKs the interrupts */ | 1427 | /* Read the ISR which also ACKs the interrupts */ |
1422 | efx_readd(efx, ®, FR_BZ_INT_ISR0); | 1428 | efx_readd(efx, ®, FR_BZ_INT_ISR0); |
1423 | queues = EFX_EXTRACT_DWORD(reg, 0, 31); | 1429 | queues = EFX_EXTRACT_DWORD(reg, 0, 31); |
diff --git a/drivers/net/skfp/skfddi.c b/drivers/net/skfp/skfddi.c index 0a66fed52e8e..16c62659cdd9 100644 --- a/drivers/net/skfp/skfddi.c +++ b/drivers/net/skfp/skfddi.c | |||
@@ -412,7 +412,7 @@ static int skfp_driver_init(struct net_device *dev) | |||
412 | bp->SharedMemAddr = pci_alloc_consistent(&bp->pdev, | 412 | bp->SharedMemAddr = pci_alloc_consistent(&bp->pdev, |
413 | bp->SharedMemSize, | 413 | bp->SharedMemSize, |
414 | &bp->SharedMemDMA); | 414 | &bp->SharedMemDMA); |
415 | if (!bp->SharedMemSize) { | 415 | if (!bp->SharedMemAddr) { |
416 | printk("could not allocate mem for "); | 416 | printk("could not allocate mem for "); |
417 | printk("hardware module: %ld byte\n", | 417 | printk("hardware module: %ld byte\n", |
418 | bp->SharedMemSize); | 418 | bp->SharedMemSize); |
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c index 4adf12422787..a4f2bd52e546 100644 --- a/drivers/net/starfire.c +++ b/drivers/net/starfire.c | |||
@@ -148,7 +148,7 @@ static int full_duplex[MAX_UNITS] = {0, }; | |||
148 | * This SUCKS. | 148 | * This SUCKS. |
149 | * We need a much better method to determine if dma_addr_t is 64-bit. | 149 | * We need a much better method to determine if dma_addr_t is 64-bit. |
150 | */ | 150 | */ |
151 | #if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || defined(__mips64__) || (defined(__mips__) && defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) || (defined(__powerpc64__) || defined(CONFIG_PHYS_64BIT)) | 151 | #if (defined(__i386__) && defined(CONFIG_HIGHMEM64G)) || defined(__x86_64__) || defined (__ia64__) || defined(__alpha__) || (defined(CONFIG_MIPS) && ((defined(CONFIG_HIGHMEM) && defined(CONFIG_64BIT_PHYS_ADDR)) || defined(CONFIG_64BIT))) || (defined(__powerpc64__) || defined(CONFIG_PHYS_64BIT)) |
152 | /* 64-bit dma_addr_t */ | 152 | /* 64-bit dma_addr_t */ |
153 | #define ADDR_64BITS /* This chip uses 64 bit addresses. */ | 153 | #define ADDR_64BITS /* This chip uses 64 bit addresses. */ |
154 | #define netdrv_addr_t __le64 | 154 | #define netdrv_addr_t __le64 |
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c index 06bc6034ce81..2114837809e7 100644 --- a/drivers/net/stmmac/stmmac_main.c +++ b/drivers/net/stmmac/stmmac_main.c | |||
@@ -1509,6 +1509,8 @@ static int stmmac_probe(struct net_device *dev) | |||
1509 | pr_warning("\tno valid MAC address;" | 1509 | pr_warning("\tno valid MAC address;" |
1510 | "please, use ifconfig or nwhwconfig!\n"); | 1510 | "please, use ifconfig or nwhwconfig!\n"); |
1511 | 1511 | ||
1512 | spin_lock_init(&priv->lock); | ||
1513 | |||
1512 | ret = register_netdev(dev); | 1514 | ret = register_netdev(dev); |
1513 | if (ret) { | 1515 | if (ret) { |
1514 | pr_err("%s: ERROR %i registering the device\n", | 1516 | pr_err("%s: ERROR %i registering the device\n", |
@@ -1520,8 +1522,6 @@ static int stmmac_probe(struct net_device *dev) | |||
1520 | dev->name, (dev->features & NETIF_F_SG) ? "on" : "off", | 1522 | dev->name, (dev->features & NETIF_F_SG) ? "on" : "off", |
1521 | (dev->features & NETIF_F_HW_CSUM) ? "on" : "off"); | 1523 | (dev->features & NETIF_F_HW_CSUM) ? "on" : "off"); |
1522 | 1524 | ||
1523 | spin_lock_init(&priv->lock); | ||
1524 | |||
1525 | return ret; | 1525 | return ret; |
1526 | } | 1526 | } |
1527 | 1527 | ||
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c index 3ed2a67bd6d3..b409d7ec4ac1 100644 --- a/drivers/net/sundance.c +++ b/drivers/net/sundance.c | |||
@@ -1016,7 +1016,7 @@ static void init_ring(struct net_device *dev) | |||
1016 | 1016 | ||
1017 | /* Fill in the Rx buffers. Handle allocation failure gracefully. */ | 1017 | /* Fill in the Rx buffers. Handle allocation failure gracefully. */ |
1018 | for (i = 0; i < RX_RING_SIZE; i++) { | 1018 | for (i = 0; i < RX_RING_SIZE; i++) { |
1019 | struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz); | 1019 | struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz + 2); |
1020 | np->rx_skbuff[i] = skb; | 1020 | np->rx_skbuff[i] = skb; |
1021 | if (skb == NULL) | 1021 | if (skb == NULL) |
1022 | break; | 1022 | break; |
@@ -1407,7 +1407,7 @@ static void refill_rx (struct net_device *dev) | |||
1407 | struct sk_buff *skb; | 1407 | struct sk_buff *skb; |
1408 | entry = np->dirty_rx % RX_RING_SIZE; | 1408 | entry = np->dirty_rx % RX_RING_SIZE; |
1409 | if (np->rx_skbuff[entry] == NULL) { | 1409 | if (np->rx_skbuff[entry] == NULL) { |
1410 | skb = dev_alloc_skb(np->rx_buf_sz); | 1410 | skb = dev_alloc_skb(np->rx_buf_sz + 2); |
1411 | np->rx_skbuff[entry] = skb; | 1411 | np->rx_skbuff[entry] = skb; |
1412 | if (skb == NULL) | 1412 | if (skb == NULL) |
1413 | break; /* Better luck next round. */ | 1413 | break; /* Better luck next round. */ |
diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index 8b3dc1eb4015..296000bf5a25 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c | |||
@@ -324,7 +324,7 @@ static int bdx_fw_load(struct bdx_priv *priv) | |||
324 | ENTER; | 324 | ENTER; |
325 | master = READ_REG(priv, regINIT_SEMAPHORE); | 325 | master = READ_REG(priv, regINIT_SEMAPHORE); |
326 | if (!READ_REG(priv, regINIT_STATUS) && master) { | 326 | if (!READ_REG(priv, regINIT_STATUS) && master) { |
327 | rc = request_firmware(&fw, "tehuti/firmware.bin", &priv->pdev->dev); | 327 | rc = request_firmware(&fw, "tehuti/bdx.bin", &priv->pdev->dev); |
328 | if (rc) | 328 | if (rc) |
329 | goto out; | 329 | goto out; |
330 | bdx_tx_push_desc_safe(priv, (char *)fw->data, fw->size); | 330 | bdx_tx_push_desc_safe(priv, (char *)fw->data, fw->size); |
@@ -2510,4 +2510,4 @@ module_exit(bdx_module_exit); | |||
2510 | MODULE_LICENSE("GPL"); | 2510 | MODULE_LICENSE("GPL"); |
2511 | MODULE_AUTHOR(DRIVER_AUTHOR); | 2511 | MODULE_AUTHOR(DRIVER_AUTHOR); |
2512 | MODULE_DESCRIPTION(BDX_DRV_DESC); | 2512 | MODULE_DESCRIPTION(BDX_DRV_DESC); |
2513 | MODULE_FIRMWARE("tehuti/firmware.bin"); | 2513 | MODULE_FIRMWARE("tehuti/bdx.bin"); |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 30ccbb6d097a..6f97b7bbcbf1 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -12658,7 +12658,7 @@ static void __devinit tg3_read_vpd(struct tg3 *tp) | |||
12658 | cnt = pci_read_vpd(tp->pdev, pos, | 12658 | cnt = pci_read_vpd(tp->pdev, pos, |
12659 | TG3_NVM_VPD_LEN - pos, | 12659 | TG3_NVM_VPD_LEN - pos, |
12660 | &vpd_data[pos]); | 12660 | &vpd_data[pos]); |
12661 | if (cnt == -ETIMEDOUT || -EINTR) | 12661 | if (cnt == -ETIMEDOUT || cnt == -EINTR) |
12662 | cnt = 0; | 12662 | cnt = 0; |
12663 | else if (cnt < 0) | 12663 | else if (cnt < 0) |
12664 | goto out_not_found; | 12664 | goto out_not_found; |
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index a9f7d5d1a269..7064e035757a 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c | |||
@@ -688,9 +688,6 @@ static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb, | |||
688 | 688 | ||
689 | DMFE_DBUG(0, "dmfe_start_xmit", 0); | 689 | DMFE_DBUG(0, "dmfe_start_xmit", 0); |
690 | 690 | ||
691 | /* Resource flag check */ | ||
692 | netif_stop_queue(dev); | ||
693 | |||
694 | /* Too large packet check */ | 691 | /* Too large packet check */ |
695 | if (skb->len > MAX_PACKET_SIZE) { | 692 | if (skb->len > MAX_PACKET_SIZE) { |
696 | pr_err("big packet = %d\n", (u16)skb->len); | 693 | pr_err("big packet = %d\n", (u16)skb->len); |
@@ -698,6 +695,9 @@ static netdev_tx_t dmfe_start_xmit(struct sk_buff *skb, | |||
698 | return NETDEV_TX_OK; | 695 | return NETDEV_TX_OK; |
699 | } | 696 | } |
700 | 697 | ||
698 | /* Resource flag check */ | ||
699 | netif_stop_queue(dev); | ||
700 | |||
701 | spin_lock_irqsave(&db->lock, flags); | 701 | spin_lock_irqsave(&db->lock, flags); |
702 | 702 | ||
703 | /* No Tx resource check, it never happen nromally */ | 703 | /* No Tx resource check, it never happen nromally */ |
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c index 5b83c3f35f47..a3c46f6a15e7 100644 --- a/drivers/net/typhoon.c +++ b/drivers/net/typhoon.c | |||
@@ -1004,7 +1004,6 @@ typhoon_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | |||
1004 | } | 1004 | } |
1005 | 1005 | ||
1006 | strcpy(info->driver, KBUILD_MODNAME); | 1006 | strcpy(info->driver, KBUILD_MODNAME); |
1007 | strcpy(info->version, UTS_RELEASE); | ||
1008 | strcpy(info->bus_info, pci_name(pci_dev)); | 1007 | strcpy(info->bus_info, pci_name(pci_dev)); |
1009 | } | 1008 | } |
1010 | 1009 | ||
diff --git a/drivers/net/usb/asix.c b/drivers/net/usb/asix.c index aea4645be7f6..6140b56cce53 100644 --- a/drivers/net/usb/asix.c +++ b/drivers/net/usb/asix.c | |||
@@ -1508,6 +1508,10 @@ static const struct usb_device_id products [] = { | |||
1508 | USB_DEVICE (0x0b95, 0x1780), | 1508 | USB_DEVICE (0x0b95, 0x1780), |
1509 | .driver_info = (unsigned long) &ax88178_info, | 1509 | .driver_info = (unsigned long) &ax88178_info, |
1510 | }, { | 1510 | }, { |
1511 | // Logitec LAN-GTJ/U2A | ||
1512 | USB_DEVICE (0x0789, 0x0160), | ||
1513 | .driver_info = (unsigned long) &ax88178_info, | ||
1514 | }, { | ||
1511 | // Linksys USB200M Rev 2 | 1515 | // Linksys USB200M Rev 2 |
1512 | USB_DEVICE (0x13b1, 0x0018), | 1516 | USB_DEVICE (0x13b1, 0x0018), |
1513 | .driver_info = (unsigned long) &ax88772_info, | 1517 | .driver_info = (unsigned long) &ax88772_info, |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 62e9e8dc8190..812edf85d6d3 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -958,10 +958,6 @@ static void packetizeRx(struct hso_net *odev, unsigned char *ip_pkt, | |||
958 | /* Packet is complete. Inject into stack. */ | 958 | /* Packet is complete. Inject into stack. */ |
959 | /* We have IP packet here */ | 959 | /* We have IP packet here */ |
960 | odev->skb_rx_buf->protocol = cpu_to_be16(ETH_P_IP); | 960 | odev->skb_rx_buf->protocol = cpu_to_be16(ETH_P_IP); |
961 | /* don't check it */ | ||
962 | odev->skb_rx_buf->ip_summed = | ||
963 | CHECKSUM_UNNECESSARY; | ||
964 | |||
965 | skb_reset_mac_header(odev->skb_rx_buf); | 961 | skb_reset_mac_header(odev->skb_rx_buf); |
966 | 962 | ||
967 | /* Ship it off to the kernel */ | 963 | /* Ship it off to the kernel */ |
diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c index a6281e3987b5..2b791392e788 100644 --- a/drivers/net/usb/mcs7830.c +++ b/drivers/net/usb/mcs7830.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * MOSCHIP MCS7830 based USB 2.0 Ethernet Devices | 2 | * MOSCHIP MCS7830 based (7730/7830/7832) USB 2.0 Ethernet Devices |
3 | * | 3 | * |
4 | * based on usbnet.c, asix.c and the vendor provided mcs7830 driver | 4 | * based on usbnet.c, asix.c and the vendor provided mcs7830 driver |
5 | * | 5 | * |
@@ -11,6 +11,9 @@ | |||
11 | * | 11 | * |
12 | * Definitions gathered from MOSCHIP, Data Sheet_7830DA.pdf (thanks!). | 12 | * Definitions gathered from MOSCHIP, Data Sheet_7830DA.pdf (thanks!). |
13 | * | 13 | * |
14 | * 2010-12-19: add 7832 USB PID ("functionality same as MCS7830"), | ||
15 | * per active notification by manufacturer | ||
16 | * | ||
14 | * TODO: | 17 | * TODO: |
15 | * - support HIF_REG_CONFIG_SLEEPMODE/HIF_REG_CONFIG_TXENABLE (via autopm?) | 18 | * - support HIF_REG_CONFIG_SLEEPMODE/HIF_REG_CONFIG_TXENABLE (via autopm?) |
16 | * - implement ethtool_ops get_pauseparam/set_pauseparam | 19 | * - implement ethtool_ops get_pauseparam/set_pauseparam |
@@ -60,6 +63,7 @@ | |||
60 | #define MCS7830_MAX_MCAST 64 | 63 | #define MCS7830_MAX_MCAST 64 |
61 | 64 | ||
62 | #define MCS7830_VENDOR_ID 0x9710 | 65 | #define MCS7830_VENDOR_ID 0x9710 |
66 | #define MCS7832_PRODUCT_ID 0x7832 | ||
63 | #define MCS7830_PRODUCT_ID 0x7830 | 67 | #define MCS7830_PRODUCT_ID 0x7830 |
64 | #define MCS7730_PRODUCT_ID 0x7730 | 68 | #define MCS7730_PRODUCT_ID 0x7730 |
65 | 69 | ||
@@ -351,7 +355,7 @@ static int mcs7830_set_autoneg(struct usbnet *dev, int ptrUserPhyMode) | |||
351 | if (!ret) | 355 | if (!ret) |
352 | ret = mcs7830_write_phy(dev, MII_BMCR, | 356 | ret = mcs7830_write_phy(dev, MII_BMCR, |
353 | BMCR_ANENABLE | BMCR_ANRESTART ); | 357 | BMCR_ANENABLE | BMCR_ANRESTART ); |
354 | return ret < 0 ? : 0; | 358 | return ret; |
355 | } | 359 | } |
356 | 360 | ||
357 | 361 | ||
@@ -626,7 +630,7 @@ static int mcs7830_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
626 | } | 630 | } |
627 | 631 | ||
628 | static const struct driver_info moschip_info = { | 632 | static const struct driver_info moschip_info = { |
629 | .description = "MOSCHIP 7830/7730 usb-NET adapter", | 633 | .description = "MOSCHIP 7830/7832/7730 usb-NET adapter", |
630 | .bind = mcs7830_bind, | 634 | .bind = mcs7830_bind, |
631 | .rx_fixup = mcs7830_rx_fixup, | 635 | .rx_fixup = mcs7830_rx_fixup, |
632 | .flags = FLAG_ETHER, | 636 | .flags = FLAG_ETHER, |
@@ -645,6 +649,10 @@ static const struct driver_info sitecom_info = { | |||
645 | 649 | ||
646 | static const struct usb_device_id products[] = { | 650 | static const struct usb_device_id products[] = { |
647 | { | 651 | { |
652 | USB_DEVICE(MCS7830_VENDOR_ID, MCS7832_PRODUCT_ID), | ||
653 | .driver_info = (unsigned long) &moschip_info, | ||
654 | }, | ||
655 | { | ||
648 | USB_DEVICE(MCS7830_VENDOR_ID, MCS7830_PRODUCT_ID), | 656 | USB_DEVICE(MCS7830_VENDOR_ID, MCS7830_PRODUCT_ID), |
649 | .driver_info = (unsigned long) &moschip_info, | 657 | .driver_info = (unsigned long) &moschip_info, |
650 | }, | 658 | }, |
diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 0bbc0c323135..cc83fa71c3ff 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c | |||
@@ -166,7 +166,9 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev) | |||
166 | if (!(rcv->flags & IFF_UP)) | 166 | if (!(rcv->flags & IFF_UP)) |
167 | goto tx_drop; | 167 | goto tx_drop; |
168 | 168 | ||
169 | if (dev->features & NETIF_F_NO_CSUM) | 169 | /* don't change ip_summed == CHECKSUM_PARTIAL, as that |
170 | will cause bad checksum on forwarded packets */ | ||
171 | if (skb->ip_summed == CHECKSUM_NONE) | ||
170 | skb->ip_summed = rcv_priv->ip_summed; | 172 | skb->ip_summed = rcv_priv->ip_summed; |
171 | 173 | ||
172 | length = skb->len + ETH_HLEN; | 174 | length = skb->len + ETH_HLEN; |
diff --git a/drivers/net/wan/hd64572.c b/drivers/net/wan/hd64572.c index ea476cbd38b5..e305274f83fb 100644 --- a/drivers/net/wan/hd64572.c +++ b/drivers/net/wan/hd64572.c | |||
@@ -293,6 +293,7 @@ static inline void sca_tx_done(port_t *port) | |||
293 | struct net_device *dev = port->netdev; | 293 | struct net_device *dev = port->netdev; |
294 | card_t* card = port->card; | 294 | card_t* card = port->card; |
295 | u8 stat; | 295 | u8 stat; |
296 | unsigned count = 0; | ||
296 | 297 | ||
297 | spin_lock(&port->lock); | 298 | spin_lock(&port->lock); |
298 | 299 | ||
@@ -316,10 +317,12 @@ static inline void sca_tx_done(port_t *port) | |||
316 | dev->stats.tx_bytes += readw(&desc->len); | 317 | dev->stats.tx_bytes += readw(&desc->len); |
317 | } | 318 | } |
318 | writeb(0, &desc->stat); /* Free descriptor */ | 319 | writeb(0, &desc->stat); /* Free descriptor */ |
320 | count++; | ||
319 | port->txlast = (port->txlast + 1) % card->tx_ring_buffers; | 321 | port->txlast = (port->txlast + 1) % card->tx_ring_buffers; |
320 | } | 322 | } |
321 | 323 | ||
322 | netif_wake_queue(dev); | 324 | if (count) |
325 | netif_wake_queue(dev); | ||
323 | spin_unlock(&port->lock); | 326 | spin_unlock(&port->lock); |
324 | } | 327 | } |
325 | 328 | ||
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 8251946842e6..42ed923cdb1a 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -1917,7 +1917,8 @@ ath5k_beacon_send(struct ath5k_softc *sc) | |||
1917 | sc->bmisscount = 0; | 1917 | sc->bmisscount = 0; |
1918 | } | 1918 | } |
1919 | 1919 | ||
1920 | if (sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) { | 1920 | if ((sc->opmode == NL80211_IFTYPE_AP && sc->num_ap_vifs > 1) || |
1921 | sc->opmode == NL80211_IFTYPE_MESH_POINT) { | ||
1921 | u64 tsf = ath5k_hw_get_tsf64(ah); | 1922 | u64 tsf = ath5k_hw_get_tsf64(ah); |
1922 | u32 tsftu = TSF_TO_TU(tsf); | 1923 | u32 tsftu = TSF_TO_TU(tsf); |
1923 | int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval; | 1924 | int slot = ((tsftu % sc->bintval) * ATH_BCBUF) / sc->bintval; |
@@ -1949,8 +1950,9 @@ ath5k_beacon_send(struct ath5k_softc *sc) | |||
1949 | /* NB: hw still stops DMA, so proceed */ | 1950 | /* NB: hw still stops DMA, so proceed */ |
1950 | } | 1951 | } |
1951 | 1952 | ||
1952 | /* refresh the beacon for AP mode */ | 1953 | /* refresh the beacon for AP or MESH mode */ |
1953 | if (sc->opmode == NL80211_IFTYPE_AP) | 1954 | if (sc->opmode == NL80211_IFTYPE_AP || |
1955 | sc->opmode == NL80211_IFTYPE_MESH_POINT) | ||
1954 | ath5k_beacon_update(sc->hw, vif); | 1956 | ath5k_beacon_update(sc->hw, vif); |
1955 | 1957 | ||
1956 | ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); | 1958 | ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); |
@@ -2851,7 +2853,8 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, | |||
2851 | 2853 | ||
2852 | /* Assign the vap/adhoc to a beacon xmit slot. */ | 2854 | /* Assign the vap/adhoc to a beacon xmit slot. */ |
2853 | if ((avf->opmode == NL80211_IFTYPE_AP) || | 2855 | if ((avf->opmode == NL80211_IFTYPE_AP) || |
2854 | (avf->opmode == NL80211_IFTYPE_ADHOC)) { | 2856 | (avf->opmode == NL80211_IFTYPE_ADHOC) || |
2857 | (avf->opmode == NL80211_IFTYPE_MESH_POINT)) { | ||
2855 | int slot; | 2858 | int slot; |
2856 | 2859 | ||
2857 | WARN_ON(list_empty(&sc->bcbuf)); | 2860 | WARN_ON(list_empty(&sc->bcbuf)); |
@@ -2870,7 +2873,7 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, | |||
2870 | sc->bslot[avf->bslot] = vif; | 2873 | sc->bslot[avf->bslot] = vif; |
2871 | if (avf->opmode == NL80211_IFTYPE_AP) | 2874 | if (avf->opmode == NL80211_IFTYPE_AP) |
2872 | sc->num_ap_vifs++; | 2875 | sc->num_ap_vifs++; |
2873 | else | 2876 | else if (avf->opmode == NL80211_IFTYPE_ADHOC) |
2874 | sc->num_adhoc_vifs++; | 2877 | sc->num_adhoc_vifs++; |
2875 | } | 2878 | } |
2876 | 2879 | ||
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c index c4182359bee4..a7b82f0085d2 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c | |||
@@ -55,6 +55,8 @@ | |||
55 | #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ | 55 | #define SUB_NUM_CTL_MODES_AT_5G_40 2 /* excluding HT40, EXT-OFDM */ |
56 | #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ | 56 | #define SUB_NUM_CTL_MODES_AT_2G_40 3 /* excluding HT40, EXT-OFDM, EXT-CCK */ |
57 | 57 | ||
58 | #define CTL(_tpower, _flag) ((_tpower) | ((_flag) << 6)) | ||
59 | |||
58 | static const struct ar9300_eeprom ar9300_default = { | 60 | static const struct ar9300_eeprom ar9300_default = { |
59 | .eepromVersion = 2, | 61 | .eepromVersion = 2, |
60 | .templateVersion = 2, | 62 | .templateVersion = 2, |
@@ -290,20 +292,21 @@ static const struct ar9300_eeprom ar9300_default = { | |||
290 | } | 292 | } |
291 | }, | 293 | }, |
292 | .ctlPowerData_2G = { | 294 | .ctlPowerData_2G = { |
293 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | 295 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
294 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | 296 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
295 | { { {60, 1}, {60, 0}, {60, 0}, {60, 1} } }, | 297 | { { CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 1) } }, |
296 | 298 | ||
297 | { { {60, 1}, {60, 0}, {0, 0}, {0, 0} } }, | 299 | { { CTL(60, 1), CTL(60, 0), CTL(0, 0), CTL(0, 0) } }, |
298 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | 300 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
299 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | 301 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
300 | 302 | ||
301 | { { {60, 0}, {60, 1}, {60, 1}, {60, 0} } }, | 303 | { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0) } }, |
302 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | 304 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
303 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | 305 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
304 | 306 | ||
305 | { { {60, 0}, {60, 1}, {60, 0}, {60, 0} } }, | 307 | { { CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 0) } }, |
306 | { { {60, 0}, {60, 1}, {60, 1}, {60, 1} } }, | 308 | { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } }, |
309 | { { CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 1) } }, | ||
307 | }, | 310 | }, |
308 | .modalHeader5G = { | 311 | .modalHeader5G = { |
309 | /* 4 idle,t1,t2,b (4 bits per setting) */ | 312 | /* 4 idle,t1,t2,b (4 bits per setting) */ |
@@ -568,56 +571,56 @@ static const struct ar9300_eeprom ar9300_default = { | |||
568 | .ctlPowerData_5G = { | 571 | .ctlPowerData_5G = { |
569 | { | 572 | { |
570 | { | 573 | { |
571 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | 574 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), |
572 | {60, 1}, {60, 1}, {60, 1}, {60, 0}, | 575 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0), |
573 | } | 576 | } |
574 | }, | 577 | }, |
575 | { | 578 | { |
576 | { | 579 | { |
577 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | 580 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), |
578 | {60, 1}, {60, 1}, {60, 1}, {60, 0}, | 581 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0), |
579 | } | 582 | } |
580 | }, | 583 | }, |
581 | { | 584 | { |
582 | { | 585 | { |
583 | {60, 0}, {60, 1}, {60, 0}, {60, 1}, | 586 | CTL(60, 0), CTL(60, 1), CTL(60, 0), CTL(60, 1), |
584 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | 587 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), |
585 | } | 588 | } |
586 | }, | 589 | }, |
587 | { | 590 | { |
588 | { | 591 | { |
589 | {60, 0}, {60, 1}, {60, 1}, {60, 0}, | 592 | CTL(60, 0), CTL(60, 1), CTL(60, 1), CTL(60, 0), |
590 | {60, 1}, {60, 0}, {60, 0}, {60, 0}, | 593 | CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0), |
591 | } | 594 | } |
592 | }, | 595 | }, |
593 | { | 596 | { |
594 | { | 597 | { |
595 | {60, 1}, {60, 1}, {60, 1}, {60, 0}, | 598 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0), |
596 | {60, 0}, {60, 0}, {60, 0}, {60, 0}, | 599 | CTL(60, 0), CTL(60, 0), CTL(60, 0), CTL(60, 0), |
597 | } | 600 | } |
598 | }, | 601 | }, |
599 | { | 602 | { |
600 | { | 603 | { |
601 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | 604 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), |
602 | {60, 1}, {60, 0}, {60, 0}, {60, 0}, | 605 | CTL(60, 1), CTL(60, 0), CTL(60, 0), CTL(60, 0), |
603 | } | 606 | } |
604 | }, | 607 | }, |
605 | { | 608 | { |
606 | { | 609 | { |
607 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | 610 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), |
608 | {60, 1}, {60, 1}, {60, 1}, {60, 1}, | 611 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 1), |
609 | } | 612 | } |
610 | }, | 613 | }, |
611 | { | 614 | { |
612 | { | 615 | { |
613 | {60, 1}, {60, 1}, {60, 0}, {60, 1}, | 616 | CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1), |
614 | {60, 1}, {60, 1}, {60, 1}, {60, 0}, | 617 | CTL(60, 1), CTL(60, 1), CTL(60, 1), CTL(60, 0), |
615 | } | 618 | } |
616 | }, | 619 | }, |
617 | { | 620 | { |
618 | { | 621 | { |
619 | {60, 1}, {60, 0}, {60, 1}, {60, 1}, | 622 | CTL(60, 1), CTL(60, 0), CTL(60, 1), CTL(60, 1), |
620 | {60, 1}, {60, 1}, {60, 0}, {60, 1}, | 623 | CTL(60, 1), CTL(60, 1), CTL(60, 0), CTL(60, 1), |
621 | } | 624 | } |
622 | }, | 625 | }, |
623 | } | 626 | } |
@@ -1827,9 +1830,9 @@ static u16 ar9003_hw_get_direct_edge_power(struct ar9300_eeprom *eep, | |||
1827 | struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G; | 1830 | struct cal_ctl_data_5g *ctl_5g = eep->ctlPowerData_5G; |
1828 | 1831 | ||
1829 | if (is2GHz) | 1832 | if (is2GHz) |
1830 | return ctl_2g[idx].ctlEdges[edge].tPower; | 1833 | return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge]); |
1831 | else | 1834 | else |
1832 | return ctl_5g[idx].ctlEdges[edge].tPower; | 1835 | return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge]); |
1833 | } | 1836 | } |
1834 | 1837 | ||
1835 | static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep, | 1838 | static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep, |
@@ -1847,12 +1850,12 @@ static u16 ar9003_hw_get_indirect_edge_power(struct ar9300_eeprom *eep, | |||
1847 | 1850 | ||
1848 | if (is2GHz) { | 1851 | if (is2GHz) { |
1849 | if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq && | 1852 | if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 1) < freq && |
1850 | ctl_2g[idx].ctlEdges[edge - 1].flag) | 1853 | CTL_EDGE_FLAGS(ctl_2g[idx].ctlEdges[edge - 1])) |
1851 | return ctl_2g[idx].ctlEdges[edge - 1].tPower; | 1854 | return CTL_EDGE_TPOWER(ctl_2g[idx].ctlEdges[edge - 1]); |
1852 | } else { | 1855 | } else { |
1853 | if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq && | 1856 | if (ath9k_hw_fbin2freq(ctl_freqbin[edge - 1], 0) < freq && |
1854 | ctl_5g[idx].ctlEdges[edge - 1].flag) | 1857 | CTL_EDGE_FLAGS(ctl_5g[idx].ctlEdges[edge - 1])) |
1855 | return ctl_5g[idx].ctlEdges[edge - 1].tPower; | 1858 | return CTL_EDGE_TPOWER(ctl_5g[idx].ctlEdges[edge - 1]); |
1856 | } | 1859 | } |
1857 | 1860 | ||
1858 | return AR9300_MAX_RATE_POWER; | 1861 | return AR9300_MAX_RATE_POWER; |
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h index 3c533bb983c7..655b3033396c 100644 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h | |||
@@ -261,17 +261,12 @@ struct cal_tgt_pow_ht { | |||
261 | u8 tPow2x[14]; | 261 | u8 tPow2x[14]; |
262 | } __packed; | 262 | } __packed; |
263 | 263 | ||
264 | struct cal_ctl_edge_pwr { | ||
265 | u8 tPower:6, | ||
266 | flag:2; | ||
267 | } __packed; | ||
268 | |||
269 | struct cal_ctl_data_2g { | 264 | struct cal_ctl_data_2g { |
270 | struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_2G]; | 265 | u8 ctlEdges[AR9300_NUM_BAND_EDGES_2G]; |
271 | } __packed; | 266 | } __packed; |
272 | 267 | ||
273 | struct cal_ctl_data_5g { | 268 | struct cal_ctl_data_5g { |
274 | struct cal_ctl_edge_pwr ctlEdges[AR9300_NUM_BAND_EDGES_5G]; | 269 | u8 ctlEdges[AR9300_NUM_BAND_EDGES_5G]; |
275 | } __packed; | 270 | } __packed; |
276 | 271 | ||
277 | struct ar9300_eeprom { | 272 | struct ar9300_eeprom { |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 170d44a35ccb..0963071e8f90 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/device.h> | 21 | #include <linux/device.h> |
22 | #include <linux/leds.h> | 22 | #include <linux/leds.h> |
23 | #include <linux/completion.h> | 23 | #include <linux/completion.h> |
24 | #include <linux/pm_qos_params.h> | ||
24 | 25 | ||
25 | #include "debug.h" | 26 | #include "debug.h" |
26 | #include "common.h" | 27 | #include "common.h" |
@@ -328,7 +329,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp); | |||
328 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); | 329 | struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype); |
329 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); | 330 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq); |
330 | int ath_tx_setup(struct ath_softc *sc, int haltype); | 331 | int ath_tx_setup(struct ath_softc *sc, int haltype); |
331 | void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx); | 332 | bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx); |
332 | void ath_draintxq(struct ath_softc *sc, | 333 | void ath_draintxq(struct ath_softc *sc, |
333 | struct ath_txq *txq, bool retry_tx); | 334 | struct ath_txq *txq, bool retry_tx); |
334 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); | 335 | void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an); |
@@ -646,6 +647,8 @@ struct ath_softc { | |||
646 | struct ath_descdma txsdma; | 647 | struct ath_descdma txsdma; |
647 | 648 | ||
648 | struct ath_ant_comb ant_comb; | 649 | struct ath_ant_comb ant_comb; |
650 | |||
651 | struct pm_qos_request_list pm_qos_req; | ||
649 | }; | 652 | }; |
650 | 653 | ||
651 | struct ath_wiphy { | 654 | struct ath_wiphy { |
@@ -675,7 +678,6 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz) | |||
675 | } | 678 | } |
676 | 679 | ||
677 | extern struct ieee80211_ops ath9k_ops; | 680 | extern struct ieee80211_ops ath9k_ops; |
678 | extern struct pm_qos_request_list ath9k_pm_qos_req; | ||
679 | extern int modparam_nohwcrypt; | 681 | extern int modparam_nohwcrypt; |
680 | extern int led_blink; | 682 | extern int led_blink; |
681 | 683 | ||
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c index 1266333f586d..2bbf94d0191e 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.c +++ b/drivers/net/wireless/ath/ath9k/eeprom.c | |||
@@ -240,16 +240,16 @@ u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower, | |||
240 | for (i = 0; (i < num_band_edges) && | 240 | for (i = 0; (i < num_band_edges) && |
241 | (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) { | 241 | (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) { |
242 | if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) { | 242 | if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) { |
243 | twiceMaxEdgePower = pRdEdgesPower[i].tPower; | 243 | twiceMaxEdgePower = CTL_EDGE_TPOWER(pRdEdgesPower[i].ctl); |
244 | break; | 244 | break; |
245 | } else if ((i > 0) && | 245 | } else if ((i > 0) && |
246 | (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, | 246 | (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, |
247 | is2GHz))) { | 247 | is2GHz))) { |
248 | if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel, | 248 | if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel, |
249 | is2GHz) < freq && | 249 | is2GHz) < freq && |
250 | pRdEdgesPower[i - 1].flag) { | 250 | CTL_EDGE_FLAGS(pRdEdgesPower[i - 1].ctl)) { |
251 | twiceMaxEdgePower = | 251 | twiceMaxEdgePower = |
252 | pRdEdgesPower[i - 1].tPower; | 252 | CTL_EDGE_TPOWER(pRdEdgesPower[i - 1].ctl); |
253 | } | 253 | } |
254 | break; | 254 | break; |
255 | } | 255 | } |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h index dacb45e1b906..dd59f09441a3 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom.h +++ b/drivers/net/wireless/ath/ath9k/eeprom.h | |||
@@ -233,6 +233,18 @@ | |||
233 | 233 | ||
234 | #define AR9287_CHECKSUM_LOCATION (AR9287_EEP_START_LOC + 1) | 234 | #define AR9287_CHECKSUM_LOCATION (AR9287_EEP_START_LOC + 1) |
235 | 235 | ||
236 | #define CTL_EDGE_TPOWER(_ctl) ((_ctl) & 0x3f) | ||
237 | #define CTL_EDGE_FLAGS(_ctl) (((_ctl) >> 6) & 0x03) | ||
238 | |||
239 | #define LNA_CTL_BUF_MODE BIT(0) | ||
240 | #define LNA_CTL_ISEL_LO BIT(1) | ||
241 | #define LNA_CTL_ISEL_HI BIT(2) | ||
242 | #define LNA_CTL_BUF_IN BIT(3) | ||
243 | #define LNA_CTL_FEM_BAND BIT(4) | ||
244 | #define LNA_CTL_LOCAL_BIAS BIT(5) | ||
245 | #define LNA_CTL_FORCE_XPA BIT(6) | ||
246 | #define LNA_CTL_USE_ANT1 BIT(7) | ||
247 | |||
236 | enum eeprom_param { | 248 | enum eeprom_param { |
237 | EEP_NFTHRESH_5, | 249 | EEP_NFTHRESH_5, |
238 | EEP_NFTHRESH_2, | 250 | EEP_NFTHRESH_2, |
@@ -378,10 +390,7 @@ struct modal_eep_header { | |||
378 | u8 xatten2Margin[AR5416_MAX_CHAINS]; | 390 | u8 xatten2Margin[AR5416_MAX_CHAINS]; |
379 | u8 ob_ch1; | 391 | u8 ob_ch1; |
380 | u8 db_ch1; | 392 | u8 db_ch1; |
381 | u8 useAnt1:1, | 393 | u8 lna_ctl; |
382 | force_xpaon:1, | ||
383 | local_bias:1, | ||
384 | femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1; | ||
385 | u8 miscBits; | 394 | u8 miscBits; |
386 | u16 xpaBiasLvlFreq[3]; | 395 | u16 xpaBiasLvlFreq[3]; |
387 | u8 futureModal[6]; | 396 | u8 futureModal[6]; |
@@ -535,18 +544,10 @@ struct cal_target_power_ht { | |||
535 | u8 tPow2x[8]; | 544 | u8 tPow2x[8]; |
536 | } __packed; | 545 | } __packed; |
537 | 546 | ||
538 | |||
539 | #ifdef __BIG_ENDIAN_BITFIELD | ||
540 | struct cal_ctl_edges { | ||
541 | u8 bChannel; | ||
542 | u8 flag:2, tPower:6; | ||
543 | } __packed; | ||
544 | #else | ||
545 | struct cal_ctl_edges { | 547 | struct cal_ctl_edges { |
546 | u8 bChannel; | 548 | u8 bChannel; |
547 | u8 tPower:6, flag:2; | 549 | u8 ctl; |
548 | } __packed; | 550 | } __packed; |
549 | #endif | ||
550 | 551 | ||
551 | struct cal_data_op_loop_ar9287 { | 552 | struct cal_data_op_loop_ar9287 { |
552 | u8 pwrPdg[2][5]; | 553 | u8 pwrPdg[2][5]; |
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c index 76b4d65472dd..a3ccb1b9638d 100644 --- a/drivers/net/wireless/ath/ath9k/eeprom_def.c +++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c | |||
@@ -451,9 +451,10 @@ static void ath9k_hw_def_set_board_values(struct ath_hw *ah, | |||
451 | ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2, | 451 | ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2, |
452 | AR_AN_TOP2_LOCALBIAS, | 452 | AR_AN_TOP2_LOCALBIAS, |
453 | AR_AN_TOP2_LOCALBIAS_S, | 453 | AR_AN_TOP2_LOCALBIAS_S, |
454 | pModal->local_bias); | 454 | !!(pModal->lna_ctl & |
455 | LNA_CTL_LOCAL_BIAS)); | ||
455 | REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG, | 456 | REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG, |
456 | pModal->force_xpaon); | 457 | !!(pModal->lna_ctl & LNA_CTL_FORCE_XPA)); |
457 | } | 458 | } |
458 | 459 | ||
459 | REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, | 460 | REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, |
@@ -1062,15 +1063,19 @@ static void ath9k_hw_set_def_power_per_rate_table(struct ath_hw *ah, | |||
1062 | case 1: | 1063 | case 1: |
1063 | break; | 1064 | break; |
1064 | case 2: | 1065 | case 2: |
1065 | scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; | 1066 | if (scaledPower > REDUCE_SCALED_POWER_BY_TWO_CHAIN) |
1067 | scaledPower -= REDUCE_SCALED_POWER_BY_TWO_CHAIN; | ||
1068 | else | ||
1069 | scaledPower = 0; | ||
1066 | break; | 1070 | break; |
1067 | case 3: | 1071 | case 3: |
1068 | scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; | 1072 | if (scaledPower > REDUCE_SCALED_POWER_BY_THREE_CHAIN) |
1073 | scaledPower -= REDUCE_SCALED_POWER_BY_THREE_CHAIN; | ||
1074 | else | ||
1075 | scaledPower = 0; | ||
1069 | break; | 1076 | break; |
1070 | } | 1077 | } |
1071 | 1078 | ||
1072 | scaledPower = max((u16)0, scaledPower); | ||
1073 | |||
1074 | if (IS_CHAN_2GHZ(chan)) { | 1079 | if (IS_CHAN_2GHZ(chan)) { |
1075 | numCtlModes = ARRAY_SIZE(ctlModesFor11g) - | 1080 | numCtlModes = ARRAY_SIZE(ctlModesFor11g) - |
1076 | SUB_NUM_CTL_MODES_AT_2G_40; | 1081 | SUB_NUM_CTL_MODES_AT_2G_40; |
@@ -1428,9 +1433,9 @@ static u8 ath9k_hw_def_get_num_ant_config(struct ath_hw *ah, | |||
1428 | 1433 | ||
1429 | num_ant_config = 1; | 1434 | num_ant_config = 1; |
1430 | 1435 | ||
1431 | if (pBase->version >= 0x0E0D) | 1436 | if (pBase->version >= 0x0E0D && |
1432 | if (pModal->useAnt1) | 1437 | (pModal->lna_ctl & LNA_CTL_USE_ANT1)) |
1433 | num_ant_config += 1; | 1438 | num_ant_config += 1; |
1434 | 1439 | ||
1435 | return num_ant_config; | 1440 | return num_ant_config; |
1436 | } | 1441 | } |
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c index dfb6560dab92..0de3c3d3c245 100644 --- a/drivers/net/wireless/ath/ath9k/hif_usb.c +++ b/drivers/net/wireless/ath/ath9k/hif_usb.c | |||
@@ -1024,6 +1024,13 @@ static int ath9k_hif_usb_suspend(struct usb_interface *interface, | |||
1024 | struct hif_device_usb *hif_dev = | 1024 | struct hif_device_usb *hif_dev = |
1025 | (struct hif_device_usb *) usb_get_intfdata(interface); | 1025 | (struct hif_device_usb *) usb_get_intfdata(interface); |
1026 | 1026 | ||
1027 | /* | ||
1028 | * The device has to be set to FULLSLEEP mode in case no | ||
1029 | * interface is up. | ||
1030 | */ | ||
1031 | if (!(hif_dev->flags & HIF_USB_START)) | ||
1032 | ath9k_htc_suspend(hif_dev->htc_handle); | ||
1033 | |||
1027 | ath9k_hif_usb_dealloc_urbs(hif_dev); | 1034 | ath9k_hif_usb_dealloc_urbs(hif_dev); |
1028 | 1035 | ||
1029 | return 0; | 1036 | return 0; |
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h index 75ecf6a30d25..c3b561daa6c1 100644 --- a/drivers/net/wireless/ath/ath9k/htc.h +++ b/drivers/net/wireless/ath/ath9k/htc.h | |||
@@ -455,6 +455,8 @@ u32 ath9k_htc_calcrxfilter(struct ath9k_htc_priv *priv); | |||
455 | void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv); | 455 | void ath9k_htc_ps_wakeup(struct ath9k_htc_priv *priv); |
456 | void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv); | 456 | void ath9k_htc_ps_restore(struct ath9k_htc_priv *priv); |
457 | void ath9k_ps_work(struct work_struct *work); | 457 | void ath9k_ps_work(struct work_struct *work); |
458 | bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, | ||
459 | enum ath9k_power_mode mode); | ||
458 | 460 | ||
459 | void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); | 461 | void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); |
460 | void ath9k_init_leds(struct ath9k_htc_priv *priv); | 462 | void ath9k_init_leds(struct ath9k_htc_priv *priv); |
@@ -464,6 +466,7 @@ int ath9k_htc_probe_device(struct htc_target *htc_handle, struct device *dev, | |||
464 | u16 devid, char *product); | 466 | u16 devid, char *product); |
465 | void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug); | 467 | void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug); |
466 | #ifdef CONFIG_PM | 468 | #ifdef CONFIG_PM |
469 | void ath9k_htc_suspend(struct htc_target *htc_handle); | ||
467 | int ath9k_htc_resume(struct htc_target *htc_handle); | 470 | int ath9k_htc_resume(struct htc_target *htc_handle); |
468 | #endif | 471 | #endif |
469 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS | 472 | #ifdef CONFIG_ATH9K_HTC_DEBUGFS |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c index 7c8a38d04561..8776f49ffd41 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c | |||
@@ -891,6 +891,12 @@ void ath9k_htc_disconnect_device(struct htc_target *htc_handle, bool hotunplug) | |||
891 | } | 891 | } |
892 | 892 | ||
893 | #ifdef CONFIG_PM | 893 | #ifdef CONFIG_PM |
894 | |||
895 | void ath9k_htc_suspend(struct htc_target *htc_handle) | ||
896 | { | ||
897 | ath9k_htc_setpower(htc_handle->drv_priv, ATH9K_PM_FULL_SLEEP); | ||
898 | } | ||
899 | |||
894 | int ath9k_htc_resume(struct htc_target *htc_handle) | 900 | int ath9k_htc_resume(struct htc_target *htc_handle) |
895 | { | 901 | { |
896 | int ret; | 902 | int ret; |
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c index 9a3be8da755d..51977caca47f 100644 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c | |||
@@ -63,8 +63,8 @@ static enum htc_phymode ath9k_htc_get_curmode(struct ath9k_htc_priv *priv, | |||
63 | return mode; | 63 | return mode; |
64 | } | 64 | } |
65 | 65 | ||
66 | static bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, | 66 | bool ath9k_htc_setpower(struct ath9k_htc_priv *priv, |
67 | enum ath9k_power_mode mode) | 67 | enum ath9k_power_mode mode) |
68 | { | 68 | { |
69 | bool ret; | 69 | bool ret; |
70 | 70 | ||
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c index 6ebc68bca91f..c7fbe25cc128 100644 --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c | |||
@@ -2044,7 +2044,8 @@ u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio) | |||
2044 | val = REG_READ(ah, AR7010_GPIO_IN); | 2044 | val = REG_READ(ah, AR7010_GPIO_IN); |
2045 | return (MS(val, AR7010_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) == 0; | 2045 | return (MS(val, AR7010_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) == 0; |
2046 | } else if (AR_SREV_9300_20_OR_LATER(ah)) | 2046 | } else if (AR_SREV_9300_20_OR_LATER(ah)) |
2047 | return MS_REG_READ(AR9300, gpio) != 0; | 2047 | return (MS(REG_READ(ah, AR_GPIO_IN), AR9300_GPIO_IN_VAL) & |
2048 | AR_GPIO_BIT(gpio)) != 0; | ||
2048 | else if (AR_SREV_9271(ah)) | 2049 | else if (AR_SREV_9271(ah)) |
2049 | return MS_REG_READ(AR9271, gpio) != 0; | 2050 | return MS_REG_READ(AR9271, gpio) != 0; |
2050 | else if (AR_SREV_9287_11_OR_LATER(ah)) | 2051 | else if (AR_SREV_9287_11_OR_LATER(ah)) |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index 92bc5c5f4876..14b8ab386daf 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -15,7 +15,6 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/pm_qos_params.h> | ||
19 | 18 | ||
20 | #include "ath9k.h" | 19 | #include "ath9k.h" |
21 | 20 | ||
@@ -180,8 +179,6 @@ static const struct ath_ops ath9k_common_ops = { | |||
180 | .write = ath9k_iowrite32, | 179 | .write = ath9k_iowrite32, |
181 | }; | 180 | }; |
182 | 181 | ||
183 | struct pm_qos_request_list ath9k_pm_qos_req; | ||
184 | |||
185 | /**************************/ | 182 | /**************************/ |
186 | /* Initialization */ | 183 | /* Initialization */ |
187 | /**************************/ | 184 | /**************************/ |
@@ -664,6 +661,8 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | |||
664 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; | 661 | hw->flags |= IEEE80211_HW_MFP_CAPABLE; |
665 | 662 | ||
666 | hw->wiphy->interface_modes = | 663 | hw->wiphy->interface_modes = |
664 | BIT(NL80211_IFTYPE_P2P_GO) | | ||
665 | BIT(NL80211_IFTYPE_P2P_CLIENT) | | ||
667 | BIT(NL80211_IFTYPE_AP) | | 666 | BIT(NL80211_IFTYPE_AP) | |
668 | BIT(NL80211_IFTYPE_WDS) | | 667 | BIT(NL80211_IFTYPE_WDS) | |
669 | BIT(NL80211_IFTYPE_STATION) | | 668 | BIT(NL80211_IFTYPE_STATION) | |
@@ -759,7 +758,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, | |||
759 | ath_init_leds(sc); | 758 | ath_init_leds(sc); |
760 | ath_start_rfkill_poll(sc); | 759 | ath_start_rfkill_poll(sc); |
761 | 760 | ||
762 | pm_qos_add_request(&ath9k_pm_qos_req, PM_QOS_CPU_DMA_LATENCY, | 761 | pm_qos_add_request(&sc->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, |
763 | PM_QOS_DEFAULT_VALUE); | 762 | PM_QOS_DEFAULT_VALUE); |
764 | 763 | ||
765 | return 0; | 764 | return 0; |
@@ -830,7 +829,7 @@ void ath9k_deinit_device(struct ath_softc *sc) | |||
830 | } | 829 | } |
831 | 830 | ||
832 | ieee80211_unregister_hw(hw); | 831 | ieee80211_unregister_hw(hw); |
833 | pm_qos_remove_request(&ath9k_pm_qos_req); | 832 | pm_qos_remove_request(&sc->pm_qos_req); |
834 | ath_rx_cleanup(sc); | 833 | ath_rx_cleanup(sc); |
835 | ath_tx_cleanup(sc); | 834 | ath_tx_cleanup(sc); |
836 | ath9k_deinit_softc(sc); | 835 | ath9k_deinit_softc(sc); |
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 8c13479b17cd..c996963ab339 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
@@ -703,8 +703,7 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, | |||
703 | rs->rs_phyerr = phyerr; | 703 | rs->rs_phyerr = phyerr; |
704 | } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) | 704 | } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) |
705 | rs->rs_status |= ATH9K_RXERR_DECRYPT; | 705 | rs->rs_status |= ATH9K_RXERR_DECRYPT; |
706 | else if ((ads.ds_rxstatus8 & AR_MichaelErr) && | 706 | else if (ads.ds_rxstatus8 & AR_MichaelErr) |
707 | rs->rs_keyix != ATH9K_RXKEYIX_INVALID) | ||
708 | rs->rs_status |= ATH9K_RXERR_MIC; | 707 | rs->rs_status |= ATH9K_RXERR_MIC; |
709 | else if (ads.ds_rxstatus8 & AR_KeyMiss) | 708 | else if (ads.ds_rxstatus8 & AR_KeyMiss) |
710 | rs->rs_status |= ATH9K_RXERR_DECRYPT; | 709 | rs->rs_status |= ATH9K_RXERR_DECRYPT; |
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 25d3ef4c338e..c0c3464d3a86 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -15,7 +15,6 @@ | |||
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/nl80211.h> | 17 | #include <linux/nl80211.h> |
18 | #include <linux/pm_qos_params.h> | ||
19 | #include "ath9k.h" | 18 | #include "ath9k.h" |
20 | #include "btcoex.h" | 19 | #include "btcoex.h" |
21 | 20 | ||
@@ -245,11 +244,12 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, | |||
245 | * the relevant bits of the h/w. | 244 | * the relevant bits of the h/w. |
246 | */ | 245 | */ |
247 | ath9k_hw_set_interrupts(ah, 0); | 246 | ath9k_hw_set_interrupts(ah, 0); |
248 | ath_drain_all_txq(sc, false); | 247 | stopped = ath_drain_all_txq(sc, false); |
249 | 248 | ||
250 | spin_lock_bh(&sc->rx.pcu_lock); | 249 | spin_lock_bh(&sc->rx.pcu_lock); |
251 | 250 | ||
252 | stopped = ath_stoprecv(sc); | 251 | if (!ath_stoprecv(sc)) |
252 | stopped = false; | ||
253 | 253 | ||
254 | /* XXX: do not flush receive queue here. We don't want | 254 | /* XXX: do not flush receive queue here. We don't want |
255 | * to flush data frames already in queue because of | 255 | * to flush data frames already in queue because of |
@@ -1244,7 +1244,7 @@ static int ath9k_start(struct ieee80211_hw *hw) | |||
1244 | ath9k_btcoex_timer_resume(sc); | 1244 | ath9k_btcoex_timer_resume(sc); |
1245 | } | 1245 | } |
1246 | 1246 | ||
1247 | pm_qos_update_request(&ath9k_pm_qos_req, 55); | 1247 | pm_qos_update_request(&sc->pm_qos_req, 55); |
1248 | 1248 | ||
1249 | mutex_unlock: | 1249 | mutex_unlock: |
1250 | mutex_unlock(&sc->mutex); | 1250 | mutex_unlock(&sc->mutex); |
@@ -1423,7 +1423,7 @@ static void ath9k_stop(struct ieee80211_hw *hw) | |||
1423 | 1423 | ||
1424 | sc->sc_flags |= SC_OP_INVALID; | 1424 | sc->sc_flags |= SC_OP_INVALID; |
1425 | 1425 | ||
1426 | pm_qos_update_request(&ath9k_pm_qos_req, PM_QOS_DEFAULT_VALUE); | 1426 | pm_qos_update_request(&sc->pm_qos_req, PM_QOS_DEFAULT_VALUE); |
1427 | 1427 | ||
1428 | mutex_unlock(&sc->mutex); | 1428 | mutex_unlock(&sc->mutex); |
1429 | 1429 | ||
@@ -1520,7 +1520,6 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
1520 | struct ath_softc *sc = aphy->sc; | 1520 | struct ath_softc *sc = aphy->sc; |
1521 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1521 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
1522 | struct ath_vif *avp = (void *)vif->drv_priv; | 1522 | struct ath_vif *avp = (void *)vif->drv_priv; |
1523 | int i; | ||
1524 | 1523 | ||
1525 | ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); | 1524 | ath_print(common, ATH_DBG_CONFIG, "Detach Interface\n"); |
1526 | 1525 | ||
@@ -1534,21 +1533,24 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw, | |||
1534 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || | 1533 | if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || |
1535 | (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || | 1534 | (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC) || |
1536 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { | 1535 | (sc->sc_ah->opmode == NL80211_IFTYPE_MESH_POINT)) { |
1536 | /* Disable SWBA interrupt */ | ||
1537 | sc->sc_ah->imask &= ~ATH9K_INT_SWBA; | ||
1537 | ath9k_ps_wakeup(sc); | 1538 | ath9k_ps_wakeup(sc); |
1539 | ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); | ||
1538 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 1540 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
1539 | ath9k_ps_restore(sc); | 1541 | ath9k_ps_restore(sc); |
1542 | tasklet_kill(&sc->bcon_tasklet); | ||
1540 | } | 1543 | } |
1541 | 1544 | ||
1542 | ath_beacon_return(sc, avp); | 1545 | ath_beacon_return(sc, avp); |
1543 | sc->sc_flags &= ~SC_OP_BEACONS; | 1546 | sc->sc_flags &= ~SC_OP_BEACONS; |
1544 | 1547 | ||
1545 | for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) { | 1548 | if (sc->nbcnvifs) { |
1546 | if (sc->beacon.bslot[i] == vif) { | 1549 | /* Re-enable SWBA interrupt */ |
1547 | printk(KERN_DEBUG "%s: vif had allocated beacon " | 1550 | sc->sc_ah->imask |= ATH9K_INT_SWBA; |
1548 | "slot\n", __func__); | 1551 | ath9k_ps_wakeup(sc); |
1549 | sc->beacon.bslot[i] = NULL; | 1552 | ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_ah->imask); |
1550 | sc->beacon.bslot_aphy[i] = NULL; | 1553 | ath9k_ps_restore(sc); |
1551 | } | ||
1552 | } | 1554 | } |
1553 | 1555 | ||
1554 | sc->nvifs--; | 1556 | sc->nvifs--; |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 1a62e351ec77..fdc2ec52b42f 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -838,6 +838,10 @@ static bool ath9k_rx_accept(struct ath_common *common, | |||
838 | struct ath_rx_status *rx_stats, | 838 | struct ath_rx_status *rx_stats, |
839 | bool *decrypt_error) | 839 | bool *decrypt_error) |
840 | { | 840 | { |
841 | #define is_mc_or_valid_tkip_keyix ((is_mc || \ | ||
842 | (rx_stats->rs_keyix != ATH9K_RXKEYIX_INVALID && \ | ||
843 | test_bit(rx_stats->rs_keyix, common->tkip_keymap)))) | ||
844 | |||
841 | struct ath_hw *ah = common->ah; | 845 | struct ath_hw *ah = common->ah; |
842 | __le16 fc; | 846 | __le16 fc; |
843 | u8 rx_status_len = ah->caps.rx_status_len; | 847 | u8 rx_status_len = ah->caps.rx_status_len; |
@@ -879,15 +883,18 @@ static bool ath9k_rx_accept(struct ath_common *common, | |||
879 | if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { | 883 | if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) { |
880 | *decrypt_error = true; | 884 | *decrypt_error = true; |
881 | } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) { | 885 | } else if (rx_stats->rs_status & ATH9K_RXERR_MIC) { |
886 | bool is_mc; | ||
882 | /* | 887 | /* |
883 | * The MIC error bit is only valid if the frame | 888 | * The MIC error bit is only valid if the frame |
884 | * is not a control frame or fragment, and it was | 889 | * is not a control frame or fragment, and it was |
885 | * decrypted using a valid TKIP key. | 890 | * decrypted using a valid TKIP key. |
886 | */ | 891 | */ |
892 | is_mc = !!is_multicast_ether_addr(hdr->addr1); | ||
893 | |||
887 | if (!ieee80211_is_ctl(fc) && | 894 | if (!ieee80211_is_ctl(fc) && |
888 | !ieee80211_has_morefrags(fc) && | 895 | !ieee80211_has_morefrags(fc) && |
889 | !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) && | 896 | !(le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG) && |
890 | test_bit(rx_stats->rs_keyix, common->tkip_keymap)) | 897 | is_mc_or_valid_tkip_keyix) |
891 | rxs->flag |= RX_FLAG_MMIC_ERROR; | 898 | rxs->flag |= RX_FLAG_MMIC_ERROR; |
892 | else | 899 | else |
893 | rx_stats->rs_status &= ~ATH9K_RXERR_MIC; | 900 | rx_stats->rs_status &= ~ATH9K_RXERR_MIC; |
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h index dddf579aacf1..2c6a22fbb0f0 100644 --- a/drivers/net/wireless/ath/ath9k/reg.h +++ b/drivers/net/wireless/ath/ath9k/reg.h | |||
@@ -984,11 +984,13 @@ enum { | |||
984 | #define AR9287_GPIO_IN_VAL_S 11 | 984 | #define AR9287_GPIO_IN_VAL_S 11 |
985 | #define AR9271_GPIO_IN_VAL 0xFFFF0000 | 985 | #define AR9271_GPIO_IN_VAL 0xFFFF0000 |
986 | #define AR9271_GPIO_IN_VAL_S 16 | 986 | #define AR9271_GPIO_IN_VAL_S 16 |
987 | #define AR9300_GPIO_IN_VAL 0x0001FFFF | ||
988 | #define AR9300_GPIO_IN_VAL_S 0 | ||
989 | #define AR7010_GPIO_IN_VAL 0x0000FFFF | 987 | #define AR7010_GPIO_IN_VAL 0x0000FFFF |
990 | #define AR7010_GPIO_IN_VAL_S 0 | 988 | #define AR7010_GPIO_IN_VAL_S 0 |
991 | 989 | ||
990 | #define AR_GPIO_IN 0x404c | ||
991 | #define AR9300_GPIO_IN_VAL 0x0001FFFF | ||
992 | #define AR9300_GPIO_IN_VAL_S 0 | ||
993 | |||
992 | #define AR_GPIO_OE_OUT (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c) | 994 | #define AR_GPIO_OE_OUT (AR_SREV_9300_20_OR_LATER(ah) ? 0x4050 : 0x404c) |
993 | #define AR_GPIO_OE_OUT_DRV 0x3 | 995 | #define AR_GPIO_OE_OUT_DRV 0x3 |
994 | #define AR_GPIO_OE_OUT_DRV_NO 0x0 | 996 | #define AR_GPIO_OE_OUT_DRV_NO 0x0 |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index f2ade2402ce2..aff04789f794 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -1120,7 +1120,7 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx) | |||
1120 | } | 1120 | } |
1121 | } | 1121 | } |
1122 | 1122 | ||
1123 | void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | 1123 | bool ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) |
1124 | { | 1124 | { |
1125 | struct ath_hw *ah = sc->sc_ah; | 1125 | struct ath_hw *ah = sc->sc_ah; |
1126 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); | 1126 | struct ath_common *common = ath9k_hw_common(sc->sc_ah); |
@@ -1128,7 +1128,7 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | |||
1128 | int i, npend = 0; | 1128 | int i, npend = 0; |
1129 | 1129 | ||
1130 | if (sc->sc_flags & SC_OP_INVALID) | 1130 | if (sc->sc_flags & SC_OP_INVALID) |
1131 | return; | 1131 | return true; |
1132 | 1132 | ||
1133 | /* Stop beacon queue */ | 1133 | /* Stop beacon queue */ |
1134 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); | 1134 | ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); |
@@ -1142,25 +1142,15 @@ void ath_drain_all_txq(struct ath_softc *sc, bool retry_tx) | |||
1142 | } | 1142 | } |
1143 | } | 1143 | } |
1144 | 1144 | ||
1145 | if (npend) { | 1145 | if (npend) |
1146 | int r; | 1146 | ath_print(common, ATH_DBG_FATAL, "Failed to stop TX DMA!\n"); |
1147 | |||
1148 | ath_print(common, ATH_DBG_FATAL, | ||
1149 | "Failed to stop TX DMA. Resetting hardware!\n"); | ||
1150 | |||
1151 | spin_lock_bh(&sc->sc_resetlock); | ||
1152 | r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, false); | ||
1153 | if (r) | ||
1154 | ath_print(common, ATH_DBG_FATAL, | ||
1155 | "Unable to reset hardware; reset status %d\n", | ||
1156 | r); | ||
1157 | spin_unlock_bh(&sc->sc_resetlock); | ||
1158 | } | ||
1159 | 1147 | ||
1160 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { | 1148 | for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) { |
1161 | if (ATH_TXQ_SETUP(sc, i)) | 1149 | if (ATH_TXQ_SETUP(sc, i)) |
1162 | ath_draintxq(sc, &sc->tx.txq[i], retry_tx); | 1150 | ath_draintxq(sc, &sc->tx.txq[i], retry_tx); |
1163 | } | 1151 | } |
1152 | |||
1153 | return !npend; | ||
1164 | } | 1154 | } |
1165 | 1155 | ||
1166 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq) | 1156 | void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq) |
diff --git a/drivers/net/wireless/ath/carl9170/fw.c b/drivers/net/wireless/ath/carl9170/fw.c index ae6c006bbc56..546b4e4ec5ea 100644 --- a/drivers/net/wireless/ath/carl9170/fw.c +++ b/drivers/net/wireless/ath/carl9170/fw.c | |||
@@ -291,7 +291,8 @@ static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len) | |||
291 | 291 | ||
292 | if (SUPP(CARL9170FW_WLANTX_CAB)) { | 292 | if (SUPP(CARL9170FW_WLANTX_CAB)) { |
293 | ar->hw->wiphy->interface_modes |= | 293 | ar->hw->wiphy->interface_modes |= |
294 | BIT(NL80211_IFTYPE_AP); | 294 | BIT(NL80211_IFTYPE_AP) | |
295 | BIT(NL80211_IFTYPE_P2P_GO); | ||
295 | } | 296 | } |
296 | } | 297 | } |
297 | 298 | ||
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c index a314c2c2bfbe..dc7b30b170d0 100644 --- a/drivers/net/wireless/ath/carl9170/main.c +++ b/drivers/net/wireless/ath/carl9170/main.c | |||
@@ -1631,7 +1631,8 @@ void *carl9170_alloc(size_t priv_size) | |||
1631 | * supports these modes. The code which will add the | 1631 | * supports these modes. The code which will add the |
1632 | * additional interface_modes is in fw.c. | 1632 | * additional interface_modes is in fw.c. |
1633 | */ | 1633 | */ |
1634 | hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); | 1634 | hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | |
1635 | BIT(NL80211_IFTYPE_P2P_CLIENT); | ||
1635 | 1636 | ||
1636 | hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | | 1637 | hw->flags |= IEEE80211_HW_RX_INCLUDES_FCS | |
1637 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | | 1638 | IEEE80211_HW_REPORTS_TX_ACK_STATUS | |
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c index b575c865142d..7e6506a77bbb 100644 --- a/drivers/net/wireless/ath/carl9170/tx.c +++ b/drivers/net/wireless/ath/carl9170/tx.c | |||
@@ -810,7 +810,7 @@ static int carl9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) | |||
810 | 810 | ||
811 | mac_tmp = cpu_to_le16(AR9170_TX_MAC_HW_DURATION | | 811 | mac_tmp = cpu_to_le16(AR9170_TX_MAC_HW_DURATION | |
812 | AR9170_TX_MAC_BACKOFF); | 812 | AR9170_TX_MAC_BACKOFF); |
813 | mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) && | 813 | mac_tmp |= cpu_to_le16((hw_queue << AR9170_TX_MAC_QOS_S) & |
814 | AR9170_TX_MAC_QOS); | 814 | AR9170_TX_MAC_QOS); |
815 | 815 | ||
816 | no_ack = !!(info->flags & IEEE80211_TX_CTL_NO_ACK); | 816 | no_ack = !!(info->flags & IEEE80211_TX_CTL_NO_ACK); |
diff --git a/drivers/net/wireless/hostap/hostap_main.c b/drivers/net/wireless/hostap/hostap_main.c index 25a2722c8a98..1d9aed645723 100644 --- a/drivers/net/wireless/hostap/hostap_main.c +++ b/drivers/net/wireless/hostap/hostap_main.c | |||
@@ -891,7 +891,6 @@ void hostap_setup_dev(struct net_device *dev, local_info_t *local, | |||
891 | 891 | ||
892 | SET_ETHTOOL_OPS(dev, &prism2_ethtool_ops); | 892 | SET_ETHTOOL_OPS(dev, &prism2_ethtool_ops); |
893 | 893 | ||
894 | netif_stop_queue(dev); | ||
895 | } | 894 | } |
896 | 895 | ||
897 | static int hostap_enable_hostapd(local_info_t *local, int rtnl_locked) | 896 | static int hostap_enable_hostapd(local_info_t *local, int rtnl_locked) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index db540910b110..0e027f787fbc 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -315,6 +315,7 @@ struct iwl_cfg iwl100_bgn_cfg = { | |||
315 | .mod_params = &iwlagn_mod_params, | 315 | .mod_params = &iwlagn_mod_params, |
316 | .base_params = &iwl1000_base_params, | 316 | .base_params = &iwl1000_base_params, |
317 | .ht_params = &iwl1000_ht_params, | 317 | .ht_params = &iwl1000_ht_params, |
318 | .use_new_eeprom_reading = true, | ||
318 | }; | 319 | }; |
319 | 320 | ||
320 | struct iwl_cfg iwl100_bg_cfg = { | 321 | struct iwl_cfg iwl100_bg_cfg = { |
@@ -330,6 +331,7 @@ struct iwl_cfg iwl100_bg_cfg = { | |||
330 | .ops = &iwl1000_ops, | 331 | .ops = &iwl1000_ops, |
331 | .mod_params = &iwlagn_mod_params, | 332 | .mod_params = &iwlagn_mod_params, |
332 | .base_params = &iwl1000_base_params, | 333 | .base_params = &iwl1000_base_params, |
334 | .use_new_eeprom_reading = true, | ||
333 | }; | 335 | }; |
334 | 336 | ||
335 | MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); | 337 | MODULE_FIRMWARE(IWL1000_MODULE_FIRMWARE(IWL1000_UCODE_API_MAX)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 11e6532fc573..0ceeaac85eda 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -561,6 +561,7 @@ struct iwl_cfg iwl6000g2a_2agn_cfg = { | |||
561 | .ht_params = &iwl6000_ht_params, | 561 | .ht_params = &iwl6000_ht_params, |
562 | .need_dc_calib = true, | 562 | .need_dc_calib = true, |
563 | .need_temp_offset_calib = true, | 563 | .need_temp_offset_calib = true, |
564 | .use_new_eeprom_reading = true, | ||
564 | }; | 565 | }; |
565 | 566 | ||
566 | struct iwl_cfg iwl6000g2a_2abg_cfg = { | 567 | struct iwl_cfg iwl6000g2a_2abg_cfg = { |
@@ -578,6 +579,7 @@ struct iwl_cfg iwl6000g2a_2abg_cfg = { | |||
578 | .base_params = &iwl6000_base_params, | 579 | .base_params = &iwl6000_base_params, |
579 | .need_dc_calib = true, | 580 | .need_dc_calib = true, |
580 | .need_temp_offset_calib = true, | 581 | .need_temp_offset_calib = true, |
582 | .use_new_eeprom_reading = true, | ||
581 | }; | 583 | }; |
582 | 584 | ||
583 | struct iwl_cfg iwl6000g2a_2bg_cfg = { | 585 | struct iwl_cfg iwl6000g2a_2bg_cfg = { |
@@ -595,6 +597,7 @@ struct iwl_cfg iwl6000g2a_2bg_cfg = { | |||
595 | .base_params = &iwl6000_base_params, | 597 | .base_params = &iwl6000_base_params, |
596 | .need_dc_calib = true, | 598 | .need_dc_calib = true, |
597 | .need_temp_offset_calib = true, | 599 | .need_temp_offset_calib = true, |
600 | .use_new_eeprom_reading = true, | ||
598 | }; | 601 | }; |
599 | 602 | ||
600 | struct iwl_cfg iwl6000g2b_2agn_cfg = { | 603 | struct iwl_cfg iwl6000g2b_2agn_cfg = { |
@@ -616,6 +619,7 @@ struct iwl_cfg iwl6000g2b_2agn_cfg = { | |||
616 | .need_temp_offset_calib = true, | 619 | .need_temp_offset_calib = true, |
617 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ | 620 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ |
618 | .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, | 621 | .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, |
622 | .use_new_eeprom_reading = true, | ||
619 | }; | 623 | }; |
620 | 624 | ||
621 | struct iwl_cfg iwl6000g2b_2abg_cfg = { | 625 | struct iwl_cfg iwl6000g2b_2abg_cfg = { |
@@ -636,6 +640,7 @@ struct iwl_cfg iwl6000g2b_2abg_cfg = { | |||
636 | .need_temp_offset_calib = true, | 640 | .need_temp_offset_calib = true, |
637 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ | 641 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ |
638 | .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, | 642 | .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, |
643 | .use_new_eeprom_reading = true, | ||
639 | }; | 644 | }; |
640 | 645 | ||
641 | struct iwl_cfg iwl6000g2b_2bgn_cfg = { | 646 | struct iwl_cfg iwl6000g2b_2bgn_cfg = { |
@@ -657,6 +662,7 @@ struct iwl_cfg iwl6000g2b_2bgn_cfg = { | |||
657 | .need_temp_offset_calib = true, | 662 | .need_temp_offset_calib = true, |
658 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ | 663 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ |
659 | .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, | 664 | .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, |
665 | .use_new_eeprom_reading = true, | ||
660 | }; | 666 | }; |
661 | 667 | ||
662 | struct iwl_cfg iwl6000g2b_2bg_cfg = { | 668 | struct iwl_cfg iwl6000g2b_2bg_cfg = { |
@@ -677,6 +683,7 @@ struct iwl_cfg iwl6000g2b_2bg_cfg = { | |||
677 | .need_temp_offset_calib = true, | 683 | .need_temp_offset_calib = true, |
678 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ | 684 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ |
679 | .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, | 685 | .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, |
686 | .use_new_eeprom_reading = true, | ||
680 | }; | 687 | }; |
681 | 688 | ||
682 | struct iwl_cfg iwl6000g2b_bgn_cfg = { | 689 | struct iwl_cfg iwl6000g2b_bgn_cfg = { |
@@ -698,6 +705,7 @@ struct iwl_cfg iwl6000g2b_bgn_cfg = { | |||
698 | .need_temp_offset_calib = true, | 705 | .need_temp_offset_calib = true, |
699 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ | 706 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ |
700 | .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, | 707 | .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, |
708 | .use_new_eeprom_reading = true, | ||
701 | }; | 709 | }; |
702 | 710 | ||
703 | struct iwl_cfg iwl6000g2b_bg_cfg = { | 711 | struct iwl_cfg iwl6000g2b_bg_cfg = { |
@@ -718,6 +726,7 @@ struct iwl_cfg iwl6000g2b_bg_cfg = { | |||
718 | .need_temp_offset_calib = true, | 726 | .need_temp_offset_calib = true, |
719 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ | 727 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ |
720 | .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, | 728 | .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, |
729 | .use_new_eeprom_reading = true, | ||
721 | }; | 730 | }; |
722 | 731 | ||
723 | /* | 732 | /* |
@@ -804,6 +813,7 @@ struct iwl_cfg iwl6050g2_bgn_cfg = { | |||
804 | .base_params = &iwl6050_base_params, | 813 | .base_params = &iwl6050_base_params, |
805 | .ht_params = &iwl6000_ht_params, | 814 | .ht_params = &iwl6000_ht_params, |
806 | .need_dc_calib = true, | 815 | .need_dc_calib = true, |
816 | .use_new_eeprom_reading = true, | ||
807 | }; | 817 | }; |
808 | 818 | ||
809 | struct iwl_cfg iwl6050_2abg_cfg = { | 819 | struct iwl_cfg iwl6050_2abg_cfg = { |
@@ -857,6 +867,7 @@ struct iwl_cfg iwl130_bgn_cfg = { | |||
857 | .need_dc_calib = true, | 867 | .need_dc_calib = true, |
858 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ | 868 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ |
859 | .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, | 869 | .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, |
870 | .use_new_eeprom_reading = true, | ||
860 | }; | 871 | }; |
861 | 872 | ||
862 | struct iwl_cfg iwl130_bg_cfg = { | 873 | struct iwl_cfg iwl130_bg_cfg = { |
@@ -876,6 +887,7 @@ struct iwl_cfg iwl130_bg_cfg = { | |||
876 | .need_dc_calib = true, | 887 | .need_dc_calib = true, |
877 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ | 888 | /* Due to bluetooth, we transmit 2.4 GHz probes only on antenna A */ |
878 | .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, | 889 | .scan_tx_antennas[IEEE80211_BAND_2GHZ] = ANT_A, |
890 | .use_new_eeprom_reading = true, | ||
879 | }; | 891 | }; |
880 | 892 | ||
881 | MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); | 893 | MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c index a650baba0809..9eeeda18748d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-eeprom.c | |||
@@ -392,7 +392,7 @@ static s8 iwl_update_channel_txpower(struct iwl_priv *priv, | |||
392 | /** | 392 | /** |
393 | * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info | 393 | * iwlcore_eeprom_enhanced_txpower: process enhanced tx power info |
394 | */ | 394 | */ |
395 | void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) | 395 | static void iwlcore_eeprom_enhanced_txpower_old(struct iwl_priv *priv) |
396 | { | 396 | { |
397 | int eeprom_section_count = 0; | 397 | int eeprom_section_count = 0; |
398 | int section, element; | 398 | int section, element; |
@@ -419,7 +419,8 @@ void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) | |||
419 | * always check for valid entry before process | 419 | * always check for valid entry before process |
420 | * the information | 420 | * the information |
421 | */ | 421 | */ |
422 | if (!enhanced_txpower->common || enhanced_txpower->reserved) | 422 | if (!(enhanced_txpower->flags || enhanced_txpower->channel) || |
423 | enhanced_txpower->delta_20_in_40) | ||
423 | continue; | 424 | continue; |
424 | 425 | ||
425 | for (element = 0; element < eeprom_section_count; element++) { | 426 | for (element = 0; element < eeprom_section_count; element++) { |
@@ -452,3 +453,86 @@ void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) | |||
452 | } | 453 | } |
453 | } | 454 | } |
454 | } | 455 | } |
456 | |||
457 | static void | ||
458 | iwlcore_eeprom_enh_txp_read_element(struct iwl_priv *priv, | ||
459 | struct iwl_eeprom_enhanced_txpwr *txp, | ||
460 | s8 max_txpower_avg) | ||
461 | { | ||
462 | int ch_idx; | ||
463 | bool is_ht40 = txp->flags & IWL_EEPROM_ENH_TXP_FL_40MHZ; | ||
464 | enum ieee80211_band band; | ||
465 | |||
466 | band = txp->flags & IWL_EEPROM_ENH_TXP_FL_BAND_52G ? | ||
467 | IEEE80211_BAND_5GHZ : IEEE80211_BAND_2GHZ; | ||
468 | |||
469 | for (ch_idx = 0; ch_idx < priv->channel_count; ch_idx++) { | ||
470 | struct iwl_channel_info *ch_info = &priv->channel_info[ch_idx]; | ||
471 | |||
472 | /* update matching channel or from common data only */ | ||
473 | if (txp->channel != 0 && ch_info->channel != txp->channel) | ||
474 | continue; | ||
475 | |||
476 | /* update matching band only */ | ||
477 | if (band != ch_info->band) | ||
478 | continue; | ||
479 | |||
480 | if (ch_info->max_power_avg < max_txpower_avg && !is_ht40) { | ||
481 | ch_info->max_power_avg = max_txpower_avg; | ||
482 | ch_info->curr_txpow = max_txpower_avg; | ||
483 | ch_info->scan_power = max_txpower_avg; | ||
484 | } | ||
485 | |||
486 | if (is_ht40 && ch_info->ht40_max_power_avg < max_txpower_avg) | ||
487 | ch_info->ht40_max_power_avg = max_txpower_avg; | ||
488 | } | ||
489 | } | ||
490 | |||
491 | #define EEPROM_TXP_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT) | ||
492 | #define EEPROM_TXP_ENTRY_LEN sizeof(struct iwl_eeprom_enhanced_txpwr) | ||
493 | #define EEPROM_TXP_SZ_OFFS (0x00 | INDIRECT_ADDRESS | INDIRECT_TXP_LIMIT_SIZE) | ||
494 | |||
495 | static void iwlcore_eeprom_enhanced_txpower_new(struct iwl_priv *priv) | ||
496 | { | ||
497 | struct iwl_eeprom_enhanced_txpwr *txp_array, *txp; | ||
498 | int idx, entries; | ||
499 | __le16 *txp_len; | ||
500 | s8 max_txp_avg, max_txp_avg_halfdbm; | ||
501 | |||
502 | BUILD_BUG_ON(sizeof(struct iwl_eeprom_enhanced_txpwr) != 8); | ||
503 | |||
504 | /* the length is in 16-bit words, but we want entries */ | ||
505 | txp_len = (__le16 *) iwlagn_eeprom_query_addr(priv, EEPROM_TXP_SZ_OFFS); | ||
506 | entries = le16_to_cpup(txp_len) * 2 / EEPROM_TXP_ENTRY_LEN; | ||
507 | |||
508 | txp_array = (void *) iwlagn_eeprom_query_addr(priv, EEPROM_TXP_OFFS); | ||
509 | for (idx = 0; idx < entries; idx++) { | ||
510 | txp = &txp_array[idx]; | ||
511 | |||
512 | /* skip invalid entries */ | ||
513 | if (!(txp->flags & IWL_EEPROM_ENH_TXP_FL_VALID)) | ||
514 | continue; | ||
515 | |||
516 | max_txp_avg = iwl_get_max_txpower_avg(priv, txp_array, idx, | ||
517 | &max_txp_avg_halfdbm); | ||
518 | |||
519 | /* | ||
520 | * Update the user limit values values to the highest | ||
521 | * power supported by any channel | ||
522 | */ | ||
523 | if (max_txp_avg > priv->tx_power_user_lmt) | ||
524 | priv->tx_power_user_lmt = max_txp_avg; | ||
525 | if (max_txp_avg_halfdbm > priv->tx_power_lmt_in_half_dbm) | ||
526 | priv->tx_power_lmt_in_half_dbm = max_txp_avg_halfdbm; | ||
527 | |||
528 | iwlcore_eeprom_enh_txp_read_element(priv, txp, max_txp_avg); | ||
529 | } | ||
530 | } | ||
531 | |||
532 | void iwlcore_eeprom_enhanced_txpower(struct iwl_priv *priv) | ||
533 | { | ||
534 | if (priv->cfg->use_new_eeprom_reading) | ||
535 | iwlcore_eeprom_enhanced_txpower_new(priv); | ||
536 | else | ||
537 | iwlcore_eeprom_enhanced_txpower_old(priv); | ||
538 | } | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index b555edd53354..554afb7d9670 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |||
@@ -569,6 +569,12 @@ static u32 eeprom_indirect_address(const struct iwl_priv *priv, u32 address) | |||
569 | case INDIRECT_REGULATORY: | 569 | case INDIRECT_REGULATORY: |
570 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_REGULATORY); | 570 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_REGULATORY); |
571 | break; | 571 | break; |
572 | case INDIRECT_TXP_LIMIT: | ||
573 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT); | ||
574 | break; | ||
575 | case INDIRECT_TXP_LIMIT_SIZE: | ||
576 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_TXP_LIMIT_SIZE); | ||
577 | break; | ||
572 | case INDIRECT_CALIBRATION: | 578 | case INDIRECT_CALIBRATION: |
573 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_CALIBRATION); | 579 | offset = iwl_eeprom_query16(priv, EEPROM_LINK_CALIBRATION); |
574 | break; | 580 | break; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 64527def059f..954ecc2c34c4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -390,6 +390,7 @@ struct iwl_cfg { | |||
390 | const bool need_temp_offset_calib; /* if used set to true */ | 390 | const bool need_temp_offset_calib; /* if used set to true */ |
391 | u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; | 391 | u8 scan_rx_antennas[IEEE80211_NUM_BANDS]; |
392 | u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; | 392 | u8 scan_tx_antennas[IEEE80211_NUM_BANDS]; |
393 | const bool use_new_eeprom_reading; /* temporary, remove later */ | ||
393 | }; | 394 | }; |
394 | 395 | ||
395 | /*************************** | 396 | /*************************** |
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.h b/drivers/net/wireless/iwlwifi/iwl-eeprom.h index d9b590625ae4..e3a279d2d0b6 100644 --- a/drivers/net/wireless/iwlwifi/iwl-eeprom.h +++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.h | |||
@@ -120,6 +120,17 @@ struct iwl_eeprom_channel { | |||
120 | s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */ | 120 | s8 max_power_avg; /* max power (dBm) on this chnl, limit 31 */ |
121 | } __packed; | 121 | } __packed; |
122 | 122 | ||
123 | enum iwl_eeprom_enhanced_txpwr_flags { | ||
124 | IWL_EEPROM_ENH_TXP_FL_VALID = BIT(0), | ||
125 | IWL_EEPROM_ENH_TXP_FL_BAND_52G = BIT(1), | ||
126 | IWL_EEPROM_ENH_TXP_FL_OFDM = BIT(2), | ||
127 | IWL_EEPROM_ENH_TXP_FL_40MHZ = BIT(3), | ||
128 | IWL_EEPROM_ENH_TXP_FL_HT_AP = BIT(4), | ||
129 | IWL_EEPROM_ENH_TXP_FL_RES1 = BIT(5), | ||
130 | IWL_EEPROM_ENH_TXP_FL_RES2 = BIT(6), | ||
131 | IWL_EEPROM_ENH_TXP_FL_COMMON_TYPE = BIT(7), | ||
132 | }; | ||
133 | |||
123 | /** | 134 | /** |
124 | * iwl_eeprom_enhanced_txpwr structure | 135 | * iwl_eeprom_enhanced_txpwr structure |
125 | * This structure presents the enhanced regulatory tx power limit layout | 136 | * This structure presents the enhanced regulatory tx power limit layout |
@@ -127,21 +138,23 @@ struct iwl_eeprom_channel { | |||
127 | * Enhanced regulatory tx power portion of eeprom image can be broken down | 138 | * Enhanced regulatory tx power portion of eeprom image can be broken down |
128 | * into individual structures; each one is 8 bytes in size and contain the | 139 | * into individual structures; each one is 8 bytes in size and contain the |
129 | * following information | 140 | * following information |
130 | * @common: (desc + channel) not used by driver, should _NOT_ be "zero" | 141 | * @flags: entry flags |
142 | * @channel: channel number | ||
131 | * @chain_a_max_pwr: chain a max power in 1/2 dBm | 143 | * @chain_a_max_pwr: chain a max power in 1/2 dBm |
132 | * @chain_b_max_pwr: chain b max power in 1/2 dBm | 144 | * @chain_b_max_pwr: chain b max power in 1/2 dBm |
133 | * @chain_c_max_pwr: chain c max power in 1/2 dBm | 145 | * @chain_c_max_pwr: chain c max power in 1/2 dBm |
134 | * @reserved: not used, should be "zero" | 146 | * @delta_20_in_40: 20-in-40 deltas (hi/lo) |
135 | * @mimo2_max_pwr: mimo2 max power in 1/2 dBm | 147 | * @mimo2_max_pwr: mimo2 max power in 1/2 dBm |
136 | * @mimo3_max_pwr: mimo3 max power in 1/2 dBm | 148 | * @mimo3_max_pwr: mimo3 max power in 1/2 dBm |
137 | * | 149 | * |
138 | */ | 150 | */ |
139 | struct iwl_eeprom_enhanced_txpwr { | 151 | struct iwl_eeprom_enhanced_txpwr { |
140 | __le16 common; | 152 | u8 flags; |
153 | u8 channel; | ||
141 | s8 chain_a_max; | 154 | s8 chain_a_max; |
142 | s8 chain_b_max; | 155 | s8 chain_b_max; |
143 | s8 chain_c_max; | 156 | s8 chain_c_max; |
144 | s8 reserved; | 157 | u8 delta_20_in_40; |
145 | s8 mimo2_max; | 158 | s8 mimo2_max; |
146 | s8 mimo3_max; | 159 | s8 mimo3_max; |
147 | } __packed; | 160 | } __packed; |
@@ -186,6 +199,8 @@ struct iwl_eeprom_enhanced_txpwr { | |||
186 | #define EEPROM_LINK_CALIBRATION (2*0x67) | 199 | #define EEPROM_LINK_CALIBRATION (2*0x67) |
187 | #define EEPROM_LINK_PROCESS_ADJST (2*0x68) | 200 | #define EEPROM_LINK_PROCESS_ADJST (2*0x68) |
188 | #define EEPROM_LINK_OTHERS (2*0x69) | 201 | #define EEPROM_LINK_OTHERS (2*0x69) |
202 | #define EEPROM_LINK_TXP_LIMIT (2*0x6a) | ||
203 | #define EEPROM_LINK_TXP_LIMIT_SIZE (2*0x6b) | ||
189 | 204 | ||
190 | /* agn regulatory - indirect access */ | 205 | /* agn regulatory - indirect access */ |
191 | #define EEPROM_REG_BAND_1_CHANNELS ((0x08)\ | 206 | #define EEPROM_REG_BAND_1_CHANNELS ((0x08)\ |
@@ -389,6 +404,8 @@ struct iwl_eeprom_calib_info { | |||
389 | #define INDIRECT_CALIBRATION 0x00040000 | 404 | #define INDIRECT_CALIBRATION 0x00040000 |
390 | #define INDIRECT_PROCESS_ADJST 0x00050000 | 405 | #define INDIRECT_PROCESS_ADJST 0x00050000 |
391 | #define INDIRECT_OTHERS 0x00060000 | 406 | #define INDIRECT_OTHERS 0x00060000 |
407 | #define INDIRECT_TXP_LIMIT 0x00070000 | ||
408 | #define INDIRECT_TXP_LIMIT_SIZE 0x00080000 | ||
392 | #define INDIRECT_ADDRESS 0x00100000 | 409 | #define INDIRECT_ADDRESS 0x00100000 |
393 | 410 | ||
394 | /* General */ | 411 | /* General */ |
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c index 373930afc26b..113f4f204657 100644 --- a/drivers/net/wireless/libertas/cfg.c +++ b/drivers/net/wireless/libertas/cfg.c | |||
@@ -619,7 +619,7 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned long dummy, | |||
619 | print_ssid(ssid_buf, ssid, ssid_len), | 619 | print_ssid(ssid_buf, ssid, ssid_len), |
620 | LBS_SCAN_RSSI_TO_MBM(rssi)/100); | 620 | LBS_SCAN_RSSI_TO_MBM(rssi)/100); |
621 | 621 | ||
622 | if (channel || | 622 | if (channel && |
623 | !(channel->flags & IEEE80211_CHAN_DISABLED)) | 623 | !(channel->flags & IEEE80211_CHAN_DISABLED)) |
624 | cfg80211_inform_bss(wiphy, channel, | 624 | cfg80211_inform_bss(wiphy, channel, |
625 | bssid, le64_to_cpu(*(__le64 *)tsfdesc), | 625 | bssid, le64_to_cpu(*(__le64 *)tsfdesc), |
diff --git a/drivers/net/wireless/libertas/if_sdio.c b/drivers/net/wireless/libertas/if_sdio.c index e5685dc317a8..b4de0ca10feb 100644 --- a/drivers/net/wireless/libertas/if_sdio.c +++ b/drivers/net/wireless/libertas/if_sdio.c | |||
@@ -1170,7 +1170,6 @@ static void if_sdio_remove(struct sdio_func *func) | |||
1170 | lbs_deb_sdio("call remove card\n"); | 1170 | lbs_deb_sdio("call remove card\n"); |
1171 | lbs_stop_card(card->priv); | 1171 | lbs_stop_card(card->priv); |
1172 | lbs_remove_card(card->priv); | 1172 | lbs_remove_card(card->priv); |
1173 | card->priv->surpriseremoved = 1; | ||
1174 | 1173 | ||
1175 | flush_workqueue(card->workqueue); | 1174 | flush_workqueue(card->workqueue); |
1176 | destroy_workqueue(card->workqueue); | 1175 | destroy_workqueue(card->workqueue); |
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index 79bcb4e5d2ca..ecd4d04b2c3c 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c | |||
@@ -1055,7 +1055,6 @@ static int __devexit libertas_spi_remove(struct spi_device *spi) | |||
1055 | lbs_stop_card(priv); | 1055 | lbs_stop_card(priv); |
1056 | lbs_remove_card(priv); /* will call free_netdev */ | 1056 | lbs_remove_card(priv); /* will call free_netdev */ |
1057 | 1057 | ||
1058 | priv->surpriseremoved = 1; | ||
1059 | free_irq(spi->irq, card); | 1058 | free_irq(spi->irq, card); |
1060 | if_spi_terminate_spi_thread(card); | 1059 | if_spi_terminate_spi_thread(card); |
1061 | if (card->pdata->teardown) | 1060 | if (card->pdata->teardown) |
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c index 46b88b118c99..fcd1bbfc632d 100644 --- a/drivers/net/wireless/libertas/main.c +++ b/drivers/net/wireless/libertas/main.c | |||
@@ -915,8 +915,6 @@ void lbs_remove_card(struct lbs_private *priv) | |||
915 | 915 | ||
916 | lbs_free_adapter(priv); | 916 | lbs_free_adapter(priv); |
917 | lbs_cfg_free(priv); | 917 | lbs_cfg_free(priv); |
918 | |||
919 | priv->dev = NULL; | ||
920 | free_netdev(dev); | 918 | free_netdev(dev); |
921 | 919 | ||
922 | lbs_deb_leave(LBS_DEB_MAIN); | 920 | lbs_deb_leave(LBS_DEB_MAIN); |
diff --git a/drivers/net/wireless/orinoco/main.c b/drivers/net/wireless/orinoco/main.c index e8e2d0f4763d..f3d396e7544b 100644 --- a/drivers/net/wireless/orinoco/main.c +++ b/drivers/net/wireless/orinoco/main.c | |||
@@ -1392,10 +1392,9 @@ static void orinoco_process_scan_results(struct work_struct *work) | |||
1392 | orinoco_add_hostscan_results(priv, buf, len); | 1392 | orinoco_add_hostscan_results(priv, buf, len); |
1393 | 1393 | ||
1394 | kfree(buf); | 1394 | kfree(buf); |
1395 | } else if (priv->scan_request) { | 1395 | } else { |
1396 | /* Either abort or complete the scan */ | 1396 | /* Either abort or complete the scan */ |
1397 | cfg80211_scan_done(priv->scan_request, (len < 0)); | 1397 | orinoco_scan_done(priv, (len < 0)); |
1398 | priv->scan_request = NULL; | ||
1399 | } | 1398 | } |
1400 | 1399 | ||
1401 | spin_lock_irqsave(&priv->scan_lock, flags); | 1400 | spin_lock_irqsave(&priv->scan_lock, flags); |
@@ -1684,6 +1683,8 @@ static int __orinoco_down(struct orinoco_private *priv) | |||
1684 | hermes_write_regn(hw, EVACK, 0xffff); | 1683 | hermes_write_regn(hw, EVACK, 0xffff); |
1685 | } | 1684 | } |
1686 | 1685 | ||
1686 | orinoco_scan_done(priv, true); | ||
1687 | |||
1687 | /* firmware will have to reassociate */ | 1688 | /* firmware will have to reassociate */ |
1688 | netif_carrier_off(dev); | 1689 | netif_carrier_off(dev); |
1689 | priv->last_linkstatus = 0xffff; | 1690 | priv->last_linkstatus = 0xffff; |
@@ -1762,10 +1763,7 @@ void orinoco_reset(struct work_struct *work) | |||
1762 | orinoco_unlock(priv, &flags); | 1763 | orinoco_unlock(priv, &flags); |
1763 | 1764 | ||
1764 | /* Scanning support: Notify scan cancellation */ | 1765 | /* Scanning support: Notify scan cancellation */ |
1765 | if (priv->scan_request) { | 1766 | orinoco_scan_done(priv, true); |
1766 | cfg80211_scan_done(priv->scan_request, 1); | ||
1767 | priv->scan_request = NULL; | ||
1768 | } | ||
1769 | 1767 | ||
1770 | if (priv->hard_reset) { | 1768 | if (priv->hard_reset) { |
1771 | err = (*priv->hard_reset)(priv); | 1769 | err = (*priv->hard_reset)(priv); |
@@ -1813,6 +1811,12 @@ static int __orinoco_commit(struct orinoco_private *priv) | |||
1813 | struct net_device *dev = priv->ndev; | 1811 | struct net_device *dev = priv->ndev; |
1814 | int err = 0; | 1812 | int err = 0; |
1815 | 1813 | ||
1814 | /* If we've called commit, we are reconfiguring or bringing the | ||
1815 | * interface up. Maintaining countermeasures across this would | ||
1816 | * be confusing, so note that we've disabled them. The port will | ||
1817 | * be enabled later in orinoco_commit or __orinoco_up. */ | ||
1818 | priv->tkip_cm_active = 0; | ||
1819 | |||
1816 | err = orinoco_hw_program_rids(priv); | 1820 | err = orinoco_hw_program_rids(priv); |
1817 | 1821 | ||
1818 | /* FIXME: what about netif_tx_lock */ | 1822 | /* FIXME: what about netif_tx_lock */ |
diff --git a/drivers/net/wireless/orinoco/orinoco_cs.c b/drivers/net/wireless/orinoco/orinoco_cs.c index 71b3d68b9403..32954c4b243a 100644 --- a/drivers/net/wireless/orinoco/orinoco_cs.c +++ b/drivers/net/wireless/orinoco/orinoco_cs.c | |||
@@ -151,20 +151,20 @@ orinoco_cs_config(struct pcmcia_device *link) | |||
151 | goto failed; | 151 | goto failed; |
152 | } | 152 | } |
153 | 153 | ||
154 | ret = pcmcia_request_irq(link, orinoco_interrupt); | ||
155 | if (ret) | ||
156 | goto failed; | ||
157 | |||
158 | /* We initialize the hermes structure before completing PCMCIA | ||
159 | * configuration just in case the interrupt handler gets | ||
160 | * called. */ | ||
161 | mem = ioport_map(link->resource[0]->start, | 154 | mem = ioport_map(link->resource[0]->start, |
162 | resource_size(link->resource[0])); | 155 | resource_size(link->resource[0])); |
163 | if (!mem) | 156 | if (!mem) |
164 | goto failed; | 157 | goto failed; |
165 | 158 | ||
159 | /* We initialize the hermes structure before completing PCMCIA | ||
160 | * configuration just in case the interrupt handler gets | ||
161 | * called. */ | ||
166 | hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); | 162 | hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); |
167 | 163 | ||
164 | ret = pcmcia_request_irq(link, orinoco_interrupt); | ||
165 | if (ret) | ||
166 | goto failed; | ||
167 | |||
168 | ret = pcmcia_enable_device(link); | 168 | ret = pcmcia_enable_device(link); |
169 | if (ret) | 169 | if (ret) |
170 | goto failed; | 170 | goto failed; |
diff --git a/drivers/net/wireless/orinoco/scan.c b/drivers/net/wireless/orinoco/scan.c index 4300d9db7d8c..86cb54c842e7 100644 --- a/drivers/net/wireless/orinoco/scan.c +++ b/drivers/net/wireless/orinoco/scan.c | |||
@@ -229,3 +229,11 @@ void orinoco_add_hostscan_results(struct orinoco_private *priv, | |||
229 | priv->scan_request = NULL; | 229 | priv->scan_request = NULL; |
230 | } | 230 | } |
231 | } | 231 | } |
232 | |||
233 | void orinoco_scan_done(struct orinoco_private *priv, bool abort) | ||
234 | { | ||
235 | if (priv->scan_request) { | ||
236 | cfg80211_scan_done(priv->scan_request, abort); | ||
237 | priv->scan_request = NULL; | ||
238 | } | ||
239 | } | ||
diff --git a/drivers/net/wireless/orinoco/scan.h b/drivers/net/wireless/orinoco/scan.h index 2dc4e046dbdb..27281fb0a6dc 100644 --- a/drivers/net/wireless/orinoco/scan.h +++ b/drivers/net/wireless/orinoco/scan.h | |||
@@ -16,5 +16,6 @@ void orinoco_add_extscan_result(struct orinoco_private *priv, | |||
16 | void orinoco_add_hostscan_results(struct orinoco_private *dev, | 16 | void orinoco_add_hostscan_results(struct orinoco_private *dev, |
17 | unsigned char *buf, | 17 | unsigned char *buf, |
18 | size_t len); | 18 | size_t len); |
19 | void orinoco_scan_done(struct orinoco_private *priv, bool abort); | ||
19 | 20 | ||
20 | #endif /* _ORINOCO_SCAN_H_ */ | 21 | #endif /* _ORINOCO_SCAN_H_ */ |
diff --git a/drivers/net/wireless/orinoco/spectrum_cs.c b/drivers/net/wireless/orinoco/spectrum_cs.c index fb859a5ad2eb..db34c282e59b 100644 --- a/drivers/net/wireless/orinoco/spectrum_cs.c +++ b/drivers/net/wireless/orinoco/spectrum_cs.c | |||
@@ -214,21 +214,21 @@ spectrum_cs_config(struct pcmcia_device *link) | |||
214 | goto failed; | 214 | goto failed; |
215 | } | 215 | } |
216 | 216 | ||
217 | ret = pcmcia_request_irq(link, orinoco_interrupt); | ||
218 | if (ret) | ||
219 | goto failed; | ||
220 | |||
221 | /* We initialize the hermes structure before completing PCMCIA | ||
222 | * configuration just in case the interrupt handler gets | ||
223 | * called. */ | ||
224 | mem = ioport_map(link->resource[0]->start, | 217 | mem = ioport_map(link->resource[0]->start, |
225 | resource_size(link->resource[0])); | 218 | resource_size(link->resource[0])); |
226 | if (!mem) | 219 | if (!mem) |
227 | goto failed; | 220 | goto failed; |
228 | 221 | ||
222 | /* We initialize the hermes structure before completing PCMCIA | ||
223 | * configuration just in case the interrupt handler gets | ||
224 | * called. */ | ||
229 | hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); | 225 | hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING); |
230 | hw->eeprom_pda = true; | 226 | hw->eeprom_pda = true; |
231 | 227 | ||
228 | ret = pcmcia_request_irq(link, orinoco_interrupt); | ||
229 | if (ret) | ||
230 | goto failed; | ||
231 | |||
232 | ret = pcmcia_enable_device(link); | 232 | ret = pcmcia_enable_device(link); |
233 | if (ret) | 233 | if (ret) |
234 | goto failed; | 234 | goto failed; |
diff --git a/drivers/net/wireless/orinoco/wext.c b/drivers/net/wireless/orinoco/wext.c index 93505f93bf97..e5afabee60d1 100644 --- a/drivers/net/wireless/orinoco/wext.c +++ b/drivers/net/wireless/orinoco/wext.c | |||
@@ -911,10 +911,10 @@ static int orinoco_ioctl_set_auth(struct net_device *dev, | |||
911 | */ | 911 | */ |
912 | if (param->value) { | 912 | if (param->value) { |
913 | priv->tkip_cm_active = 1; | 913 | priv->tkip_cm_active = 1; |
914 | ret = hermes_enable_port(hw, 0); | 914 | ret = hermes_disable_port(hw, 0); |
915 | } else { | 915 | } else { |
916 | priv->tkip_cm_active = 0; | 916 | priv->tkip_cm_active = 0; |
917 | ret = hermes_disable_port(hw, 0); | 917 | ret = hermes_enable_port(hw, 0); |
918 | } | 918 | } |
919 | break; | 919 | break; |
920 | 920 | ||
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index d5bc21e5a02c..2325e56a9b0b 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
@@ -43,6 +43,7 @@ MODULE_FIRMWARE("isl3887usb"); | |||
43 | 43 | ||
44 | static struct usb_device_id p54u_table[] __devinitdata = { | 44 | static struct usb_device_id p54u_table[] __devinitdata = { |
45 | /* Version 1 devices (pci chip + net2280) */ | 45 | /* Version 1 devices (pci chip + net2280) */ |
46 | {USB_DEVICE(0x0411, 0x0050)}, /* Buffalo WLI2-USB2-G54 */ | ||
46 | {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */ | 47 | {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */ |
47 | {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */ | 48 | {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */ |
48 | {USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */ | 49 | {USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */ |
@@ -56,9 +57,13 @@ static struct usb_device_id p54u_table[] __devinitdata = { | |||
56 | {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */ | 57 | {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */ |
57 | {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */ | 58 | {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */ |
58 | {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */ | 59 | {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */ |
60 | {USB_DEVICE(0x0db0, 0x6826)}, /* MSI UB54G (MS-6826) */ | ||
59 | {USB_DEVICE(0x107b, 0x55f2)}, /* Gateway WGU-210 (Gemtek) */ | 61 | {USB_DEVICE(0x107b, 0x55f2)}, /* Gateway WGU-210 (Gemtek) */ |
60 | {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */ | 62 | {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */ |
63 | {USB_DEVICE(0x1435, 0x0210)}, /* Inventel UR054G */ | ||
64 | {USB_DEVICE(0x15a9, 0x0002)}, /* Gemtek WUBI-100GW 802.11g */ | ||
61 | {USB_DEVICE(0x1630, 0x0005)}, /* 2Wire 802.11g USB (v1) / Z-Com */ | 65 | {USB_DEVICE(0x1630, 0x0005)}, /* 2Wire 802.11g USB (v1) / Z-Com */ |
66 | {USB_DEVICE(0x182d, 0x096b)}, /* Sitecom WL-107 */ | ||
62 | {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */ | 67 | {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */ |
63 | {USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */ | 68 | {USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */ |
64 | {USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */ | 69 | {USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */ |
@@ -94,6 +99,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { | |||
94 | {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ | 99 | {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ |
95 | {USB_DEVICE(0x1668, 0x1050)}, /* Actiontec 802UIG-1 */ | 100 | {USB_DEVICE(0x1668, 0x1050)}, /* Actiontec 802UIG-1 */ |
96 | {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ | 101 | {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ |
102 | {USB_DEVICE(0x2001, 0x3705)}, /* D-Link DWL-G120 rev C1 */ | ||
97 | {USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */ | 103 | {USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */ |
98 | {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */ | 104 | {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */ |
99 | {USB_DEVICE(0x413c, 0x8104)}, /* Cohiba Proto board */ | 105 | {USB_DEVICE(0x413c, 0x8104)}, /* Cohiba Proto board */ |
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c index b26739535986..09a67905c230 100644 --- a/drivers/net/wireless/rt2x00/rt2800pci.c +++ b/drivers/net/wireless/rt2x00/rt2800pci.c | |||
@@ -912,6 +912,7 @@ static int rt2800pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
912 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); | 912 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); |
913 | __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags); | 913 | __set_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags); |
914 | __set_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags); | 914 | __set_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags); |
915 | __set_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags); | ||
915 | if (!modparam_nohwcrypt) | 916 | if (!modparam_nohwcrypt) |
916 | __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); | 917 | __set_bit(CONFIG_SUPPORT_HW_CRYPTO, &rt2x00dev->flags); |
917 | __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); | 918 | __set_bit(DRIVER_SUPPORT_LINK_TUNING, &rt2x00dev->flags); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 94fe589acfaa..ab43e7ca2a23 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -664,6 +664,7 @@ enum rt2x00_flags { | |||
664 | DRIVER_REQUIRE_COPY_IV, | 664 | DRIVER_REQUIRE_COPY_IV, |
665 | DRIVER_REQUIRE_L2PAD, | 665 | DRIVER_REQUIRE_L2PAD, |
666 | DRIVER_REQUIRE_TXSTATUS_FIFO, | 666 | DRIVER_REQUIRE_TXSTATUS_FIFO, |
667 | DRIVER_REQUIRE_TASKLET_CONTEXT, | ||
667 | 668 | ||
668 | /* | 669 | /* |
669 | * Driver features | 670 | * Driver features |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index 5ba79b935f09..d019830ca840 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -390,9 +390,12 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
390 | * through a mac80211 library call (RTS/CTS) then we should not | 390 | * through a mac80211 library call (RTS/CTS) then we should not |
391 | * send the status report back. | 391 | * send the status report back. |
392 | */ | 392 | */ |
393 | if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) | 393 | if (!(skbdesc_flags & SKBDESC_NOT_MAC80211)) { |
394 | ieee80211_tx_status(rt2x00dev->hw, entry->skb); | 394 | if (test_bit(DRIVER_REQUIRE_TASKLET_CONTEXT, &rt2x00dev->flags)) |
395 | else | 395 | ieee80211_tx_status(rt2x00dev->hw, entry->skb); |
396 | else | ||
397 | ieee80211_tx_status_ni(rt2x00dev->hw, entry->skb); | ||
398 | } else | ||
396 | dev_kfree_skb_any(entry->skb); | 399 | dev_kfree_skb_any(entry->skb); |
397 | 400 | ||
398 | /* | 401 | /* |
diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index 458bb57914a3..cdbeec9f83ea 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c | |||
@@ -66,8 +66,8 @@ struct netfront_cb { | |||
66 | 66 | ||
67 | #define GRANT_INVALID_REF 0 | 67 | #define GRANT_INVALID_REF 0 |
68 | 68 | ||
69 | #define NET_TX_RING_SIZE __RING_SIZE((struct xen_netif_tx_sring *)0, PAGE_SIZE) | 69 | #define NET_TX_RING_SIZE __CONST_RING_SIZE(xen_netif_tx, PAGE_SIZE) |
70 | #define NET_RX_RING_SIZE __RING_SIZE((struct xen_netif_rx_sring *)0, PAGE_SIZE) | 70 | #define NET_RX_RING_SIZE __CONST_RING_SIZE(xen_netif_rx, PAGE_SIZE) |
71 | #define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256) | 71 | #define TX_MAX_TARGET min_t(int, NET_RX_RING_SIZE, 256) |
72 | 72 | ||
73 | struct netfront_info { | 73 | struct netfront_info { |
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c index cd1b3dcd61db..ec47e22fa186 100644 --- a/drivers/net/yellowfin.c +++ b/drivers/net/yellowfin.c | |||
@@ -744,7 +744,7 @@ static int yellowfin_init_ring(struct net_device *dev) | |||
744 | } | 744 | } |
745 | 745 | ||
746 | for (i = 0; i < RX_RING_SIZE; i++) { | 746 | for (i = 0; i < RX_RING_SIZE; i++) { |
747 | struct sk_buff *skb = dev_alloc_skb(yp->rx_buf_sz); | 747 | struct sk_buff *skb = dev_alloc_skb(yp->rx_buf_sz + 2); |
748 | yp->rx_skbuff[i] = skb; | 748 | yp->rx_skbuff[i] = skb; |
749 | if (skb == NULL) | 749 | if (skb == NULL) |
750 | break; | 750 | break; |
@@ -1157,7 +1157,7 @@ static int yellowfin_rx(struct net_device *dev) | |||
1157 | for (; yp->cur_rx - yp->dirty_rx > 0; yp->dirty_rx++) { | 1157 | for (; yp->cur_rx - yp->dirty_rx > 0; yp->dirty_rx++) { |
1158 | entry = yp->dirty_rx % RX_RING_SIZE; | 1158 | entry = yp->dirty_rx % RX_RING_SIZE; |
1159 | if (yp->rx_skbuff[entry] == NULL) { | 1159 | if (yp->rx_skbuff[entry] == NULL) { |
1160 | struct sk_buff *skb = dev_alloc_skb(yp->rx_buf_sz); | 1160 | struct sk_buff *skb = dev_alloc_skb(yp->rx_buf_sz + 2); |
1161 | if (skb == NULL) | 1161 | if (skb == NULL) |
1162 | break; /* Better luck next round. */ | 1162 | break; /* Better luck next round. */ |
1163 | yp->rx_skbuff[entry] = skb; | 1163 | yp->rx_skbuff[entry] = skb; |
diff --git a/drivers/of/of_i2c.c b/drivers/of/of_i2c.c index c85d3c7421fc..f37fbeb66a44 100644 --- a/drivers/of/of_i2c.c +++ b/drivers/of/of_i2c.c | |||
@@ -61,7 +61,7 @@ void of_i2c_register_devices(struct i2c_adapter *adap) | |||
61 | info.of_node = of_node_get(node); | 61 | info.of_node = of_node_get(node); |
62 | info.archdata = &dev_ad; | 62 | info.archdata = &dev_ad; |
63 | 63 | ||
64 | request_module("%s", info.type); | 64 | request_module("%s%s", I2C_MODULE_PREFIX, info.type); |
65 | 65 | ||
66 | result = i2c_new_device(adap, &info); | 66 | result = i2c_new_device(adap, &info); |
67 | if (result == NULL) { | 67 | if (result == NULL) { |
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index 003170ea2e39..69546e9213dd 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c | |||
@@ -64,77 +64,6 @@ void pci_bus_remove_resources(struct pci_bus *bus) | |||
64 | } | 64 | } |
65 | } | 65 | } |
66 | 66 | ||
67 | static bool pci_bus_resource_better(struct resource *res1, bool pos1, | ||
68 | struct resource *res2, bool pos2) | ||
69 | { | ||
70 | /* If exactly one is positive decode, always prefer that one */ | ||
71 | if (pos1 != pos2) | ||
72 | return pos1 ? true : false; | ||
73 | |||
74 | /* Prefer the one that contains the highest address */ | ||
75 | if (res1->end != res2->end) | ||
76 | return (res1->end > res2->end) ? true : false; | ||
77 | |||
78 | /* Otherwise, prefer the one with highest "center of gravity" */ | ||
79 | if (res1->start != res2->start) | ||
80 | return (res1->start > res2->start) ? true : false; | ||
81 | |||
82 | /* Otherwise, choose one arbitrarily (but consistently) */ | ||
83 | return (res1 > res2) ? true : false; | ||
84 | } | ||
85 | |||
86 | static bool pci_bus_resource_positive(struct pci_bus *bus, struct resource *res) | ||
87 | { | ||
88 | struct pci_bus_resource *bus_res; | ||
89 | |||
90 | /* | ||
91 | * This relies on the fact that pci_bus.resource[] refers to P2P or | ||
92 | * CardBus bridge base/limit registers, which are always positively | ||
93 | * decoded. The pci_bus.resources list contains host bridge or | ||
94 | * subtractively decoded resources. | ||
95 | */ | ||
96 | list_for_each_entry(bus_res, &bus->resources, list) { | ||
97 | if (bus_res->res == res) | ||
98 | return (bus_res->flags & PCI_SUBTRACTIVE_DECODE) ? | ||
99 | false : true; | ||
100 | } | ||
101 | return true; | ||
102 | } | ||
103 | |||
104 | /* | ||
105 | * Find the next-best bus resource after the cursor "res". If the cursor is | ||
106 | * NULL, return the best resource. "Best" means that we prefer positive | ||
107 | * decode regions over subtractive decode, then those at higher addresses. | ||
108 | */ | ||
109 | static struct resource *pci_bus_find_resource_prev(struct pci_bus *bus, | ||
110 | unsigned int type, | ||
111 | struct resource *res) | ||
112 | { | ||
113 | bool res_pos, r_pos, prev_pos = false; | ||
114 | struct resource *r, *prev = NULL; | ||
115 | int i; | ||
116 | |||
117 | res_pos = pci_bus_resource_positive(bus, res); | ||
118 | pci_bus_for_each_resource(bus, r, i) { | ||
119 | if (!r) | ||
120 | continue; | ||
121 | |||
122 | if ((r->flags & IORESOURCE_TYPE_BITS) != type) | ||
123 | continue; | ||
124 | |||
125 | r_pos = pci_bus_resource_positive(bus, r); | ||
126 | if (!res || pci_bus_resource_better(res, res_pos, r, r_pos)) { | ||
127 | if (!prev || pci_bus_resource_better(r, r_pos, | ||
128 | prev, prev_pos)) { | ||
129 | prev = r; | ||
130 | prev_pos = r_pos; | ||
131 | } | ||
132 | } | ||
133 | } | ||
134 | |||
135 | return prev; | ||
136 | } | ||
137 | |||
138 | /** | 67 | /** |
139 | * pci_bus_alloc_resource - allocate a resource from a parent bus | 68 | * pci_bus_alloc_resource - allocate a resource from a parent bus |
140 | * @bus: PCI bus | 69 | * @bus: PCI bus |
@@ -160,10 +89,9 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | |||
160 | resource_size_t), | 89 | resource_size_t), |
161 | void *alignf_data) | 90 | void *alignf_data) |
162 | { | 91 | { |
163 | int ret = -ENOMEM; | 92 | int i, ret = -ENOMEM; |
164 | struct resource *r; | 93 | struct resource *r; |
165 | resource_size_t max = -1; | 94 | resource_size_t max = -1; |
166 | unsigned int type = res->flags & IORESOURCE_TYPE_BITS; | ||
167 | 95 | ||
168 | type_mask |= IORESOURCE_IO | IORESOURCE_MEM; | 96 | type_mask |= IORESOURCE_IO | IORESOURCE_MEM; |
169 | 97 | ||
@@ -171,9 +99,10 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, | |||
171 | if (!(res->flags & IORESOURCE_MEM_64)) | 99 | if (!(res->flags & IORESOURCE_MEM_64)) |
172 | max = PCIBIOS_MAX_MEM_32; | 100 | max = PCIBIOS_MAX_MEM_32; |
173 | 101 | ||
174 | /* Look for space at highest addresses first */ | 102 | pci_bus_for_each_resource(bus, r, i) { |
175 | r = pci_bus_find_resource_prev(bus, type, NULL); | 103 | if (!r) |
176 | for ( ; r; r = pci_bus_find_resource_prev(bus, type, r)) { | 104 | continue; |
105 | |||
177 | /* type_mask must match */ | 106 | /* type_mask must match */ |
178 | if ((res->flags ^ r->flags) & type_mask) | 107 | if ((res->flags ^ r->flags) & type_mask) |
179 | continue; | 108 | continue; |
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 0157708d474d..09933eb9126b 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c | |||
@@ -1417,6 +1417,11 @@ int __init enable_drhd_fault_handling(void) | |||
1417 | (unsigned long long)drhd->reg_base_addr, ret); | 1417 | (unsigned long long)drhd->reg_base_addr, ret); |
1418 | return -1; | 1418 | return -1; |
1419 | } | 1419 | } |
1420 | |||
1421 | /* | ||
1422 | * Clear any previous faults. | ||
1423 | */ | ||
1424 | dmar_fault(iommu->irq, iommu); | ||
1420 | } | 1425 | } |
1421 | 1426 | ||
1422 | return 0; | 1427 | return 0; |
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c index 2574700db461..5f7226223a62 100644 --- a/drivers/pci/hotplug/pciehp_acpi.c +++ b/drivers/pci/hotplug/pciehp_acpi.c | |||
@@ -115,7 +115,8 @@ static struct pcie_port_service_driver __initdata dummy_driver = { | |||
115 | static int __init select_detection_mode(void) | 115 | static int __init select_detection_mode(void) |
116 | { | 116 | { |
117 | struct dummy_slot *slot, *tmp; | 117 | struct dummy_slot *slot, *tmp; |
118 | pcie_port_service_register(&dummy_driver); | 118 | if (pcie_port_service_register(&dummy_driver)) |
119 | return PCIEHP_DETECT_ACPI; | ||
119 | pcie_port_service_unregister(&dummy_driver); | 120 | pcie_port_service_unregister(&dummy_driver); |
120 | list_for_each_entry_safe(slot, tmp, &dummy_slots, list) { | 121 | list_for_each_entry_safe(slot, tmp, &dummy_slots, list) { |
121 | list_del(&slot->list); | 122 | list_del(&slot->list); |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 6f9350cabbd5..53a786fd0d40 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -2329,6 +2329,9 @@ static void __devinit nvbridge_check_legacy_irq_routing(struct pci_dev *dev) | |||
2329 | { | 2329 | { |
2330 | u32 cfg; | 2330 | u32 cfg; |
2331 | 2331 | ||
2332 | if (!pci_find_capability(dev, PCI_CAP_ID_HT)) | ||
2333 | return; | ||
2334 | |||
2332 | pci_read_config_dword(dev, 0x74, &cfg); | 2335 | pci_read_config_dword(dev, 0x74, &cfg); |
2333 | 2336 | ||
2334 | if (cfg & ((1 << 2) | (1 << 15))) { | 2337 | if (cfg & ((1 << 2) | (1 << 15))) { |
@@ -2764,6 +2767,29 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_m | |||
2764 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); | 2767 | DECLARE_PCI_FIXUP_RESUME_EARLY(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_R5C832, ricoh_mmc_fixup_r5c832); |
2765 | #endif /*CONFIG_MMC_RICOH_MMC*/ | 2768 | #endif /*CONFIG_MMC_RICOH_MMC*/ |
2766 | 2769 | ||
2770 | #if defined(CONFIG_DMAR) || defined(CONFIG_INTR_REMAP) | ||
2771 | #define VTUNCERRMSK_REG 0x1ac | ||
2772 | #define VTD_MSK_SPEC_ERRORS (1 << 31) | ||
2773 | /* | ||
2774 | * This is a quirk for masking vt-d spec defined errors to platform error | ||
2775 | * handling logic. With out this, platforms using Intel 7500, 5500 chipsets | ||
2776 | * (and the derivative chipsets like X58 etc) seem to generate NMI/SMI (based | ||
2777 | * on the RAS config settings of the platform) when a vt-d fault happens. | ||
2778 | * The resulting SMI caused the system to hang. | ||
2779 | * | ||
2780 | * VT-d spec related errors are already handled by the VT-d OS code, so no | ||
2781 | * need to report the same error through other channels. | ||
2782 | */ | ||
2783 | static void vtd_mask_spec_errors(struct pci_dev *dev) | ||
2784 | { | ||
2785 | u32 word; | ||
2786 | |||
2787 | pci_read_config_dword(dev, VTUNCERRMSK_REG, &word); | ||
2788 | pci_write_config_dword(dev, VTUNCERRMSK_REG, word | VTD_MSK_SPEC_ERRORS); | ||
2789 | } | ||
2790 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x342e, vtd_mask_spec_errors); | ||
2791 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, 0x3c28, vtd_mask_spec_errors); | ||
2792 | #endif | ||
2767 | 2793 | ||
2768 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, | 2794 | static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, |
2769 | struct pci_fixup *end) | 2795 | struct pci_fixup *end) |
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 60a5a5c6b50a..d235f44fd7a3 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c | |||
@@ -81,6 +81,8 @@ MODULE_PARM_DESC(wapf, "WAPF value"); | |||
81 | 81 | ||
82 | static int wlan_status = 1; | 82 | static int wlan_status = 1; |
83 | static int bluetooth_status = 1; | 83 | static int bluetooth_status = 1; |
84 | static int wimax_status = -1; | ||
85 | static int wwan_status = -1; | ||
84 | 86 | ||
85 | module_param(wlan_status, int, 0444); | 87 | module_param(wlan_status, int, 0444); |
86 | MODULE_PARM_DESC(wlan_status, "Set the wireless status on boot " | 88 | MODULE_PARM_DESC(wlan_status, "Set the wireless status on boot " |
@@ -92,6 +94,16 @@ MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot " | |||
92 | "(0 = disabled, 1 = enabled, -1 = don't do anything). " | 94 | "(0 = disabled, 1 = enabled, -1 = don't do anything). " |
93 | "default is 1"); | 95 | "default is 1"); |
94 | 96 | ||
97 | module_param(wimax_status, int, 0444); | ||
98 | MODULE_PARM_DESC(wimax_status, "Set the wireless status on boot " | ||
99 | "(0 = disabled, 1 = enabled, -1 = don't do anything). " | ||
100 | "default is 1"); | ||
101 | |||
102 | module_param(wwan_status, int, 0444); | ||
103 | MODULE_PARM_DESC(wwan_status, "Set the wireless status on boot " | ||
104 | "(0 = disabled, 1 = enabled, -1 = don't do anything). " | ||
105 | "default is 1"); | ||
106 | |||
95 | /* | 107 | /* |
96 | * Some events we use, same for all Asus | 108 | * Some events we use, same for all Asus |
97 | */ | 109 | */ |
@@ -114,6 +126,8 @@ MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot " | |||
114 | */ | 126 | */ |
115 | #define WL_RSTS 0x01 /* internal Wifi */ | 127 | #define WL_RSTS 0x01 /* internal Wifi */ |
116 | #define BT_RSTS 0x02 /* internal Bluetooth */ | 128 | #define BT_RSTS 0x02 /* internal Bluetooth */ |
129 | #define WM_RSTS 0x08 /* internal wimax */ | ||
130 | #define WW_RSTS 0x20 /* internal wwan */ | ||
117 | 131 | ||
118 | /* LED */ | 132 | /* LED */ |
119 | #define METHOD_MLED "MLED" | 133 | #define METHOD_MLED "MLED" |
@@ -132,6 +146,11 @@ MODULE_PARM_DESC(bluetooth_status, "Set the wireless status on boot " | |||
132 | */ | 146 | */ |
133 | #define METHOD_WLAN "WLED" | 147 | #define METHOD_WLAN "WLED" |
134 | #define METHOD_BLUETOOTH "BLED" | 148 | #define METHOD_BLUETOOTH "BLED" |
149 | |||
150 | /* WWAN and WIMAX */ | ||
151 | #define METHOD_WWAN "GSMC" | ||
152 | #define METHOD_WIMAX "WMXC" | ||
153 | |||
135 | #define METHOD_WL_STATUS "RSTS" | 154 | #define METHOD_WL_STATUS "RSTS" |
136 | 155 | ||
137 | /* Brightness */ | 156 | /* Brightness */ |
@@ -883,6 +902,64 @@ static ssize_t store_bluetooth(struct device *dev, | |||
883 | } | 902 | } |
884 | 903 | ||
885 | /* | 904 | /* |
905 | * Wimax | ||
906 | */ | ||
907 | static int asus_wimax_set(struct asus_laptop *asus, int status) | ||
908 | { | ||
909 | if (write_acpi_int(asus->handle, METHOD_WIMAX, !!status)) { | ||
910 | pr_warning("Error setting wimax status to %d", status); | ||
911 | return -EIO; | ||
912 | } | ||
913 | return 0; | ||
914 | } | ||
915 | |||
916 | static ssize_t show_wimax(struct device *dev, | ||
917 | struct device_attribute *attr, char *buf) | ||
918 | { | ||
919 | struct asus_laptop *asus = dev_get_drvdata(dev); | ||
920 | |||
921 | return sprintf(buf, "%d\n", asus_wireless_status(asus, WM_RSTS)); | ||
922 | } | ||
923 | |||
924 | static ssize_t store_wimax(struct device *dev, | ||
925 | struct device_attribute *attr, const char *buf, | ||
926 | size_t count) | ||
927 | { | ||
928 | struct asus_laptop *asus = dev_get_drvdata(dev); | ||
929 | |||
930 | return sysfs_acpi_set(asus, buf, count, METHOD_WIMAX); | ||
931 | } | ||
932 | |||
933 | /* | ||
934 | * Wwan | ||
935 | */ | ||
936 | static int asus_wwan_set(struct asus_laptop *asus, int status) | ||
937 | { | ||
938 | if (write_acpi_int(asus->handle, METHOD_WWAN, !!status)) { | ||
939 | pr_warning("Error setting wwan status to %d", status); | ||
940 | return -EIO; | ||
941 | } | ||
942 | return 0; | ||
943 | } | ||
944 | |||
945 | static ssize_t show_wwan(struct device *dev, | ||
946 | struct device_attribute *attr, char *buf) | ||
947 | { | ||
948 | struct asus_laptop *asus = dev_get_drvdata(dev); | ||
949 | |||
950 | return sprintf(buf, "%d\n", asus_wireless_status(asus, WW_RSTS)); | ||
951 | } | ||
952 | |||
953 | static ssize_t store_wwan(struct device *dev, | ||
954 | struct device_attribute *attr, const char *buf, | ||
955 | size_t count) | ||
956 | { | ||
957 | struct asus_laptop *asus = dev_get_drvdata(dev); | ||
958 | |||
959 | return sysfs_acpi_set(asus, buf, count, METHOD_WWAN); | ||
960 | } | ||
961 | |||
962 | /* | ||
886 | * Display | 963 | * Display |
887 | */ | 964 | */ |
888 | static void asus_set_display(struct asus_laptop *asus, int value) | 965 | static void asus_set_display(struct asus_laptop *asus, int value) |
@@ -1202,6 +1279,8 @@ static DEVICE_ATTR(infos, S_IRUGO, show_infos, NULL); | |||
1202 | static DEVICE_ATTR(wlan, S_IRUGO | S_IWUSR, show_wlan, store_wlan); | 1279 | static DEVICE_ATTR(wlan, S_IRUGO | S_IWUSR, show_wlan, store_wlan); |
1203 | static DEVICE_ATTR(bluetooth, S_IRUGO | S_IWUSR, | 1280 | static DEVICE_ATTR(bluetooth, S_IRUGO | S_IWUSR, |
1204 | show_bluetooth, store_bluetooth); | 1281 | show_bluetooth, store_bluetooth); |
1282 | static DEVICE_ATTR(wimax, S_IRUGO | S_IWUSR, show_wimax, store_wimax); | ||
1283 | static DEVICE_ATTR(wwan, S_IRUGO | S_IWUSR, show_wwan, store_wwan); | ||
1205 | static DEVICE_ATTR(display, S_IRUGO | S_IWUSR, show_disp, store_disp); | 1284 | static DEVICE_ATTR(display, S_IRUGO | S_IWUSR, show_disp, store_disp); |
1206 | static DEVICE_ATTR(ledd, S_IRUGO | S_IWUSR, show_ledd, store_ledd); | 1285 | static DEVICE_ATTR(ledd, S_IRUGO | S_IWUSR, show_ledd, store_ledd); |
1207 | static DEVICE_ATTR(ls_level, S_IRUGO | S_IWUSR, show_lslvl, store_lslvl); | 1286 | static DEVICE_ATTR(ls_level, S_IRUGO | S_IWUSR, show_lslvl, store_lslvl); |
@@ -1212,6 +1291,8 @@ static struct attribute *asus_attributes[] = { | |||
1212 | &dev_attr_infos.attr, | 1291 | &dev_attr_infos.attr, |
1213 | &dev_attr_wlan.attr, | 1292 | &dev_attr_wlan.attr, |
1214 | &dev_attr_bluetooth.attr, | 1293 | &dev_attr_bluetooth.attr, |
1294 | &dev_attr_wimax.attr, | ||
1295 | &dev_attr_wwan.attr, | ||
1215 | &dev_attr_display.attr, | 1296 | &dev_attr_display.attr, |
1216 | &dev_attr_ledd.attr, | 1297 | &dev_attr_ledd.attr, |
1217 | &dev_attr_ls_level.attr, | 1298 | &dev_attr_ls_level.attr, |
@@ -1239,6 +1320,13 @@ static mode_t asus_sysfs_is_visible(struct kobject *kobj, | |||
1239 | } else if (attr == &dev_attr_display.attr) { | 1320 | } else if (attr == &dev_attr_display.attr) { |
1240 | supported = !acpi_check_handle(handle, METHOD_SWITCH_DISPLAY, NULL); | 1321 | supported = !acpi_check_handle(handle, METHOD_SWITCH_DISPLAY, NULL); |
1241 | 1322 | ||
1323 | } else if (attr == &dev_attr_wimax.attr) { | ||
1324 | supported = | ||
1325 | !acpi_check_handle(asus->handle, METHOD_WIMAX, NULL); | ||
1326 | |||
1327 | } else if (attr == &dev_attr_wwan.attr) { | ||
1328 | supported = !acpi_check_handle(asus->handle, METHOD_WWAN, NULL); | ||
1329 | |||
1242 | } else if (attr == &dev_attr_ledd.attr) { | 1330 | } else if (attr == &dev_attr_ledd.attr) { |
1243 | supported = !acpi_check_handle(handle, METHOD_LEDD, NULL); | 1331 | supported = !acpi_check_handle(handle, METHOD_LEDD, NULL); |
1244 | 1332 | ||
@@ -1397,7 +1485,8 @@ static int asus_laptop_get_info(struct asus_laptop *asus) | |||
1397 | 1485 | ||
1398 | /* | 1486 | /* |
1399 | * The HWRS method return informations about the hardware. | 1487 | * The HWRS method return informations about the hardware. |
1400 | * 0x80 bit is for WLAN, 0x100 for Bluetooth. | 1488 | * 0x80 bit is for WLAN, 0x100 for Bluetooth, |
1489 | * 0x40 for WWAN, 0x10 for WIMAX. | ||
1401 | * The significance of others is yet to be found. | 1490 | * The significance of others is yet to be found. |
1402 | */ | 1491 | */ |
1403 | status = | 1492 | status = |
@@ -1440,6 +1529,12 @@ static int __devinit asus_acpi_init(struct asus_laptop *asus) | |||
1440 | if (wlan_status >= 0) | 1529 | if (wlan_status >= 0) |
1441 | asus_wlan_set(asus, !!wlan_status); | 1530 | asus_wlan_set(asus, !!wlan_status); |
1442 | 1531 | ||
1532 | if (wimax_status >= 0) | ||
1533 | asus_wimax_set(asus, !!wimax_status); | ||
1534 | |||
1535 | if (wwan_status >= 0) | ||
1536 | asus_wwan_set(asus, !!wwan_status); | ||
1537 | |||
1443 | /* Keyboard Backlight is on by default */ | 1538 | /* Keyboard Backlight is on by default */ |
1444 | if (!acpi_check_handle(asus->handle, METHOD_KBD_LIGHT_SET, NULL)) | 1539 | if (!acpi_check_handle(asus->handle, METHOD_KBD_LIGHT_SET, NULL)) |
1445 | asus_kled_set(asus, 1); | 1540 | asus_kled_set(asus, 1); |
diff --git a/drivers/platform/x86/eeepc-wmi.c b/drivers/platform/x86/eeepc-wmi.c index 462ceab93f87..0d50fbbe2478 100644 --- a/drivers/platform/x86/eeepc-wmi.c +++ b/drivers/platform/x86/eeepc-wmi.c | |||
@@ -298,8 +298,8 @@ static void eeepc_wmi_notify(u32 value, void *context) | |||
298 | kfree(obj); | 298 | kfree(obj); |
299 | } | 299 | } |
300 | 300 | ||
301 | static int store_cpufv(struct device *dev, struct device_attribute *attr, | 301 | static ssize_t store_cpufv(struct device *dev, struct device_attribute *attr, |
302 | const char *buf, size_t count) | 302 | const char *buf, size_t count) |
303 | { | 303 | { |
304 | int value; | 304 | int value; |
305 | struct acpi_buffer input = { (acpi_size)sizeof(value), &value }; | 305 | struct acpi_buffer input = { (acpi_size)sizeof(value), &value }; |
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index f44cd2620ff9..cf6c47250c56 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c | |||
@@ -689,7 +689,7 @@ static int acpi_fujitsu_add(struct acpi_device *device) | |||
689 | if (error) | 689 | if (error) |
690 | goto err_free_input_dev; | 690 | goto err_free_input_dev; |
691 | 691 | ||
692 | result = acpi_bus_get_power(fujitsu->acpi_handle, &state); | 692 | result = acpi_bus_update_power(fujitsu->acpi_handle, &state); |
693 | if (result) { | 693 | if (result) { |
694 | printk(KERN_ERR "Error reading power state\n"); | 694 | printk(KERN_ERR "Error reading power state\n"); |
695 | goto err_unregister_input_dev; | 695 | goto err_unregister_input_dev; |
@@ -857,7 +857,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
857 | if (error) | 857 | if (error) |
858 | goto err_free_input_dev; | 858 | goto err_free_input_dev; |
859 | 859 | ||
860 | result = acpi_bus_get_power(fujitsu_hotkey->acpi_handle, &state); | 860 | result = acpi_bus_update_power(fujitsu_hotkey->acpi_handle, &state); |
861 | if (result) { | 861 | if (result) { |
862 | printk(KERN_ERR "Error reading power state\n"); | 862 | printk(KERN_ERR "Error reading power state\n"); |
863 | goto err_unregister_input_dev; | 863 | goto err_unregister_input_dev; |
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index 1dac659b5e0c..9e05af9c41cb 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
@@ -172,6 +172,8 @@ static int hp_wmi_perform_query(int query, int write, u32 *buffer, | |||
172 | bios_return = *((struct bios_return *)obj->buffer.pointer); | 172 | bios_return = *((struct bios_return *)obj->buffer.pointer); |
173 | 173 | ||
174 | memcpy(buffer, &bios_return.value, sizeof(bios_return.value)); | 174 | memcpy(buffer, &bios_return.value, sizeof(bios_return.value)); |
175 | |||
176 | kfree(obj); | ||
175 | return 0; | 177 | return 0; |
176 | } | 178 | } |
177 | 179 | ||
diff --git a/drivers/platform/x86/ibm_rtl.c b/drivers/platform/x86/ibm_rtl.c index 3c2c6b91ecb3..94a114aa8e28 100644 --- a/drivers/platform/x86/ibm_rtl.c +++ b/drivers/platform/x86/ibm_rtl.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/io.h> | 28 | #include <linux/io.h> |
29 | #include <linux/sysdev.h> | 29 | #include <linux/sysdev.h> |
30 | #include <linux/dmi.h> | 30 | #include <linux/dmi.h> |
31 | #include <linux/efi.h> | ||
31 | #include <linux/mutex.h> | 32 | #include <linux/mutex.h> |
32 | #include <asm/bios_ebda.h> | 33 | #include <asm/bios_ebda.h> |
33 | 34 | ||
@@ -220,32 +221,13 @@ static void rtl_teardown_sysfs(void) { | |||
220 | sysdev_class_unregister(&class_rtl); | 221 | sysdev_class_unregister(&class_rtl); |
221 | } | 222 | } |
222 | 223 | ||
223 | static int dmi_check_cb(const struct dmi_system_id *id) | ||
224 | { | ||
225 | RTL_DEBUG("found IBM server '%s'\n", id->ident); | ||
226 | return 0; | ||
227 | } | ||
228 | |||
229 | #define ibm_dmi_entry(NAME, TYPE) \ | ||
230 | { \ | ||
231 | .ident = NAME, \ | ||
232 | .matches = { \ | ||
233 | DMI_MATCH(DMI_SYS_VENDOR, "IBM"), \ | ||
234 | DMI_MATCH(DMI_PRODUCT_NAME, TYPE), \ | ||
235 | }, \ | ||
236 | .callback = dmi_check_cb \ | ||
237 | } | ||
238 | 224 | ||
239 | static struct dmi_system_id __initdata ibm_rtl_dmi_table[] = { | 225 | static struct dmi_system_id __initdata ibm_rtl_dmi_table[] = { |
240 | ibm_dmi_entry("BladeCenter LS21", "7971"), | 226 | { \ |
241 | ibm_dmi_entry("BladeCenter LS22", "7901"), | 227 | .matches = { \ |
242 | ibm_dmi_entry("BladeCenter HS21 XM", "7995"), | 228 | DMI_MATCH(DMI_SYS_VENDOR, "IBM"), \ |
243 | ibm_dmi_entry("BladeCenter HS22", "7870"), | 229 | }, \ |
244 | ibm_dmi_entry("BladeCenter HS22V", "7871"), | 230 | }, |
245 | ibm_dmi_entry("System x3550 M2", "7946"), | ||
246 | ibm_dmi_entry("System x3650 M2", "7947"), | ||
247 | ibm_dmi_entry("System x3550 M3", "7944"), | ||
248 | ibm_dmi_entry("System x3650 M3", "7945"), | ||
249 | { } | 231 | { } |
250 | }; | 232 | }; |
251 | 233 | ||
@@ -257,7 +239,7 @@ static int __init ibm_rtl_init(void) { | |||
257 | if (force) | 239 | if (force) |
258 | pr_warning("ibm-rtl: module loaded by force\n"); | 240 | pr_warning("ibm-rtl: module loaded by force\n"); |
259 | /* first ensure that we are running on IBM HW */ | 241 | /* first ensure that we are running on IBM HW */ |
260 | else if (!dmi_check_system(ibm_rtl_dmi_table)) | 242 | else if (efi_enabled || !dmi_check_system(ibm_rtl_dmi_table)) |
261 | return -ENODEV; | 243 | return -ENODEV; |
262 | 244 | ||
263 | /* Get the address for the Extended BIOS Data Area */ | 245 | /* Get the address for the Extended BIOS Data Area */ |
@@ -302,7 +284,7 @@ static int __init ibm_rtl_init(void) { | |||
302 | RTL_DEBUG("rtl_cmd_width = %u, rtl_cmd_type = %u\n", | 284 | RTL_DEBUG("rtl_cmd_width = %u, rtl_cmd_type = %u\n", |
303 | rtl_cmd_width, rtl_cmd_type); | 285 | rtl_cmd_width, rtl_cmd_type); |
304 | addr = ioread32(&rtl_table->cmd_port_address); | 286 | addr = ioread32(&rtl_table->cmd_port_address); |
305 | RTL_DEBUG("addr = %#llx\n", addr); | 287 | RTL_DEBUG("addr = %#llx\n", (unsigned long long)addr); |
306 | plen = rtl_cmd_width/sizeof(char); | 288 | plen = rtl_cmd_width/sizeof(char); |
307 | rtl_cmd_addr = rtl_port_map(addr, plen); | 289 | rtl_cmd_addr = rtl_port_map(addr, plen); |
308 | RTL_DEBUG("rtl_cmd_addr = %#llx\n", (u64)rtl_cmd_addr); | 290 | RTL_DEBUG("rtl_cmd_addr = %#llx\n", (u64)rtl_cmd_addr); |
diff --git a/drivers/platform/x86/intel_ips.c b/drivers/platform/x86/intel_ips.c index c44a5e8b8b82..f0b3ad13c273 100644 --- a/drivers/platform/x86/intel_ips.c +++ b/drivers/platform/x86/intel_ips.c | |||
@@ -75,6 +75,7 @@ | |||
75 | #include <drm/i915_drm.h> | 75 | #include <drm/i915_drm.h> |
76 | #include <asm/msr.h> | 76 | #include <asm/msr.h> |
77 | #include <asm/processor.h> | 77 | #include <asm/processor.h> |
78 | #include "intel_ips.h" | ||
78 | 79 | ||
79 | #define PCI_DEVICE_ID_INTEL_THERMAL_SENSOR 0x3b32 | 80 | #define PCI_DEVICE_ID_INTEL_THERMAL_SENSOR 0x3b32 |
80 | 81 | ||
@@ -245,6 +246,7 @@ | |||
245 | #define thm_writel(off, val) writel((val), ips->regmap + (off)) | 246 | #define thm_writel(off, val) writel((val), ips->regmap + (off)) |
246 | 247 | ||
247 | static const int IPS_ADJUST_PERIOD = 5000; /* ms */ | 248 | static const int IPS_ADJUST_PERIOD = 5000; /* ms */ |
249 | static bool late_i915_load = false; | ||
248 | 250 | ||
249 | /* For initial average collection */ | 251 | /* For initial average collection */ |
250 | static const int IPS_SAMPLE_PERIOD = 200; /* ms */ | 252 | static const int IPS_SAMPLE_PERIOD = 200; /* ms */ |
@@ -339,6 +341,9 @@ struct ips_driver { | |||
339 | u64 orig_turbo_ratios; | 341 | u64 orig_turbo_ratios; |
340 | }; | 342 | }; |
341 | 343 | ||
344 | static bool | ||
345 | ips_gpu_turbo_enabled(struct ips_driver *ips); | ||
346 | |||
342 | /** | 347 | /** |
343 | * ips_cpu_busy - is CPU busy? | 348 | * ips_cpu_busy - is CPU busy? |
344 | * @ips: IPS driver struct | 349 | * @ips: IPS driver struct |
@@ -517,7 +522,7 @@ static void ips_disable_cpu_turbo(struct ips_driver *ips) | |||
517 | */ | 522 | */ |
518 | static bool ips_gpu_busy(struct ips_driver *ips) | 523 | static bool ips_gpu_busy(struct ips_driver *ips) |
519 | { | 524 | { |
520 | if (!ips->gpu_turbo_enabled) | 525 | if (!ips_gpu_turbo_enabled(ips)) |
521 | return false; | 526 | return false; |
522 | 527 | ||
523 | return ips->gpu_busy(); | 528 | return ips->gpu_busy(); |
@@ -532,7 +537,7 @@ static bool ips_gpu_busy(struct ips_driver *ips) | |||
532 | */ | 537 | */ |
533 | static void ips_gpu_raise(struct ips_driver *ips) | 538 | static void ips_gpu_raise(struct ips_driver *ips) |
534 | { | 539 | { |
535 | if (!ips->gpu_turbo_enabled) | 540 | if (!ips_gpu_turbo_enabled(ips)) |
536 | return; | 541 | return; |
537 | 542 | ||
538 | if (!ips->gpu_raise()) | 543 | if (!ips->gpu_raise()) |
@@ -549,7 +554,7 @@ static void ips_gpu_raise(struct ips_driver *ips) | |||
549 | */ | 554 | */ |
550 | static void ips_gpu_lower(struct ips_driver *ips) | 555 | static void ips_gpu_lower(struct ips_driver *ips) |
551 | { | 556 | { |
552 | if (!ips->gpu_turbo_enabled) | 557 | if (!ips_gpu_turbo_enabled(ips)) |
553 | return; | 558 | return; |
554 | 559 | ||
555 | if (!ips->gpu_lower()) | 560 | if (!ips->gpu_lower()) |
@@ -1454,6 +1459,31 @@ out_err: | |||
1454 | return false; | 1459 | return false; |
1455 | } | 1460 | } |
1456 | 1461 | ||
1462 | static bool | ||
1463 | ips_gpu_turbo_enabled(struct ips_driver *ips) | ||
1464 | { | ||
1465 | if (!ips->gpu_busy && late_i915_load) { | ||
1466 | if (ips_get_i915_syms(ips)) { | ||
1467 | dev_info(&ips->dev->dev, | ||
1468 | "i915 driver attached, reenabling gpu turbo\n"); | ||
1469 | ips->gpu_turbo_enabled = !(thm_readl(THM_HTS) & HTS_GTD_DIS); | ||
1470 | } | ||
1471 | } | ||
1472 | |||
1473 | return ips->gpu_turbo_enabled; | ||
1474 | } | ||
1475 | |||
1476 | void | ||
1477 | ips_link_to_i915_driver() | ||
1478 | { | ||
1479 | /* We can't cleanly get at the various ips_driver structs from | ||
1480 | * this caller (the i915 driver), so just set a flag saying | ||
1481 | * that it's time to try getting the symbols again. | ||
1482 | */ | ||
1483 | late_i915_load = true; | ||
1484 | } | ||
1485 | EXPORT_SYMBOL_GPL(ips_link_to_i915_driver); | ||
1486 | |||
1457 | static DEFINE_PCI_DEVICE_TABLE(ips_id_table) = { | 1487 | static DEFINE_PCI_DEVICE_TABLE(ips_id_table) = { |
1458 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, | 1488 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, |
1459 | PCI_DEVICE_ID_INTEL_THERMAL_SENSOR), }, | 1489 | PCI_DEVICE_ID_INTEL_THERMAL_SENSOR), }, |
diff --git a/drivers/platform/x86/intel_ips.h b/drivers/platform/x86/intel_ips.h new file mode 100644 index 000000000000..73299beff5b3 --- /dev/null +++ b/drivers/platform/x86/intel_ips.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2010 Intel Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License along with | ||
14 | * this program; if not, write to the Free Software Foundation, Inc., | ||
15 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | ||
16 | * | ||
17 | * The full GNU General Public License is included in this distribution in | ||
18 | * the file called "COPYING". | ||
19 | */ | ||
20 | |||
21 | void ips_link_to_i915_driver(void); | ||
diff --git a/drivers/platform/x86/msi-wmi.c b/drivers/platform/x86/msi-wmi.c index 42a5469a2459..35278ad7e628 100644 --- a/drivers/platform/x86/msi-wmi.c +++ b/drivers/platform/x86/msi-wmi.c | |||
@@ -43,16 +43,18 @@ MODULE_ALIAS("wmi:B6F3EEF2-3D2F-49DC-9DE3-85BCE18C62F2"); | |||
43 | 43 | ||
44 | #define dprintk(msg...) pr_debug(DRV_PFX msg) | 44 | #define dprintk(msg...) pr_debug(DRV_PFX msg) |
45 | 45 | ||
46 | #define KEYCODE_BASE 0xD0 | 46 | #define SCANCODE_BASE 0xD0 |
47 | #define MSI_WMI_BRIGHTNESSUP KEYCODE_BASE | 47 | #define MSI_WMI_BRIGHTNESSUP SCANCODE_BASE |
48 | #define MSI_WMI_BRIGHTNESSDOWN (KEYCODE_BASE + 1) | 48 | #define MSI_WMI_BRIGHTNESSDOWN (SCANCODE_BASE + 1) |
49 | #define MSI_WMI_VOLUMEUP (KEYCODE_BASE + 2) | 49 | #define MSI_WMI_VOLUMEUP (SCANCODE_BASE + 2) |
50 | #define MSI_WMI_VOLUMEDOWN (KEYCODE_BASE + 3) | 50 | #define MSI_WMI_VOLUMEDOWN (SCANCODE_BASE + 3) |
51 | #define MSI_WMI_MUTE (SCANCODE_BASE + 4) | ||
51 | static struct key_entry msi_wmi_keymap[] = { | 52 | static struct key_entry msi_wmi_keymap[] = { |
52 | { KE_KEY, MSI_WMI_BRIGHTNESSUP, {KEY_BRIGHTNESSUP} }, | 53 | { KE_KEY, MSI_WMI_BRIGHTNESSUP, {KEY_BRIGHTNESSUP} }, |
53 | { KE_KEY, MSI_WMI_BRIGHTNESSDOWN, {KEY_BRIGHTNESSDOWN} }, | 54 | { KE_KEY, MSI_WMI_BRIGHTNESSDOWN, {KEY_BRIGHTNESSDOWN} }, |
54 | { KE_KEY, MSI_WMI_VOLUMEUP, {KEY_VOLUMEUP} }, | 55 | { KE_KEY, MSI_WMI_VOLUMEUP, {KEY_VOLUMEUP} }, |
55 | { KE_KEY, MSI_WMI_VOLUMEDOWN, {KEY_VOLUMEDOWN} }, | 56 | { KE_KEY, MSI_WMI_VOLUMEDOWN, {KEY_VOLUMEDOWN} }, |
57 | { KE_KEY, MSI_WMI_MUTE, {KEY_MUTE} }, | ||
56 | { KE_END, 0} | 58 | { KE_END, 0} |
57 | }; | 59 | }; |
58 | static ktime_t last_pressed[ARRAY_SIZE(msi_wmi_keymap) - 1]; | 60 | static ktime_t last_pressed[ARRAY_SIZE(msi_wmi_keymap) - 1]; |
@@ -169,7 +171,7 @@ static void msi_wmi_notify(u32 value, void *context) | |||
169 | ktime_t diff; | 171 | ktime_t diff; |
170 | cur = ktime_get_real(); | 172 | cur = ktime_get_real(); |
171 | diff = ktime_sub(cur, last_pressed[key->code - | 173 | diff = ktime_sub(cur, last_pressed[key->code - |
172 | KEYCODE_BASE]); | 174 | SCANCODE_BASE]); |
173 | /* Ignore event if the same event happened in a 50 ms | 175 | /* Ignore event if the same event happened in a 50 ms |
174 | timeframe -> Key press may result in 10-20 GPEs */ | 176 | timeframe -> Key press may result in 10-20 GPEs */ |
175 | if (ktime_to_us(diff) < 1000 * 50) { | 177 | if (ktime_to_us(diff) < 1000 * 50) { |
@@ -178,7 +180,7 @@ static void msi_wmi_notify(u32 value, void *context) | |||
178 | key->code, ktime_to_us(diff)); | 180 | key->code, ktime_to_us(diff)); |
179 | return; | 181 | return; |
180 | } | 182 | } |
181 | last_pressed[key->code - KEYCODE_BASE] = cur; | 183 | last_pressed[key->code - SCANCODE_BASE] = cur; |
182 | 184 | ||
183 | if (key->type == KE_KEY && | 185 | if (key->type == KE_KEY && |
184 | /* Brightness is served via acpi video driver */ | 186 | /* Brightness is served via acpi video driver */ |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 2d61186ad5a2..e8c21994b36d 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -8497,7 +8497,6 @@ static void ibm_exit(struct ibm_struct *ibm) | |||
8497 | ibm->acpi->type, | 8497 | ibm->acpi->type, |
8498 | dispatch_acpi_notify); | 8498 | dispatch_acpi_notify); |
8499 | ibm->flags.acpi_notify_installed = 0; | 8499 | ibm->flags.acpi_notify_installed = 0; |
8500 | ibm->flags.acpi_notify_installed = 0; | ||
8501 | } | 8500 | } |
8502 | 8501 | ||
8503 | if (ibm->flags.proc_created) { | 8502 | if (ibm->flags.proc_created) { |
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 06f304f46e02..4276da7291b8 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
@@ -135,6 +135,7 @@ static const struct key_entry toshiba_acpi_keymap[] __initconst = { | |||
135 | { KE_KEY, 0x141, { KEY_BRIGHTNESSUP } }, | 135 | { KE_KEY, 0x141, { KEY_BRIGHTNESSUP } }, |
136 | { KE_KEY, 0x142, { KEY_WLAN } }, | 136 | { KE_KEY, 0x142, { KEY_WLAN } }, |
137 | { KE_KEY, 0x143, { KEY_PROG1 } }, | 137 | { KE_KEY, 0x143, { KEY_PROG1 } }, |
138 | { KE_KEY, 0x17f, { KEY_FN } }, | ||
138 | { KE_KEY, 0xb05, { KEY_PROG2 } }, | 139 | { KE_KEY, 0xb05, { KEY_PROG2 } }, |
139 | { KE_KEY, 0xb06, { KEY_WWW } }, | 140 | { KE_KEY, 0xb06, { KEY_WWW } }, |
140 | { KE_KEY, 0xb07, { KEY_MAIL } }, | 141 | { KE_KEY, 0xb07, { KEY_MAIL } }, |
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 104b77c87ef5..aecd9a9b549f 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c | |||
@@ -755,7 +755,7 @@ static bool guid_already_parsed(const char *guid_string) | |||
755 | struct wmi_block *wblock; | 755 | struct wmi_block *wblock; |
756 | 756 | ||
757 | list_for_each_entry(wblock, &wmi_block_list, list) | 757 | list_for_each_entry(wblock, &wmi_block_list, list) |
758 | if (strncmp(wblock->gblock.guid, guid_string, 16) == 0) | 758 | if (memcmp(wblock->gblock.guid, guid_string, 16) == 0) |
759 | return true; | 759 | return true; |
760 | 760 | ||
761 | return false; | 761 | return false; |
diff --git a/drivers/pnp/Makefile b/drivers/pnp/Makefile index 8de3775ec242..bfba893cb321 100644 --- a/drivers/pnp/Makefile +++ b/drivers/pnp/Makefile | |||
@@ -2,11 +2,13 @@ | |||
2 | # Makefile for the Linux Plug-and-Play Support. | 2 | # Makefile for the Linux Plug-and-Play Support. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := core.o card.o driver.o resource.o manager.o support.o interface.o quirks.o | 5 | obj-y := pnp.o |
6 | |||
7 | pnp-y := core.o card.o driver.o resource.o manager.o support.o interface.o quirks.o | ||
6 | 8 | ||
7 | obj-$(CONFIG_PNPACPI) += pnpacpi/ | 9 | obj-$(CONFIG_PNPACPI) += pnpacpi/ |
8 | obj-$(CONFIG_PNPBIOS) += pnpbios/ | 10 | obj-$(CONFIG_PNPBIOS) += pnpbios/ |
9 | obj-$(CONFIG_ISAPNP) += isapnp/ | 11 | obj-$(CONFIG_ISAPNP) += isapnp/ |
10 | 12 | ||
11 | # pnp_system_init goes after pnpacpi/pnpbios init | 13 | # pnp_system_init goes after pnpacpi/pnpbios init |
12 | obj-y += system.o | 14 | pnp-y += system.o |
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c index 0f34d962fd3c..cb6ce42f8e77 100644 --- a/drivers/pnp/core.c +++ b/drivers/pnp/core.c | |||
@@ -220,10 +220,5 @@ subsys_initcall(pnp_init); | |||
220 | int pnp_debug; | 220 | int pnp_debug; |
221 | 221 | ||
222 | #if defined(CONFIG_PNP_DEBUG_MESSAGES) | 222 | #if defined(CONFIG_PNP_DEBUG_MESSAGES) |
223 | static int __init pnp_debug_setup(char *__unused) | 223 | module_param_named(debug, pnp_debug, int, 0644); |
224 | { | ||
225 | pnp_debug = 1; | ||
226 | return 1; | ||
227 | } | ||
228 | __setup("pnp.debug", pnp_debug_setup); | ||
229 | #endif | 224 | #endif |
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c index d1dbb9df53fa..00e94032531a 100644 --- a/drivers/pnp/driver.c +++ b/drivers/pnp/driver.c | |||
@@ -189,8 +189,11 @@ static int pnp_bus_resume(struct device *dev) | |||
189 | if (!pnp_drv) | 189 | if (!pnp_drv) |
190 | return 0; | 190 | return 0; |
191 | 191 | ||
192 | if (pnp_dev->protocol->resume) | 192 | if (pnp_dev->protocol->resume) { |
193 | pnp_dev->protocol->resume(pnp_dev); | 193 | error = pnp_dev->protocol->resume(pnp_dev); |
194 | if (error) | ||
195 | return error; | ||
196 | } | ||
194 | 197 | ||
195 | if (pnp_can_write(pnp_dev)) { | 198 | if (pnp_can_write(pnp_dev)) { |
196 | error = pnp_start_dev(pnp_dev); | 199 | error = pnp_start_dev(pnp_dev); |
diff --git a/drivers/pnp/isapnp/Makefile b/drivers/pnp/isapnp/Makefile index cac18bbfb817..6e607aa33aa3 100644 --- a/drivers/pnp/isapnp/Makefile +++ b/drivers/pnp/isapnp/Makefile | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Makefile for the kernel ISAPNP driver. | 2 | # Makefile for the kernel ISAPNP driver. |
3 | # | 3 | # |
4 | obj-y += pnp.o | ||
5 | pnp-y := core.o compat.o | ||
4 | 6 | ||
5 | isapnp-proc-$(CONFIG_PROC_FS) = proc.o | 7 | pnp-$(CONFIG_PROC_FS) += proc.o |
6 | |||
7 | obj-y := core.o compat.o $(isapnp-proc-y) | ||
diff --git a/drivers/pnp/pnpacpi/Makefile b/drivers/pnp/pnpacpi/Makefile index 905326fcca85..40c93da18252 100644 --- a/drivers/pnp/pnpacpi/Makefile +++ b/drivers/pnp/pnpacpi/Makefile | |||
@@ -1,5 +1,6 @@ | |||
1 | # | 1 | # |
2 | # Makefile for the kernel PNPACPI driver. | 2 | # Makefile for the kernel PNPACPI driver. |
3 | # | 3 | # |
4 | obj-y += pnp.o | ||
4 | 5 | ||
5 | obj-y := core.o rsparser.o | 6 | pnp-y := core.o rsparser.o |
diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 2d73dfcecdbb..ca84d5099ce7 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c | |||
@@ -81,12 +81,19 @@ static int pnpacpi_get_resources(struct pnp_dev *dev) | |||
81 | 81 | ||
82 | static int pnpacpi_set_resources(struct pnp_dev *dev) | 82 | static int pnpacpi_set_resources(struct pnp_dev *dev) |
83 | { | 83 | { |
84 | struct acpi_device *acpi_dev = dev->data; | 84 | struct acpi_device *acpi_dev; |
85 | acpi_handle handle = acpi_dev->handle; | 85 | acpi_handle handle; |
86 | struct acpi_buffer buffer; | 86 | struct acpi_buffer buffer; |
87 | int ret; | 87 | int ret; |
88 | 88 | ||
89 | pnp_dbg(&dev->dev, "set resources\n"); | 89 | pnp_dbg(&dev->dev, "set resources\n"); |
90 | |||
91 | handle = DEVICE_ACPI_HANDLE(&dev->dev); | ||
92 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) { | ||
93 | dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); | ||
94 | return -ENODEV; | ||
95 | } | ||
96 | |||
90 | ret = pnpacpi_build_resource_template(dev, &buffer); | 97 | ret = pnpacpi_build_resource_template(dev, &buffer); |
91 | if (ret) | 98 | if (ret) |
92 | return ret; | 99 | return ret; |
@@ -105,12 +112,18 @@ static int pnpacpi_set_resources(struct pnp_dev *dev) | |||
105 | 112 | ||
106 | static int pnpacpi_disable_resources(struct pnp_dev *dev) | 113 | static int pnpacpi_disable_resources(struct pnp_dev *dev) |
107 | { | 114 | { |
108 | struct acpi_device *acpi_dev = dev->data; | 115 | struct acpi_device *acpi_dev; |
109 | acpi_handle handle = acpi_dev->handle; | 116 | acpi_handle handle; |
110 | int ret; | 117 | int ret; |
111 | 118 | ||
112 | dev_dbg(&dev->dev, "disable resources\n"); | 119 | dev_dbg(&dev->dev, "disable resources\n"); |
113 | 120 | ||
121 | handle = DEVICE_ACPI_HANDLE(&dev->dev); | ||
122 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) { | ||
123 | dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); | ||
124 | return 0; | ||
125 | } | ||
126 | |||
114 | /* acpi_unregister_gsi(pnp_irq(dev, 0)); */ | 127 | /* acpi_unregister_gsi(pnp_irq(dev, 0)); */ |
115 | ret = 0; | 128 | ret = 0; |
116 | if (acpi_bus_power_manageable(handle)) | 129 | if (acpi_bus_power_manageable(handle)) |
@@ -124,46 +137,74 @@ static int pnpacpi_disable_resources(struct pnp_dev *dev) | |||
124 | #ifdef CONFIG_ACPI_SLEEP | 137 | #ifdef CONFIG_ACPI_SLEEP |
125 | static bool pnpacpi_can_wakeup(struct pnp_dev *dev) | 138 | static bool pnpacpi_can_wakeup(struct pnp_dev *dev) |
126 | { | 139 | { |
127 | struct acpi_device *acpi_dev = dev->data; | 140 | struct acpi_device *acpi_dev; |
128 | acpi_handle handle = acpi_dev->handle; | 141 | acpi_handle handle; |
142 | |||
143 | handle = DEVICE_ACPI_HANDLE(&dev->dev); | ||
144 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) { | ||
145 | dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); | ||
146 | return false; | ||
147 | } | ||
129 | 148 | ||
130 | return acpi_bus_can_wakeup(handle); | 149 | return acpi_bus_can_wakeup(handle); |
131 | } | 150 | } |
132 | 151 | ||
133 | static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state) | 152 | static int pnpacpi_suspend(struct pnp_dev *dev, pm_message_t state) |
134 | { | 153 | { |
135 | struct acpi_device *acpi_dev = dev->data; | 154 | struct acpi_device *acpi_dev; |
136 | acpi_handle handle = acpi_dev->handle; | 155 | acpi_handle handle; |
137 | int power_state; | 156 | int error = 0; |
157 | |||
158 | handle = DEVICE_ACPI_HANDLE(&dev->dev); | ||
159 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) { | ||
160 | dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); | ||
161 | return 0; | ||
162 | } | ||
138 | 163 | ||
139 | if (device_can_wakeup(&dev->dev)) { | 164 | if (device_can_wakeup(&dev->dev)) { |
140 | int rc = acpi_pm_device_sleep_wake(&dev->dev, | 165 | error = acpi_pm_device_sleep_wake(&dev->dev, |
141 | device_may_wakeup(&dev->dev)); | 166 | device_may_wakeup(&dev->dev)); |
167 | if (error) | ||
168 | return error; | ||
169 | } | ||
170 | |||
171 | if (acpi_bus_power_manageable(handle)) { | ||
172 | int power_state = acpi_pm_device_sleep_state(&dev->dev, NULL); | ||
173 | |||
174 | if (power_state < 0) | ||
175 | power_state = (state.event == PM_EVENT_ON) ? | ||
176 | ACPI_STATE_D0 : ACPI_STATE_D3; | ||
142 | 177 | ||
143 | if (rc) | 178 | /* |
144 | return rc; | 179 | * acpi_bus_set_power() often fails (keyboard port can't be |
180 | * powered-down?), and in any case, our return value is ignored | ||
181 | * by pnp_bus_suspend(). Hence we don't revert the wakeup | ||
182 | * setting if the set_power fails. | ||
183 | */ | ||
184 | error = acpi_bus_set_power(handle, power_state); | ||
145 | } | 185 | } |
146 | power_state = acpi_pm_device_sleep_state(&dev->dev, NULL); | 186 | |
147 | if (power_state < 0) | 187 | return error; |
148 | power_state = (state.event == PM_EVENT_ON) ? | ||
149 | ACPI_STATE_D0 : ACPI_STATE_D3; | ||
150 | |||
151 | /* acpi_bus_set_power() often fails (keyboard port can't be | ||
152 | * powered-down?), and in any case, our return value is ignored | ||
153 | * by pnp_bus_suspend(). Hence we don't revert the wakeup | ||
154 | * setting if the set_power fails. | ||
155 | */ | ||
156 | return acpi_bus_set_power(handle, power_state); | ||
157 | } | 188 | } |
158 | 189 | ||
159 | static int pnpacpi_resume(struct pnp_dev *dev) | 190 | static int pnpacpi_resume(struct pnp_dev *dev) |
160 | { | 191 | { |
161 | struct acpi_device *acpi_dev = dev->data; | 192 | struct acpi_device *acpi_dev; |
162 | acpi_handle handle = acpi_dev->handle; | 193 | acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev); |
194 | int error = 0; | ||
195 | |||
196 | if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &acpi_dev))) { | ||
197 | dev_dbg(&dev->dev, "ACPI device not found in %s!\n", __func__); | ||
198 | return -ENODEV; | ||
199 | } | ||
163 | 200 | ||
164 | if (device_may_wakeup(&dev->dev)) | 201 | if (device_may_wakeup(&dev->dev)) |
165 | acpi_pm_device_sleep_wake(&dev->dev, false); | 202 | acpi_pm_device_sleep_wake(&dev->dev, false); |
166 | return acpi_bus_set_power(handle, ACPI_STATE_D0); | 203 | |
204 | if (acpi_bus_power_manageable(handle)) | ||
205 | error = acpi_bus_set_power(handle, ACPI_STATE_D0); | ||
206 | |||
207 | return error; | ||
167 | } | 208 | } |
168 | #endif | 209 | #endif |
169 | 210 | ||
@@ -180,7 +221,7 @@ struct pnp_protocol pnpacpi_protocol = { | |||
180 | }; | 221 | }; |
181 | EXPORT_SYMBOL(pnpacpi_protocol); | 222 | EXPORT_SYMBOL(pnpacpi_protocol); |
182 | 223 | ||
183 | static char *pnpacpi_get_id(struct acpi_device *device) | 224 | static char *__init pnpacpi_get_id(struct acpi_device *device) |
184 | { | 225 | { |
185 | struct acpi_hardware_id *id; | 226 | struct acpi_hardware_id *id; |
186 | 227 | ||
diff --git a/drivers/pnp/pnpbios/Makefile b/drivers/pnp/pnpbios/Makefile index 3cd3ed760605..240b0ffb83ca 100644 --- a/drivers/pnp/pnpbios/Makefile +++ b/drivers/pnp/pnpbios/Makefile | |||
@@ -1,7 +1,8 @@ | |||
1 | # | 1 | # |
2 | # Makefile for the kernel PNPBIOS driver. | 2 | # Makefile for the kernel PNPBIOS driver. |
3 | # | 3 | # |
4 | obj-y := pnp.o | ||
4 | 5 | ||
5 | pnpbios-proc-$(CONFIG_PNPBIOS_PROC_FS) = proc.o | 6 | pnp-y := core.o bioscalls.o rsparser.o |
6 | 7 | ||
7 | obj-y := core.o bioscalls.o rsparser.o $(pnpbios-proc-y) | 8 | pnp-$(CONFIG_PNPBIOS_PROC_FS) += proc.o |
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index 51237fbb1bbb..6d20b0454a1d 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c | |||
@@ -231,8 +231,7 @@ static int tps6586x_dvm_voltages[] = { | |||
231 | }; | 231 | }; |
232 | 232 | ||
233 | #define TPS6586X_REGULATOR(_id, vdata, _ops, vreg, shift, nbits, \ | 233 | #define TPS6586X_REGULATOR(_id, vdata, _ops, vreg, shift, nbits, \ |
234 | ereg0, ebit0, ereg1, ebit1, goreg, gobit) \ | 234 | ereg0, ebit0, ereg1, ebit1) \ |
235 | { \ | ||
236 | .desc = { \ | 235 | .desc = { \ |
237 | .name = "REG-" #_id, \ | 236 | .name = "REG-" #_id, \ |
238 | .ops = &tps6586x_regulator_##_ops, \ | 237 | .ops = &tps6586x_regulator_##_ops, \ |
@@ -248,18 +247,26 @@ static int tps6586x_dvm_voltages[] = { | |||
248 | .enable_bit[0] = (ebit0), \ | 247 | .enable_bit[0] = (ebit0), \ |
249 | .enable_reg[1] = TPS6586X_SUPPLY##ereg1, \ | 248 | .enable_reg[1] = TPS6586X_SUPPLY##ereg1, \ |
250 | .enable_bit[1] = (ebit1), \ | 249 | .enable_bit[1] = (ebit1), \ |
251 | .voltages = tps6586x_##vdata##_voltages, \ | 250 | .voltages = tps6586x_##vdata##_voltages, |
252 | } | 251 | |
252 | #define TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \ | ||
253 | .go_reg = TPS6586X_##goreg, \ | ||
254 | .go_bit = (gobit), | ||
253 | 255 | ||
254 | #define TPS6586X_LDO(_id, vdata, vreg, shift, nbits, \ | 256 | #define TPS6586X_LDO(_id, vdata, vreg, shift, nbits, \ |
255 | ereg0, ebit0, ereg1, ebit1) \ | 257 | ereg0, ebit0, ereg1, ebit1) \ |
258 | { \ | ||
256 | TPS6586X_REGULATOR(_id, vdata, ldo_ops, vreg, shift, nbits, \ | 259 | TPS6586X_REGULATOR(_id, vdata, ldo_ops, vreg, shift, nbits, \ |
257 | ereg0, ebit0, ereg1, ebit1, 0, 0) | 260 | ereg0, ebit0, ereg1, ebit1) \ |
261 | } | ||
258 | 262 | ||
259 | #define TPS6586X_DVM(_id, vdata, vreg, shift, nbits, \ | 263 | #define TPS6586X_DVM(_id, vdata, vreg, shift, nbits, \ |
260 | ereg0, ebit0, ereg1, ebit1, goreg, gobit) \ | 264 | ereg0, ebit0, ereg1, ebit1, goreg, gobit) \ |
265 | { \ | ||
261 | TPS6586X_REGULATOR(_id, vdata, dvm_ops, vreg, shift, nbits, \ | 266 | TPS6586X_REGULATOR(_id, vdata, dvm_ops, vreg, shift, nbits, \ |
262 | ereg0, ebit0, ereg1, ebit1, goreg, gobit) | 267 | ereg0, ebit0, ereg1, ebit1) \ |
268 | TPS6586X_REGULATOR_DVM_GOREG(goreg, gobit) \ | ||
269 | } | ||
263 | 270 | ||
264 | static struct tps6586x_regulator tps6586x_regulator[] = { | 271 | static struct tps6586x_regulator tps6586x_regulator[] = { |
265 | TPS6586X_LDO(LDO_0, ldo, SUPPLYV1, 5, 3, ENC, 0, END, 0), | 272 | TPS6586X_LDO(LDO_0, ldo, SUPPLYV1, 5, 3, ENC, 0, END, 0), |
@@ -267,11 +274,11 @@ static struct tps6586x_regulator tps6586x_regulator[] = { | |||
267 | TPS6586X_LDO(LDO_5, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6), | 274 | TPS6586X_LDO(LDO_5, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6), |
268 | TPS6586X_LDO(LDO_6, ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4), | 275 | TPS6586X_LDO(LDO_6, ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4), |
269 | TPS6586X_LDO(LDO_7, ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5), | 276 | TPS6586X_LDO(LDO_7, ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5), |
270 | TPS6586X_LDO(LDO_8, ldo, SUPPLYV1, 5, 3, ENC, 6, END, 6), | 277 | TPS6586X_LDO(LDO_8, ldo, SUPPLYV2, 5, 3, ENC, 6, END, 6), |
271 | TPS6586X_LDO(LDO_9, ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7), | 278 | TPS6586X_LDO(LDO_9, ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7), |
272 | TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, ENE, 7, ENE, 7), | 279 | TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7), |
273 | TPS6586X_LDO(LDO_1, dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1), | 280 | TPS6586X_LDO(LDO_1, dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1), |
274 | TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 1, END, 1), | 281 | TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7), |
275 | 282 | ||
276 | TPS6586X_DVM(LDO_2, dvm, LDO2BV1, 0, 5, ENA, 3, ENB, 3, VCC2, 6), | 283 | TPS6586X_DVM(LDO_2, dvm, LDO2BV1, 0, 5, ENA, 3, ENB, 3, VCC2, 6), |
277 | TPS6586X_DVM(LDO_4, ldo4, LDO4V1, 0, 5, ENC, 3, END, 3, VCC1, 6), | 284 | TPS6586X_DVM(LDO_4, ldo4, LDO4V1, 0, 5, ENC, 3, END, 3, VCC1, 6), |
@@ -290,6 +297,10 @@ static inline int tps6586x_regulator_preinit(struct device *parent, | |||
290 | uint8_t val1, val2; | 297 | uint8_t val1, val2; |
291 | int ret; | 298 | int ret; |
292 | 299 | ||
300 | if (ri->enable_reg[0] == ri->enable_reg[1] && | ||
301 | ri->enable_bit[0] == ri->enable_bit[1]) | ||
302 | return 0; | ||
303 | |||
293 | ret = tps6586x_read(parent, ri->enable_reg[0], &val1); | 304 | ret = tps6586x_read(parent, ri->enable_reg[0], &val1); |
294 | if (ret) | 305 | if (ret) |
295 | return ret; | 306 | return ret; |
@@ -298,14 +309,14 @@ static inline int tps6586x_regulator_preinit(struct device *parent, | |||
298 | if (ret) | 309 | if (ret) |
299 | return ret; | 310 | return ret; |
300 | 311 | ||
301 | if (!(val2 & ri->enable_bit[1])) | 312 | if (!(val2 & (1 << ri->enable_bit[1]))) |
302 | return 0; | 313 | return 0; |
303 | 314 | ||
304 | /* | 315 | /* |
305 | * The regulator is on, but it's enabled with the bit we don't | 316 | * The regulator is on, but it's enabled with the bit we don't |
306 | * want to use, so we switch the enable bits | 317 | * want to use, so we switch the enable bits |
307 | */ | 318 | */ |
308 | if (!(val1 & ri->enable_bit[0])) { | 319 | if (!(val1 & (1 << ri->enable_bit[0]))) { |
309 | ret = tps6586x_set_bits(parent, ri->enable_reg[0], | 320 | ret = tps6586x_set_bits(parent, ri->enable_reg[0], |
310 | 1 << ri->enable_bit[0]); | 321 | 1 << ri->enable_bit[0]); |
311 | if (ret) | 322 | if (ret) |
diff --git a/drivers/rtc/rtc-rs5c372.c b/drivers/rtc/rtc-rs5c372.c index 90cf0a6ff23e..dd14e202c2c8 100644 --- a/drivers/rtc/rtc-rs5c372.c +++ b/drivers/rtc/rtc-rs5c372.c | |||
@@ -207,7 +207,7 @@ static int rs5c372_get_datetime(struct i2c_client *client, struct rtc_time *tm) | |||
207 | static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm) | 207 | static int rs5c372_set_datetime(struct i2c_client *client, struct rtc_time *tm) |
208 | { | 208 | { |
209 | struct rs5c372 *rs5c = i2c_get_clientdata(client); | 209 | struct rs5c372 *rs5c = i2c_get_clientdata(client); |
210 | unsigned char buf[8]; | 210 | unsigned char buf[7]; |
211 | int addr; | 211 | int addr; |
212 | 212 | ||
213 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d " | 213 | dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d " |
diff --git a/drivers/s390/cio/css.c b/drivers/s390/cio/css.c index a5050e217150..825951b6b83f 100644 --- a/drivers/s390/cio/css.c +++ b/drivers/s390/cio/css.c | |||
@@ -635,7 +635,7 @@ static void css_process_crw(struct crw *crw0, struct crw *crw1, int overflow) | |||
635 | init_subchannel_id(&mchk_schid); | 635 | init_subchannel_id(&mchk_schid); |
636 | mchk_schid.sch_no = crw0->rsid; | 636 | mchk_schid.sch_no = crw0->rsid; |
637 | if (crw1) | 637 | if (crw1) |
638 | mchk_schid.ssid = (crw1->rsid >> 8) & 3; | 638 | mchk_schid.ssid = (crw1->rsid >> 4) & 3; |
639 | 639 | ||
640 | /* | 640 | /* |
641 | * Since we are always presented with IPI in the CRW, we have to | 641 | * Since we are always presented with IPI in the CRW, we have to |
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index d37c7331f244..0bcd5806bd9a 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -156,6 +156,8 @@ static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter, | |||
156 | if (!(a_status & ZFCP_STATUS_COMMON_RUNNING) || | 156 | if (!(a_status & ZFCP_STATUS_COMMON_RUNNING) || |
157 | a_status & ZFCP_STATUS_COMMON_ERP_FAILED) | 157 | a_status & ZFCP_STATUS_COMMON_ERP_FAILED) |
158 | return 0; | 158 | return 0; |
159 | if (p_status & ZFCP_STATUS_COMMON_NOESC) | ||
160 | return need; | ||
159 | if (!(a_status & ZFCP_STATUS_COMMON_UNBLOCKED)) | 161 | if (!(a_status & ZFCP_STATUS_COMMON_UNBLOCKED)) |
160 | need = ZFCP_ERP_ACTION_REOPEN_ADAPTER; | 162 | need = ZFCP_ERP_ACTION_REOPEN_ADAPTER; |
161 | /* fall through */ | 163 | /* fall through */ |
@@ -188,6 +190,9 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, | |||
188 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, | 190 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, |
189 | &zfcp_sdev->status); | 191 | &zfcp_sdev->status); |
190 | erp_action = &zfcp_sdev->erp_action; | 192 | erp_action = &zfcp_sdev->erp_action; |
193 | memset(erp_action, 0, sizeof(struct zfcp_erp_action)); | ||
194 | erp_action->port = port; | ||
195 | erp_action->sdev = sdev; | ||
191 | if (!(atomic_read(&zfcp_sdev->status) & | 196 | if (!(atomic_read(&zfcp_sdev->status) & |
192 | ZFCP_STATUS_COMMON_RUNNING)) | 197 | ZFCP_STATUS_COMMON_RUNNING)) |
193 | act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; | 198 | act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; |
@@ -200,6 +205,8 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, | |||
200 | zfcp_erp_action_dismiss_port(port); | 205 | zfcp_erp_action_dismiss_port(port); |
201 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status); | 206 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status); |
202 | erp_action = &port->erp_action; | 207 | erp_action = &port->erp_action; |
208 | memset(erp_action, 0, sizeof(struct zfcp_erp_action)); | ||
209 | erp_action->port = port; | ||
203 | if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING)) | 210 | if (!(atomic_read(&port->status) & ZFCP_STATUS_COMMON_RUNNING)) |
204 | act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; | 211 | act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; |
205 | break; | 212 | break; |
@@ -209,6 +216,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, | |||
209 | zfcp_erp_action_dismiss_adapter(adapter); | 216 | zfcp_erp_action_dismiss_adapter(adapter); |
210 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status); | 217 | atomic_set_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status); |
211 | erp_action = &adapter->erp_action; | 218 | erp_action = &adapter->erp_action; |
219 | memset(erp_action, 0, sizeof(struct zfcp_erp_action)); | ||
212 | if (!(atomic_read(&adapter->status) & | 220 | if (!(atomic_read(&adapter->status) & |
213 | ZFCP_STATUS_COMMON_RUNNING)) | 221 | ZFCP_STATUS_COMMON_RUNNING)) |
214 | act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; | 222 | act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; |
@@ -218,10 +226,7 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, | |||
218 | return NULL; | 226 | return NULL; |
219 | } | 227 | } |
220 | 228 | ||
221 | memset(erp_action, 0, sizeof(struct zfcp_erp_action)); | ||
222 | erp_action->adapter = adapter; | 229 | erp_action->adapter = adapter; |
223 | erp_action->port = port; | ||
224 | erp_action->sdev = sdev; | ||
225 | erp_action->action = need; | 230 | erp_action->action = need; |
226 | erp_action->status = act_status; | 231 | erp_action->status = act_status; |
227 | 232 | ||
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index be0317457147..2eb7dd56ab80 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -851,7 +851,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd *scmnd) | |||
851 | 851 | ||
852 | zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); | 852 | zfcp_qdio_set_sbale_last(qdio, &req->qdio_req); |
853 | 853 | ||
854 | req->data = zfcp_sdev; | 854 | req->data = sdev; |
855 | req->handler = zfcp_fsf_abort_fcp_command_handler; | 855 | req->handler = zfcp_fsf_abort_fcp_command_handler; |
856 | req->qtcb->header.lun_handle = zfcp_sdev->lun_handle; | 856 | req->qtcb->header.lun_handle = zfcp_sdev->lun_handle; |
857 | req->qtcb->header.port_handle = zfcp_sdev->port->handle; | 857 | req->qtcb->header.port_handle = zfcp_sdev->port->handle; |
@@ -2069,8 +2069,6 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req) | |||
2069 | struct fcp_resp_with_ext *fcp_rsp; | 2069 | struct fcp_resp_with_ext *fcp_rsp; |
2070 | unsigned long flags; | 2070 | unsigned long flags; |
2071 | 2071 | ||
2072 | zfcp_fsf_fcp_handler_common(req); | ||
2073 | |||
2074 | read_lock_irqsave(&req->adapter->abort_lock, flags); | 2072 | read_lock_irqsave(&req->adapter->abort_lock, flags); |
2075 | 2073 | ||
2076 | scpnt = req->data; | 2074 | scpnt = req->data; |
@@ -2079,6 +2077,8 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req) | |||
2079 | return; | 2077 | return; |
2080 | } | 2078 | } |
2081 | 2079 | ||
2080 | zfcp_fsf_fcp_handler_common(req); | ||
2081 | |||
2082 | if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) { | 2082 | if (unlikely(req->status & ZFCP_STATUS_FSFREQ_ERROR)) { |
2083 | set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED); | 2083 | set_host_byte(scpnt, DID_TRANSPORT_DISRUPTED); |
2084 | goto skip_fsfstatus; | 2084 | goto skip_fsfstatus; |
@@ -2170,12 +2170,13 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd) | |||
2170 | struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; | 2170 | struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; |
2171 | struct zfcp_qdio *qdio = adapter->qdio; | 2171 | struct zfcp_qdio *qdio = adapter->qdio; |
2172 | struct fsf_qtcb_bottom_io *io; | 2172 | struct fsf_qtcb_bottom_io *io; |
2173 | unsigned long flags; | ||
2173 | 2174 | ||
2174 | if (unlikely(!(atomic_read(&zfcp_sdev->status) & | 2175 | if (unlikely(!(atomic_read(&zfcp_sdev->status) & |
2175 | ZFCP_STATUS_COMMON_UNBLOCKED))) | 2176 | ZFCP_STATUS_COMMON_UNBLOCKED))) |
2176 | return -EBUSY; | 2177 | return -EBUSY; |
2177 | 2178 | ||
2178 | spin_lock(&qdio->req_q_lock); | 2179 | spin_lock_irqsave(&qdio->req_q_lock, flags); |
2179 | if (atomic_read(&qdio->req_q_free) <= 0) { | 2180 | if (atomic_read(&qdio->req_q_free) <= 0) { |
2180 | atomic_inc(&qdio->req_q_full); | 2181 | atomic_inc(&qdio->req_q_full); |
2181 | goto out; | 2182 | goto out; |
@@ -2239,7 +2240,7 @@ failed_scsi_cmnd: | |||
2239 | zfcp_fsf_req_free(req); | 2240 | zfcp_fsf_req_free(req); |
2240 | scsi_cmnd->host_scribble = NULL; | 2241 | scsi_cmnd->host_scribble = NULL; |
2241 | out: | 2242 | out: |
2242 | spin_unlock(&qdio->req_q_lock); | 2243 | spin_unlock_irqrestore(&qdio->req_q_lock, flags); |
2243 | return retval; | 2244 | return retval; |
2244 | } | 2245 | } |
2245 | 2246 | ||
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 6bd2dbc4c316..63529ed801eb 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
@@ -76,8 +76,8 @@ static void zfcp_scsi_command_fail(struct scsi_cmnd *scpnt, int result) | |||
76 | scpnt->scsi_done(scpnt); | 76 | scpnt->scsi_done(scpnt); |
77 | } | 77 | } |
78 | 78 | ||
79 | static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt, | 79 | static |
80 | void (*done) (struct scsi_cmnd *)) | 80 | int zfcp_scsi_queuecommand(struct Scsi_Host *shost, struct scsi_cmnd *scpnt) |
81 | { | 81 | { |
82 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device); | 82 | struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(scpnt->device); |
83 | struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; | 83 | struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; |
@@ -87,7 +87,6 @@ static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt, | |||
87 | /* reset the status for this request */ | 87 | /* reset the status for this request */ |
88 | scpnt->result = 0; | 88 | scpnt->result = 0; |
89 | scpnt->host_scribble = NULL; | 89 | scpnt->host_scribble = NULL; |
90 | scpnt->scsi_done = done; | ||
91 | 90 | ||
92 | scsi_result = fc_remote_port_chkready(rport); | 91 | scsi_result = fc_remote_port_chkready(rport); |
93 | if (unlikely(scsi_result)) { | 92 | if (unlikely(scsi_result)) { |
@@ -127,8 +126,6 @@ static int zfcp_scsi_queuecommand_lck(struct scsi_cmnd *scpnt, | |||
127 | return ret; | 126 | return ret; |
128 | } | 127 | } |
129 | 128 | ||
130 | static DEF_SCSI_QCMD(zfcp_scsi_queuecommand) | ||
131 | |||
132 | static int zfcp_scsi_slave_alloc(struct scsi_device *sdev) | 129 | static int zfcp_scsi_slave_alloc(struct scsi_device *sdev) |
133 | { | 130 | { |
134 | struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); | 131 | struct fc_rport *rport = starget_to_rport(scsi_target(sdev)); |
diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c index c94502dfac66..045d7e87b632 100644 --- a/drivers/scsi/bfa/bfa_fcs.c +++ b/drivers/scsi/bfa/bfa_fcs.c | |||
@@ -677,7 +677,7 @@ bfa_fcs_fabric_sm_isolated(struct bfa_fcs_fabric_s *fabric, | |||
677 | bfa_trc(fabric->fcs, event); | 677 | bfa_trc(fabric->fcs, event); |
678 | wwn2str(pwwn_ptr, fabric->bport.port_cfg.pwwn); | 678 | wwn2str(pwwn_ptr, fabric->bport.port_cfg.pwwn); |
679 | 679 | ||
680 | BFA_LOG(KERN_INFO, bfad, log_level, | 680 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
681 | "Port is isolated due to VF_ID mismatch. " | 681 | "Port is isolated due to VF_ID mismatch. " |
682 | "PWWN: %s Port VF_ID: %04x switch port VF_ID: %04x.", | 682 | "PWWN: %s Port VF_ID: %04x switch port VF_ID: %04x.", |
683 | pwwn_ptr, fabric->fcs->port_vfid, | 683 | pwwn_ptr, fabric->fcs->port_vfid, |
@@ -1411,7 +1411,7 @@ bfa_fcs_fabric_set_fabric_name(struct bfa_fcs_fabric_s *fabric, | |||
1411 | wwn2str(pwwn_ptr, bfa_fcs_lport_get_pwwn(&fabric->bport)); | 1411 | wwn2str(pwwn_ptr, bfa_fcs_lport_get_pwwn(&fabric->bport)); |
1412 | wwn2str(fwwn_ptr, | 1412 | wwn2str(fwwn_ptr, |
1413 | bfa_fcs_lport_get_fabric_name(&fabric->bport)); | 1413 | bfa_fcs_lport_get_fabric_name(&fabric->bport)); |
1414 | BFA_LOG(KERN_WARNING, bfad, log_level, | 1414 | BFA_LOG(KERN_WARNING, bfad, bfa_log_level, |
1415 | "Base port WWN = %s Fabric WWN = %s\n", | 1415 | "Base port WWN = %s Fabric WWN = %s\n", |
1416 | pwwn_ptr, fwwn_ptr); | 1416 | pwwn_ptr, fwwn_ptr); |
1417 | } | 1417 | } |
diff --git a/drivers/scsi/bfa/bfa_fcs_fcpim.c b/drivers/scsi/bfa/bfa_fcs_fcpim.c index 9662bcdeb41d..413b58eef93a 100644 --- a/drivers/scsi/bfa/bfa_fcs_fcpim.c +++ b/drivers/scsi/bfa/bfa_fcs_fcpim.c | |||
@@ -261,7 +261,7 @@ bfa_fcs_itnim_sm_hcb_online(struct bfa_fcs_itnim_s *itnim, | |||
261 | bfa_fcb_itnim_online(itnim->itnim_drv); | 261 | bfa_fcb_itnim_online(itnim->itnim_drv); |
262 | wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(itnim->rport->port)); | 262 | wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(itnim->rport->port)); |
263 | wwn2str(rpwwn_buf, itnim->rport->pwwn); | 263 | wwn2str(rpwwn_buf, itnim->rport->pwwn); |
264 | BFA_LOG(KERN_INFO, bfad, log_level, | 264 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
265 | "Target (WWN = %s) is online for initiator (WWN = %s)\n", | 265 | "Target (WWN = %s) is online for initiator (WWN = %s)\n", |
266 | rpwwn_buf, lpwwn_buf); | 266 | rpwwn_buf, lpwwn_buf); |
267 | break; | 267 | break; |
@@ -301,11 +301,11 @@ bfa_fcs_itnim_sm_online(struct bfa_fcs_itnim_s *itnim, | |||
301 | wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(itnim->rport->port)); | 301 | wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(itnim->rport->port)); |
302 | wwn2str(rpwwn_buf, itnim->rport->pwwn); | 302 | wwn2str(rpwwn_buf, itnim->rport->pwwn); |
303 | if (bfa_fcs_lport_is_online(itnim->rport->port) == BFA_TRUE) | 303 | if (bfa_fcs_lport_is_online(itnim->rport->port) == BFA_TRUE) |
304 | BFA_LOG(KERN_ERR, bfad, log_level, | 304 | BFA_LOG(KERN_ERR, bfad, bfa_log_level, |
305 | "Target (WWN = %s) connectivity lost for " | 305 | "Target (WWN = %s) connectivity lost for " |
306 | "initiator (WWN = %s)\n", rpwwn_buf, lpwwn_buf); | 306 | "initiator (WWN = %s)\n", rpwwn_buf, lpwwn_buf); |
307 | else | 307 | else |
308 | BFA_LOG(KERN_INFO, bfad, log_level, | 308 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
309 | "Target (WWN = %s) offlined by initiator (WWN = %s)\n", | 309 | "Target (WWN = %s) offlined by initiator (WWN = %s)\n", |
310 | rpwwn_buf, lpwwn_buf); | 310 | rpwwn_buf, lpwwn_buf); |
311 | break; | 311 | break; |
diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index 377cbfff6f2e..8d651309302b 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c | |||
@@ -491,7 +491,7 @@ bfa_fcs_lport_online_actions(struct bfa_fcs_lport_s *port) | |||
491 | __port_action[port->fabric->fab_type].online(port); | 491 | __port_action[port->fabric->fab_type].online(port); |
492 | 492 | ||
493 | wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); | 493 | wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); |
494 | BFA_LOG(KERN_INFO, bfad, log_level, | 494 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
495 | "Logical port online: WWN = %s Role = %s\n", | 495 | "Logical port online: WWN = %s Role = %s\n", |
496 | lpwwn_buf, "Initiator"); | 496 | lpwwn_buf, "Initiator"); |
497 | 497 | ||
@@ -512,11 +512,11 @@ bfa_fcs_lport_offline_actions(struct bfa_fcs_lport_s *port) | |||
512 | 512 | ||
513 | wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); | 513 | wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); |
514 | if (bfa_fcs_fabric_is_online(port->fabric) == BFA_TRUE) | 514 | if (bfa_fcs_fabric_is_online(port->fabric) == BFA_TRUE) |
515 | BFA_LOG(KERN_ERR, bfad, log_level, | 515 | BFA_LOG(KERN_ERR, bfad, bfa_log_level, |
516 | "Logical port lost fabric connectivity: WWN = %s Role = %s\n", | 516 | "Logical port lost fabric connectivity: WWN = %s Role = %s\n", |
517 | lpwwn_buf, "Initiator"); | 517 | lpwwn_buf, "Initiator"); |
518 | else | 518 | else |
519 | BFA_LOG(KERN_INFO, bfad, log_level, | 519 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
520 | "Logical port taken offline: WWN = %s Role = %s\n", | 520 | "Logical port taken offline: WWN = %s Role = %s\n", |
521 | lpwwn_buf, "Initiator"); | 521 | lpwwn_buf, "Initiator"); |
522 | 522 | ||
@@ -573,7 +573,7 @@ bfa_fcs_lport_deleted(struct bfa_fcs_lport_s *port) | |||
573 | char lpwwn_buf[BFA_STRING_32]; | 573 | char lpwwn_buf[BFA_STRING_32]; |
574 | 574 | ||
575 | wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); | 575 | wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); |
576 | BFA_LOG(KERN_INFO, bfad, log_level, | 576 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
577 | "Logical port deleted: WWN = %s Role = %s\n", | 577 | "Logical port deleted: WWN = %s Role = %s\n", |
578 | lpwwn_buf, "Initiator"); | 578 | lpwwn_buf, "Initiator"); |
579 | 579 | ||
@@ -878,7 +878,7 @@ bfa_fcs_lport_init(struct bfa_fcs_lport_s *lport, | |||
878 | vport ? vport->vport_drv : NULL); | 878 | vport ? vport->vport_drv : NULL); |
879 | 879 | ||
880 | wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(lport)); | 880 | wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(lport)); |
881 | BFA_LOG(KERN_INFO, bfad, log_level, | 881 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
882 | "New logical port created: WWN = %s Role = %s\n", | 882 | "New logical port created: WWN = %s Role = %s\n", |
883 | lpwwn_buf, "Initiator"); | 883 | lpwwn_buf, "Initiator"); |
884 | 884 | ||
diff --git a/drivers/scsi/bfa/bfa_fcs_rport.c b/drivers/scsi/bfa/bfa_fcs_rport.c index 47f35c0ef29a..cf4a6e73e60d 100644 --- a/drivers/scsi/bfa/bfa_fcs_rport.c +++ b/drivers/scsi/bfa/bfa_fcs_rport.c | |||
@@ -2056,7 +2056,7 @@ bfa_fcs_rport_online_action(struct bfa_fcs_rport_s *rport) | |||
2056 | wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); | 2056 | wwn2str(lpwwn_buf, bfa_fcs_lport_get_pwwn(port)); |
2057 | wwn2str(rpwwn_buf, rport->pwwn); | 2057 | wwn2str(rpwwn_buf, rport->pwwn); |
2058 | if (!BFA_FCS_PID_IS_WKA(rport->pid)) | 2058 | if (!BFA_FCS_PID_IS_WKA(rport->pid)) |
2059 | BFA_LOG(KERN_INFO, bfad, log_level, | 2059 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
2060 | "Remote port (WWN = %s) online for logical port (WWN = %s)\n", | 2060 | "Remote port (WWN = %s) online for logical port (WWN = %s)\n", |
2061 | rpwwn_buf, lpwwn_buf); | 2061 | rpwwn_buf, lpwwn_buf); |
2062 | } | 2062 | } |
@@ -2075,12 +2075,12 @@ bfa_fcs_rport_offline_action(struct bfa_fcs_rport_s *rport) | |||
2075 | wwn2str(rpwwn_buf, rport->pwwn); | 2075 | wwn2str(rpwwn_buf, rport->pwwn); |
2076 | if (!BFA_FCS_PID_IS_WKA(rport->pid)) { | 2076 | if (!BFA_FCS_PID_IS_WKA(rport->pid)) { |
2077 | if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE) | 2077 | if (bfa_fcs_lport_is_online(rport->port) == BFA_TRUE) |
2078 | BFA_LOG(KERN_ERR, bfad, log_level, | 2078 | BFA_LOG(KERN_ERR, bfad, bfa_log_level, |
2079 | "Remote port (WWN = %s) connectivity lost for " | 2079 | "Remote port (WWN = %s) connectivity lost for " |
2080 | "logical port (WWN = %s)\n", | 2080 | "logical port (WWN = %s)\n", |
2081 | rpwwn_buf, lpwwn_buf); | 2081 | rpwwn_buf, lpwwn_buf); |
2082 | else | 2082 | else |
2083 | BFA_LOG(KERN_INFO, bfad, log_level, | 2083 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
2084 | "Remote port (WWN = %s) offlined by " | 2084 | "Remote port (WWN = %s) offlined by " |
2085 | "logical port (WWN = %s)\n", | 2085 | "logical port (WWN = %s)\n", |
2086 | rpwwn_buf, lpwwn_buf); | 2086 | rpwwn_buf, lpwwn_buf); |
diff --git a/drivers/scsi/bfa/bfa_ioc.c b/drivers/scsi/bfa/bfa_ioc.c index 54475b53a5ab..9f4aa391ea9d 100644 --- a/drivers/scsi/bfa/bfa_ioc.c +++ b/drivers/scsi/bfa/bfa_ioc.c | |||
@@ -402,7 +402,7 @@ bfa_ioc_sm_op_entry(struct bfa_ioc_s *ioc) | |||
402 | 402 | ||
403 | ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK); | 403 | ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_OK); |
404 | bfa_ioc_hb_monitor(ioc); | 404 | bfa_ioc_hb_monitor(ioc); |
405 | BFA_LOG(KERN_INFO, bfad, log_level, "IOC enabled\n"); | 405 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC enabled\n"); |
406 | } | 406 | } |
407 | 407 | ||
408 | static void | 408 | static void |
@@ -444,7 +444,7 @@ bfa_ioc_sm_disabling_entry(struct bfa_ioc_s *ioc) | |||
444 | { | 444 | { |
445 | struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad; | 445 | struct bfad_s *bfad = (struct bfad_s *)ioc->bfa->bfad; |
446 | bfa_iocpf_disable(ioc); | 446 | bfa_iocpf_disable(ioc); |
447 | BFA_LOG(KERN_INFO, bfad, log_level, "IOC disabled\n"); | 447 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, "IOC disabled\n"); |
448 | } | 448 | } |
449 | 449 | ||
450 | /* | 450 | /* |
@@ -565,7 +565,7 @@ bfa_ioc_sm_fail_entry(struct bfa_ioc_s *ioc) | |||
565 | notify->cbfn(notify->cbarg); | 565 | notify->cbfn(notify->cbarg); |
566 | } | 566 | } |
567 | 567 | ||
568 | BFA_LOG(KERN_CRIT, bfad, log_level, | 568 | BFA_LOG(KERN_CRIT, bfad, bfa_log_level, |
569 | "Heart Beat of IOC has failed\n"); | 569 | "Heart Beat of IOC has failed\n"); |
570 | } | 570 | } |
571 | 571 | ||
@@ -1812,7 +1812,7 @@ bfa_ioc_pf_fwmismatch(struct bfa_ioc_s *ioc) | |||
1812 | * Provide enable completion callback. | 1812 | * Provide enable completion callback. |
1813 | */ | 1813 | */ |
1814 | ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); | 1814 | ioc->cbfn->enable_cbfn(ioc->bfa, BFA_STATUS_IOC_FAILURE); |
1815 | BFA_LOG(KERN_WARNING, bfad, log_level, | 1815 | BFA_LOG(KERN_WARNING, bfad, bfa_log_level, |
1816 | "Running firmware version is incompatible " | 1816 | "Running firmware version is incompatible " |
1817 | "with the driver version\n"); | 1817 | "with the driver version\n"); |
1818 | } | 1818 | } |
diff --git a/drivers/scsi/bfa/bfa_svc.c b/drivers/scsi/bfa/bfa_svc.c index c768143f4805..37e16ac8f249 100644 --- a/drivers/scsi/bfa/bfa_svc.c +++ b/drivers/scsi/bfa/bfa_svc.c | |||
@@ -2138,7 +2138,7 @@ bfa_fcport_sm_enabling_qwait(struct bfa_fcport_s *fcport, | |||
2138 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, | 2138 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, |
2139 | BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); | 2139 | BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); |
2140 | wwn2str(pwwn_buf, fcport->pwwn); | 2140 | wwn2str(pwwn_buf, fcport->pwwn); |
2141 | BFA_LOG(KERN_INFO, bfad, log_level, | 2141 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
2142 | "Base port disabled: WWN = %s\n", pwwn_buf); | 2142 | "Base port disabled: WWN = %s\n", pwwn_buf); |
2143 | break; | 2143 | break; |
2144 | 2144 | ||
@@ -2198,7 +2198,7 @@ bfa_fcport_sm_enabling(struct bfa_fcport_s *fcport, | |||
2198 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, | 2198 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, |
2199 | BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); | 2199 | BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); |
2200 | wwn2str(pwwn_buf, fcport->pwwn); | 2200 | wwn2str(pwwn_buf, fcport->pwwn); |
2201 | BFA_LOG(KERN_INFO, bfad, log_level, | 2201 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
2202 | "Base port disabled: WWN = %s\n", pwwn_buf); | 2202 | "Base port disabled: WWN = %s\n", pwwn_buf); |
2203 | break; | 2203 | break; |
2204 | 2204 | ||
@@ -2251,7 +2251,7 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport, | |||
2251 | 2251 | ||
2252 | bfa_fcport_scn(fcport, BFA_PORT_LINKUP, BFA_FALSE); | 2252 | bfa_fcport_scn(fcport, BFA_PORT_LINKUP, BFA_FALSE); |
2253 | wwn2str(pwwn_buf, fcport->pwwn); | 2253 | wwn2str(pwwn_buf, fcport->pwwn); |
2254 | BFA_LOG(KERN_INFO, bfad, log_level, | 2254 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
2255 | "Base port online: WWN = %s\n", pwwn_buf); | 2255 | "Base port online: WWN = %s\n", pwwn_buf); |
2256 | break; | 2256 | break; |
2257 | 2257 | ||
@@ -2277,7 +2277,7 @@ bfa_fcport_sm_linkdown(struct bfa_fcport_s *fcport, | |||
2277 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, | 2277 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, |
2278 | BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); | 2278 | BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); |
2279 | wwn2str(pwwn_buf, fcport->pwwn); | 2279 | wwn2str(pwwn_buf, fcport->pwwn); |
2280 | BFA_LOG(KERN_INFO, bfad, log_level, | 2280 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
2281 | "Base port disabled: WWN = %s\n", pwwn_buf); | 2281 | "Base port disabled: WWN = %s\n", pwwn_buf); |
2282 | break; | 2282 | break; |
2283 | 2283 | ||
@@ -2322,9 +2322,9 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport, | |||
2322 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, | 2322 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, |
2323 | BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); | 2323 | BFA_PL_EID_PORT_DISABLE, 0, "Port Disable"); |
2324 | wwn2str(pwwn_buf, fcport->pwwn); | 2324 | wwn2str(pwwn_buf, fcport->pwwn); |
2325 | BFA_LOG(KERN_INFO, bfad, log_level, | 2325 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
2326 | "Base port offline: WWN = %s\n", pwwn_buf); | 2326 | "Base port offline: WWN = %s\n", pwwn_buf); |
2327 | BFA_LOG(KERN_INFO, bfad, log_level, | 2327 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
2328 | "Base port disabled: WWN = %s\n", pwwn_buf); | 2328 | "Base port disabled: WWN = %s\n", pwwn_buf); |
2329 | break; | 2329 | break; |
2330 | 2330 | ||
@@ -2336,10 +2336,10 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport, | |||
2336 | BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown"); | 2336 | BFA_PL_EID_PORT_ST_CHANGE, 0, "Port Linkdown"); |
2337 | wwn2str(pwwn_buf, fcport->pwwn); | 2337 | wwn2str(pwwn_buf, fcport->pwwn); |
2338 | if (BFA_PORT_IS_DISABLED(fcport->bfa)) | 2338 | if (BFA_PORT_IS_DISABLED(fcport->bfa)) |
2339 | BFA_LOG(KERN_INFO, bfad, log_level, | 2339 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
2340 | "Base port offline: WWN = %s\n", pwwn_buf); | 2340 | "Base port offline: WWN = %s\n", pwwn_buf); |
2341 | else | 2341 | else |
2342 | BFA_LOG(KERN_ERR, bfad, log_level, | 2342 | BFA_LOG(KERN_ERR, bfad, bfa_log_level, |
2343 | "Base port (WWN = %s) " | 2343 | "Base port (WWN = %s) " |
2344 | "lost fabric connectivity\n", pwwn_buf); | 2344 | "lost fabric connectivity\n", pwwn_buf); |
2345 | break; | 2345 | break; |
@@ -2349,10 +2349,10 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport, | |||
2349 | bfa_fcport_reset_linkinfo(fcport); | 2349 | bfa_fcport_reset_linkinfo(fcport); |
2350 | wwn2str(pwwn_buf, fcport->pwwn); | 2350 | wwn2str(pwwn_buf, fcport->pwwn); |
2351 | if (BFA_PORT_IS_DISABLED(fcport->bfa)) | 2351 | if (BFA_PORT_IS_DISABLED(fcport->bfa)) |
2352 | BFA_LOG(KERN_INFO, bfad, log_level, | 2352 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
2353 | "Base port offline: WWN = %s\n", pwwn_buf); | 2353 | "Base port offline: WWN = %s\n", pwwn_buf); |
2354 | else | 2354 | else |
2355 | BFA_LOG(KERN_ERR, bfad, log_level, | 2355 | BFA_LOG(KERN_ERR, bfad, bfa_log_level, |
2356 | "Base port (WWN = %s) " | 2356 | "Base port (WWN = %s) " |
2357 | "lost fabric connectivity\n", pwwn_buf); | 2357 | "lost fabric connectivity\n", pwwn_buf); |
2358 | break; | 2358 | break; |
@@ -2363,10 +2363,10 @@ bfa_fcport_sm_linkup(struct bfa_fcport_s *fcport, | |||
2363 | bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE); | 2363 | bfa_fcport_scn(fcport, BFA_PORT_LINKDOWN, BFA_FALSE); |
2364 | wwn2str(pwwn_buf, fcport->pwwn); | 2364 | wwn2str(pwwn_buf, fcport->pwwn); |
2365 | if (BFA_PORT_IS_DISABLED(fcport->bfa)) | 2365 | if (BFA_PORT_IS_DISABLED(fcport->bfa)) |
2366 | BFA_LOG(KERN_INFO, bfad, log_level, | 2366 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
2367 | "Base port offline: WWN = %s\n", pwwn_buf); | 2367 | "Base port offline: WWN = %s\n", pwwn_buf); |
2368 | else | 2368 | else |
2369 | BFA_LOG(KERN_ERR, bfad, log_level, | 2369 | BFA_LOG(KERN_ERR, bfad, bfa_log_level, |
2370 | "Base port (WWN = %s) " | 2370 | "Base port (WWN = %s) " |
2371 | "lost fabric connectivity\n", pwwn_buf); | 2371 | "lost fabric connectivity\n", pwwn_buf); |
2372 | break; | 2372 | break; |
@@ -2497,7 +2497,7 @@ bfa_fcport_sm_disabling(struct bfa_fcport_s *fcport, | |||
2497 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, | 2497 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, |
2498 | BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); | 2498 | BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); |
2499 | wwn2str(pwwn_buf, fcport->pwwn); | 2499 | wwn2str(pwwn_buf, fcport->pwwn); |
2500 | BFA_LOG(KERN_INFO, bfad, log_level, | 2500 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
2501 | "Base port enabled: WWN = %s\n", pwwn_buf); | 2501 | "Base port enabled: WWN = %s\n", pwwn_buf); |
2502 | break; | 2502 | break; |
2503 | 2503 | ||
@@ -2551,7 +2551,7 @@ bfa_fcport_sm_disabled(struct bfa_fcport_s *fcport, | |||
2551 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, | 2551 | bfa_plog_str(fcport->bfa->plog, BFA_PL_MID_HAL, |
2552 | BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); | 2552 | BFA_PL_EID_PORT_ENABLE, 0, "Port Enable"); |
2553 | wwn2str(pwwn_buf, fcport->pwwn); | 2553 | wwn2str(pwwn_buf, fcport->pwwn); |
2554 | BFA_LOG(KERN_INFO, bfad, log_level, | 2554 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
2555 | "Base port enabled: WWN = %s\n", pwwn_buf); | 2555 | "Base port enabled: WWN = %s\n", pwwn_buf); |
2556 | break; | 2556 | break; |
2557 | 2557 | ||
diff --git a/drivers/scsi/bfa/bfad.c b/drivers/scsi/bfa/bfad.c index 1f938974b848..6797720213b2 100644 --- a/drivers/scsi/bfa/bfad.c +++ b/drivers/scsi/bfa/bfad.c | |||
@@ -50,7 +50,7 @@ int reqq_size, rspq_size, num_sgpgs; | |||
50 | int rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT; | 50 | int rport_del_timeout = BFA_FCS_RPORT_DEF_DEL_TIMEOUT; |
51 | int bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH; | 51 | int bfa_lun_queue_depth = BFAD_LUN_QUEUE_DEPTH; |
52 | int bfa_io_max_sge = BFAD_IO_MAX_SGE; | 52 | int bfa_io_max_sge = BFAD_IO_MAX_SGE; |
53 | int log_level = 3; /* WARNING log level */ | 53 | int bfa_log_level = 3; /* WARNING log level */ |
54 | int ioc_auto_recover = BFA_TRUE; | 54 | int ioc_auto_recover = BFA_TRUE; |
55 | int bfa_linkup_delay = -1; | 55 | int bfa_linkup_delay = -1; |
56 | int fdmi_enable = BFA_TRUE; | 56 | int fdmi_enable = BFA_TRUE; |
@@ -108,8 +108,8 @@ module_param(bfa_lun_queue_depth, int, S_IRUGO | S_IWUSR); | |||
108 | MODULE_PARM_DESC(bfa_lun_queue_depth, "Lun queue depth, default=32, Range[>0]"); | 108 | MODULE_PARM_DESC(bfa_lun_queue_depth, "Lun queue depth, default=32, Range[>0]"); |
109 | module_param(bfa_io_max_sge, int, S_IRUGO | S_IWUSR); | 109 | module_param(bfa_io_max_sge, int, S_IRUGO | S_IWUSR); |
110 | MODULE_PARM_DESC(bfa_io_max_sge, "Max io scatter/gather elements, default=255"); | 110 | MODULE_PARM_DESC(bfa_io_max_sge, "Max io scatter/gather elements, default=255"); |
111 | module_param(log_level, int, S_IRUGO | S_IWUSR); | 111 | module_param(bfa_log_level, int, S_IRUGO | S_IWUSR); |
112 | MODULE_PARM_DESC(log_level, "Driver log level, default=3, " | 112 | MODULE_PARM_DESC(bfa_log_level, "Driver log level, default=3, " |
113 | "Range[Critical:1|Error:2|Warning:3|Info:4]"); | 113 | "Range[Critical:1|Error:2|Warning:3|Info:4]"); |
114 | module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR); | 114 | module_param(ioc_auto_recover, int, S_IRUGO | S_IWUSR); |
115 | MODULE_PARM_DESC(ioc_auto_recover, "IOC auto recovery, default=1, " | 115 | MODULE_PARM_DESC(ioc_auto_recover, "IOC auto recovery, default=1, " |
@@ -1112,7 +1112,7 @@ bfad_start_ops(struct bfad_s *bfad) { | |||
1112 | } else | 1112 | } else |
1113 | bfad_os_rport_online_wait(bfad); | 1113 | bfad_os_rport_online_wait(bfad); |
1114 | 1114 | ||
1115 | BFA_LOG(KERN_INFO, bfad, log_level, "bfa device claimed\n"); | 1115 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, "bfa device claimed\n"); |
1116 | 1116 | ||
1117 | return BFA_STATUS_OK; | 1117 | return BFA_STATUS_OK; |
1118 | } | 1118 | } |
diff --git a/drivers/scsi/bfa/bfad_drv.h b/drivers/scsi/bfa/bfad_drv.h index 97f9b6c0937e..d5ce2349ac59 100644 --- a/drivers/scsi/bfa/bfad_drv.h +++ b/drivers/scsi/bfa/bfad_drv.h | |||
@@ -337,7 +337,7 @@ extern int num_sgpgs; | |||
337 | extern int rport_del_timeout; | 337 | extern int rport_del_timeout; |
338 | extern int bfa_lun_queue_depth; | 338 | extern int bfa_lun_queue_depth; |
339 | extern int bfa_io_max_sge; | 339 | extern int bfa_io_max_sge; |
340 | extern int log_level; | 340 | extern int bfa_log_level; |
341 | extern int ioc_auto_recover; | 341 | extern int ioc_auto_recover; |
342 | extern int bfa_linkup_delay; | 342 | extern int bfa_linkup_delay; |
343 | extern int msix_disable_cb; | 343 | extern int msix_disable_cb; |
diff --git a/drivers/scsi/bfa/bfad_im.c b/drivers/scsi/bfa/bfad_im.c index 8ca967dee66d..fbad5e9b2402 100644 --- a/drivers/scsi/bfa/bfad_im.c +++ b/drivers/scsi/bfa/bfad_im.c | |||
@@ -225,7 +225,8 @@ bfad_im_abort_handler(struct scsi_cmnd *cmnd) | |||
225 | } | 225 | } |
226 | 226 | ||
227 | bfa_trc(bfad, hal_io->iotag); | 227 | bfa_trc(bfad, hal_io->iotag); |
228 | BFA_LOG(KERN_INFO, bfad, log_level, "scsi%d: abort cmnd %p iotag %x\n", | 228 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
229 | "scsi%d: abort cmnd %p iotag %x\n", | ||
229 | im_port->shost->host_no, cmnd, hal_io->iotag); | 230 | im_port->shost->host_no, cmnd, hal_io->iotag); |
230 | (void) bfa_ioim_abort(hal_io); | 231 | (void) bfa_ioim_abort(hal_io); |
231 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 232 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
@@ -241,7 +242,7 @@ bfad_im_abort_handler(struct scsi_cmnd *cmnd) | |||
241 | 242 | ||
242 | cmnd->scsi_done(cmnd); | 243 | cmnd->scsi_done(cmnd); |
243 | bfa_trc(bfad, hal_io->iotag); | 244 | bfa_trc(bfad, hal_io->iotag); |
244 | BFA_LOG(KERN_INFO, bfad, log_level, | 245 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
245 | "scsi%d: complete abort 0x%p iotag 0x%x\n", | 246 | "scsi%d: complete abort 0x%p iotag 0x%x\n", |
246 | im_port->shost->host_no, cmnd, hal_io->iotag); | 247 | im_port->shost->host_no, cmnd, hal_io->iotag); |
247 | return SUCCESS; | 248 | return SUCCESS; |
@@ -260,7 +261,7 @@ bfad_im_target_reset_send(struct bfad_s *bfad, struct scsi_cmnd *cmnd, | |||
260 | 261 | ||
261 | tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd); | 262 | tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd); |
262 | if (!tskim) { | 263 | if (!tskim) { |
263 | BFA_LOG(KERN_ERR, bfad, log_level, | 264 | BFA_LOG(KERN_ERR, bfad, bfa_log_level, |
264 | "target reset, fail to allocate tskim\n"); | 265 | "target reset, fail to allocate tskim\n"); |
265 | rc = BFA_STATUS_FAILED; | 266 | rc = BFA_STATUS_FAILED; |
266 | goto out; | 267 | goto out; |
@@ -311,7 +312,7 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
311 | 312 | ||
312 | tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd); | 313 | tskim = bfa_tskim_alloc(&bfad->bfa, (struct bfad_tskim_s *) cmnd); |
313 | if (!tskim) { | 314 | if (!tskim) { |
314 | BFA_LOG(KERN_ERR, bfad, log_level, | 315 | BFA_LOG(KERN_ERR, bfad, bfa_log_level, |
315 | "LUN reset, fail to allocate tskim"); | 316 | "LUN reset, fail to allocate tskim"); |
316 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); | 317 | spin_unlock_irqrestore(&bfad->bfad_lock, flags); |
317 | rc = FAILED; | 318 | rc = FAILED; |
@@ -336,7 +337,7 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd) | |||
336 | 337 | ||
337 | task_status = cmnd->SCp.Status >> 1; | 338 | task_status = cmnd->SCp.Status >> 1; |
338 | if (task_status != BFI_TSKIM_STS_OK) { | 339 | if (task_status != BFI_TSKIM_STS_OK) { |
339 | BFA_LOG(KERN_ERR, bfad, log_level, | 340 | BFA_LOG(KERN_ERR, bfad, bfa_log_level, |
340 | "LUN reset failure, status: %d\n", task_status); | 341 | "LUN reset failure, status: %d\n", task_status); |
341 | rc = FAILED; | 342 | rc = FAILED; |
342 | } | 343 | } |
@@ -380,7 +381,7 @@ bfad_im_reset_bus_handler(struct scsi_cmnd *cmnd) | |||
380 | 381 | ||
381 | task_status = cmnd->SCp.Status >> 1; | 382 | task_status = cmnd->SCp.Status >> 1; |
382 | if (task_status != BFI_TSKIM_STS_OK) { | 383 | if (task_status != BFI_TSKIM_STS_OK) { |
383 | BFA_LOG(KERN_ERR, bfad, log_level, | 384 | BFA_LOG(KERN_ERR, bfad, bfa_log_level, |
384 | "target reset failure," | 385 | "target reset failure," |
385 | " status: %d\n", task_status); | 386 | " status: %d\n", task_status); |
386 | err_cnt++; | 387 | err_cnt++; |
@@ -460,7 +461,7 @@ bfa_fcb_itnim_free(struct bfad_s *bfad, struct bfad_itnim_s *itnim_drv) | |||
460 | fcid = bfa_fcs_itnim_get_fcid(&itnim_drv->fcs_itnim); | 461 | fcid = bfa_fcs_itnim_get_fcid(&itnim_drv->fcs_itnim); |
461 | wwn2str(wwpn_str, wwpn); | 462 | wwn2str(wwpn_str, wwpn); |
462 | fcid2str(fcid_str, fcid); | 463 | fcid2str(fcid_str, fcid); |
463 | BFA_LOG(KERN_INFO, bfad, log_level, | 464 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
464 | "ITNIM FREE scsi%d: FCID: %s WWPN: %s\n", | 465 | "ITNIM FREE scsi%d: FCID: %s WWPN: %s\n", |
465 | port->im_port->shost->host_no, | 466 | port->im_port->shost->host_no, |
466 | fcid_str, wwpn_str); | 467 | fcid_str, wwpn_str); |
@@ -589,7 +590,7 @@ void | |||
589 | bfad_im_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port) | 590 | bfad_im_scsi_host_free(struct bfad_s *bfad, struct bfad_im_port_s *im_port) |
590 | { | 591 | { |
591 | bfa_trc(bfad, bfad->inst_no); | 592 | bfa_trc(bfad, bfad->inst_no); |
592 | BFA_LOG(KERN_INFO, bfad, log_level, "Free scsi%d\n", | 593 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, "Free scsi%d\n", |
593 | im_port->shost->host_no); | 594 | im_port->shost->host_no); |
594 | 595 | ||
595 | fc_remove_host(im_port->shost); | 596 | fc_remove_host(im_port->shost); |
@@ -1048,7 +1049,7 @@ bfad_im_itnim_work_handler(struct work_struct *work) | |||
1048 | fcid2str(fcid_str, fcid); | 1049 | fcid2str(fcid_str, fcid); |
1049 | list_add_tail(&itnim->list_entry, | 1050 | list_add_tail(&itnim->list_entry, |
1050 | &im_port->itnim_mapped_list); | 1051 | &im_port->itnim_mapped_list); |
1051 | BFA_LOG(KERN_INFO, bfad, log_level, | 1052 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
1052 | "ITNIM ONLINE Target: %d:0:%d " | 1053 | "ITNIM ONLINE Target: %d:0:%d " |
1053 | "FCID: %s WWPN: %s\n", | 1054 | "FCID: %s WWPN: %s\n", |
1054 | im_port->shost->host_no, | 1055 | im_port->shost->host_no, |
@@ -1081,7 +1082,7 @@ bfad_im_itnim_work_handler(struct work_struct *work) | |||
1081 | wwn2str(wwpn_str, wwpn); | 1082 | wwn2str(wwpn_str, wwpn); |
1082 | fcid2str(fcid_str, fcid); | 1083 | fcid2str(fcid_str, fcid); |
1083 | list_del(&itnim->list_entry); | 1084 | list_del(&itnim->list_entry); |
1084 | BFA_LOG(KERN_INFO, bfad, log_level, | 1085 | BFA_LOG(KERN_INFO, bfad, bfa_log_level, |
1085 | "ITNIM OFFLINE Target: %d:0:%d " | 1086 | "ITNIM OFFLINE Target: %d:0:%d " |
1086 | "FCID: %s WWPN: %s\n", | 1087 | "FCID: %s WWPN: %s\n", |
1087 | im_port->shost->host_no, | 1088 | im_port->shost->host_no, |
diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index b2fb2b2a6e70..a6dea08664fc 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c | |||
@@ -90,11 +90,7 @@ static const struct pci_device_id hpsa_pci_device_id[] = { | |||
90 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3252}, | 90 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3252}, |
91 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3253}, | 91 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3253}, |
92 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3254}, | 92 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSE, 0x103C, 0x3254}, |
93 | #define PCI_DEVICE_ID_HP_CISSF 0x333f | 93 | {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, |
94 | {PCI_VENDOR_ID_HP, PCI_DEVICE_ID_HP_CISSF, 0x103C, 0x333F}, | ||
95 | {PCI_VENDOR_ID_HP, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | ||
96 | PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, | ||
97 | {PCI_VENDOR_ID_COMPAQ, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, | ||
98 | PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, | 94 | PCI_CLASS_STORAGE_RAID << 8, 0xffff << 8, 0}, |
99 | {0,} | 95 | {0,} |
100 | }; | 96 | }; |
@@ -113,8 +109,6 @@ static struct board_type products[] = { | |||
113 | {0x3249103C, "Smart Array P812", &SA5_access}, | 109 | {0x3249103C, "Smart Array P812", &SA5_access}, |
114 | {0x324a103C, "Smart Array P712m", &SA5_access}, | 110 | {0x324a103C, "Smart Array P712m", &SA5_access}, |
115 | {0x324b103C, "Smart Array P711m", &SA5_access}, | 111 | {0x324b103C, "Smart Array P711m", &SA5_access}, |
116 | {0x3233103C, "StorageWorks P1210m", &SA5_access}, | ||
117 | {0x333F103C, "StorageWorks P1210m", &SA5_access}, | ||
118 | {0x3250103C, "Smart Array", &SA5_access}, | 112 | {0x3250103C, "Smart Array", &SA5_access}, |
119 | {0x3250113C, "Smart Array", &SA5_access}, | 113 | {0x3250113C, "Smart Array", &SA5_access}, |
120 | {0x3250123C, "Smart Array", &SA5_access}, | 114 | {0x3250123C, "Smart Array", &SA5_access}, |
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c index 0433ea6f27c9..b37c8a3c1bb0 100644 --- a/drivers/scsi/osd/osd_initiator.c +++ b/drivers/scsi/osd/osd_initiator.c | |||
@@ -951,8 +951,8 @@ static int _osd_req_finalize_cdb_cont(struct osd_request *or, const u8 *cap_key) | |||
951 | /* create a bio for continuation segment */ | 951 | /* create a bio for continuation segment */ |
952 | bio = bio_map_kern(req_q, or->cdb_cont.buff, or->cdb_cont.total_bytes, | 952 | bio = bio_map_kern(req_q, or->cdb_cont.buff, or->cdb_cont.total_bytes, |
953 | GFP_KERNEL); | 953 | GFP_KERNEL); |
954 | if (unlikely(!bio)) | 954 | if (IS_ERR(bio)) |
955 | return -ENOMEM; | 955 | return PTR_ERR(bio); |
956 | 956 | ||
957 | bio->bi_rw |= REQ_WRITE; | 957 | bio->bi_rw |= REQ_WRITE; |
958 | 958 | ||
diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 5e76a624cb08..300d59f389da 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c | |||
@@ -62,6 +62,7 @@ | |||
62 | static unsigned int pmcraid_debug_log; | 62 | static unsigned int pmcraid_debug_log; |
63 | static unsigned int pmcraid_disable_aen; | 63 | static unsigned int pmcraid_disable_aen; |
64 | static unsigned int pmcraid_log_level = IOASC_LOG_LEVEL_MUST; | 64 | static unsigned int pmcraid_log_level = IOASC_LOG_LEVEL_MUST; |
65 | static unsigned int pmcraid_enable_msix; | ||
65 | 66 | ||
66 | /* | 67 | /* |
67 | * Data structures to support multiple adapters by the LLD. | 68 | * Data structures to support multiple adapters by the LLD. |
@@ -4691,7 +4692,8 @@ pmcraid_register_interrupt_handler(struct pmcraid_instance *pinstance) | |||
4691 | int rc; | 4692 | int rc; |
4692 | struct pci_dev *pdev = pinstance->pdev; | 4693 | struct pci_dev *pdev = pinstance->pdev; |
4693 | 4694 | ||
4694 | if (pci_find_capability(pdev, PCI_CAP_ID_MSIX)) { | 4695 | if ((pmcraid_enable_msix) && |
4696 | (pci_find_capability(pdev, PCI_CAP_ID_MSIX))) { | ||
4695 | int num_hrrq = PMCRAID_NUM_MSIX_VECTORS; | 4697 | int num_hrrq = PMCRAID_NUM_MSIX_VECTORS; |
4696 | struct msix_entry entries[PMCRAID_NUM_MSIX_VECTORS]; | 4698 | struct msix_entry entries[PMCRAID_NUM_MSIX_VECTORS]; |
4697 | int i; | 4699 | int i; |
diff --git a/drivers/scsi/pmcraid.h b/drivers/scsi/pmcraid.h index 1134279604e8..4db210d93947 100644 --- a/drivers/scsi/pmcraid.h +++ b/drivers/scsi/pmcraid.h | |||
@@ -42,7 +42,7 @@ | |||
42 | */ | 42 | */ |
43 | #define PMCRAID_DRIVER_NAME "PMC MaxRAID" | 43 | #define PMCRAID_DRIVER_NAME "PMC MaxRAID" |
44 | #define PMCRAID_DEVFILE "pmcsas" | 44 | #define PMCRAID_DEVFILE "pmcsas" |
45 | #define PMCRAID_DRIVER_VERSION "2.0.3" | 45 | #define PMCRAID_DRIVER_VERSION "1.0.3" |
46 | #define PMCRAID_DRIVER_DATE __DATE__ | 46 | #define PMCRAID_DRIVER_DATE __DATE__ |
47 | 47 | ||
48 | #define PMCRAID_FW_VERSION_1 0x002 | 48 | #define PMCRAID_FW_VERSION_1 0x002 |
@@ -333,11 +333,9 @@ struct pmcraid_config_table_entry { | |||
333 | __u8 lun[PMCRAID_LUN_LEN]; | 333 | __u8 lun[PMCRAID_LUN_LEN]; |
334 | } __attribute__((packed, aligned(4))); | 334 | } __attribute__((packed, aligned(4))); |
335 | 335 | ||
336 | /* extended configuration table sizes are of 64 bytes in size */ | 336 | /* extended configuration table sizes are also of 32 bytes in size */ |
337 | #define PMCRAID_CFGTE_EXT_SIZE 32 | ||
338 | struct pmcraid_config_table_entry_ext { | 337 | struct pmcraid_config_table_entry_ext { |
339 | struct pmcraid_config_table_entry cfgte; | 338 | struct pmcraid_config_table_entry cfgte; |
340 | __u8 cfgte_ext[PMCRAID_CFGTE_EXT_SIZE]; | ||
341 | }; | 339 | }; |
342 | 340 | ||
343 | /* resource types (config_table_entry.resource_type values) */ | 341 | /* resource types (config_table_entry.resource_type values) */ |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 3a22effced5f..9ce539d4557e 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -2409,7 +2409,6 @@ struct qla_hw_data { | |||
2409 | uint32_t enable_target_reset :1; | 2409 | uint32_t enable_target_reset :1; |
2410 | uint32_t enable_lip_full_login :1; | 2410 | uint32_t enable_lip_full_login :1; |
2411 | uint32_t enable_led_scheme :1; | 2411 | uint32_t enable_led_scheme :1; |
2412 | uint32_t inta_enabled :1; | ||
2413 | uint32_t msi_enabled :1; | 2412 | uint32_t msi_enabled :1; |
2414 | uint32_t msix_enabled :1; | 2413 | uint32_t msix_enabled :1; |
2415 | uint32_t disable_serdes :1; | 2414 | uint32_t disable_serdes :1; |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 5f94430b42f0..4c1ba6263eb3 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -1061,6 +1061,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt, | |||
1061 | fcp_cmnd->additional_cdb_len |= 2; | 1061 | fcp_cmnd->additional_cdb_len |= 2; |
1062 | 1062 | ||
1063 | int_to_scsilun(sp->cmd->device->lun, &fcp_cmnd->lun); | 1063 | int_to_scsilun(sp->cmd->device->lun, &fcp_cmnd->lun); |
1064 | host_to_fcp_swap((uint8_t *)&fcp_cmnd->lun, sizeof(fcp_cmnd->lun)); | ||
1064 | memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len); | 1065 | memcpy(fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len); |
1065 | cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len); | 1066 | cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(fcp_cmnd_len); |
1066 | cmd_pkt->fcp_cmnd_dseg_address[0] = cpu_to_le32( | 1067 | cmd_pkt->fcp_cmnd_dseg_address[0] = cpu_to_le32( |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 1f06ddd9bdd1..7f77898486a9 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -2491,14 +2491,15 @@ skip_msix: | |||
2491 | skip_msi: | 2491 | skip_msi: |
2492 | 2492 | ||
2493 | ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler, | 2493 | ret = request_irq(ha->pdev->irq, ha->isp_ops->intr_handler, |
2494 | IRQF_SHARED, QLA2XXX_DRIVER_NAME, rsp); | 2494 | ha->flags.msi_enabled ? 0 : IRQF_SHARED, |
2495 | QLA2XXX_DRIVER_NAME, rsp); | ||
2495 | if (ret) { | 2496 | if (ret) { |
2496 | qla_printk(KERN_WARNING, ha, | 2497 | qla_printk(KERN_WARNING, ha, |
2497 | "Failed to reserve interrupt %d already in use.\n", | 2498 | "Failed to reserve interrupt %d already in use.\n", |
2498 | ha->pdev->irq); | 2499 | ha->pdev->irq); |
2499 | goto fail; | 2500 | goto fail; |
2500 | } | 2501 | } |
2501 | ha->flags.inta_enabled = 1; | 2502 | |
2502 | clear_risc_ints: | 2503 | clear_risc_ints: |
2503 | 2504 | ||
2504 | /* | 2505 | /* |
diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 8d9edfb39803..ae2acacc0003 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c | |||
@@ -2749,6 +2749,7 @@ sufficient_dsds: | |||
2749 | goto queuing_error_fcp_cmnd; | 2749 | goto queuing_error_fcp_cmnd; |
2750 | 2750 | ||
2751 | int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); | 2751 | int_to_scsilun(sp->cmd->device->lun, &cmd_pkt->lun); |
2752 | host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun)); | ||
2752 | 2753 | ||
2753 | /* build FCP_CMND IU */ | 2754 | /* build FCP_CMND IU */ |
2754 | memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd)); | 2755 | memset(ctx->fcp_cmnd, 0, sizeof(struct fcp_cmnd)); |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 1644eabaafeb..2c0876c81a3f 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -829,7 +829,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd) | |||
829 | { | 829 | { |
830 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); | 830 | scsi_qla_host_t *vha = shost_priv(cmd->device->host); |
831 | srb_t *sp; | 831 | srb_t *sp; |
832 | int ret; | 832 | int ret = SUCCESS; |
833 | unsigned int id, lun; | 833 | unsigned int id, lun; |
834 | unsigned long flags; | 834 | unsigned long flags; |
835 | int wait = 0; | 835 | int wait = 0; |
@@ -2064,6 +2064,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
2064 | ha->init_cb_size = sizeof(struct mid_init_cb_81xx); | 2064 | ha->init_cb_size = sizeof(struct mid_init_cb_81xx); |
2065 | ha->gid_list_info_size = 8; | 2065 | ha->gid_list_info_size = 8; |
2066 | ha->optrom_size = OPTROM_SIZE_82XX; | 2066 | ha->optrom_size = OPTROM_SIZE_82XX; |
2067 | ha->nvram_npiv_size = QLA_MAX_VPORTS_QLA25XX; | ||
2067 | ha->isp_ops = &qla82xx_isp_ops; | 2068 | ha->isp_ops = &qla82xx_isp_ops; |
2068 | ha->flash_conf_off = FARX_ACCESS_FLASH_CONF; | 2069 | ha->flash_conf_off = FARX_ACCESS_FLASH_CONF; |
2069 | ha->flash_data_off = FARX_ACCESS_FLASH_DATA; | 2070 | ha->flash_data_off = FARX_ACCESS_FLASH_DATA; |
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 8edbccb3232d..cf0075a2d0c2 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -7,9 +7,9 @@ | |||
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.03.04-k0" | 10 | #define QLA2XXX_VERSION "8.03.05-k0" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 3 | 13 | #define QLA_DRIVER_MINOR_VER 3 |
14 | #define QLA_DRIVER_PATCH_VER 4 | 14 | #define QLA_DRIVER_PATCH_VER 5 |
15 | #define QLA_DRIVER_BETA_VER 0 | 15 | #define QLA_DRIVER_BETA_VER 0 |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 824b8fc03ce5..30ac116186f5 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -615,7 +615,7 @@ static int scsi_try_bus_device_reset(struct scsi_cmnd *scmd) | |||
615 | return rtn; | 615 | return rtn; |
616 | } | 616 | } |
617 | 617 | ||
618 | static int __scsi_try_to_abort_cmd(struct scsi_cmnd *scmd) | 618 | static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd) |
619 | { | 619 | { |
620 | if (!scmd->device->host->hostt->eh_abort_handler) | 620 | if (!scmd->device->host->hostt->eh_abort_handler) |
621 | return FAILED; | 621 | return FAILED; |
@@ -623,31 +623,9 @@ static int __scsi_try_to_abort_cmd(struct scsi_cmnd *scmd) | |||
623 | return scmd->device->host->hostt->eh_abort_handler(scmd); | 623 | return scmd->device->host->hostt->eh_abort_handler(scmd); |
624 | } | 624 | } |
625 | 625 | ||
626 | /** | ||
627 | * scsi_try_to_abort_cmd - Ask host to abort a running command. | ||
628 | * @scmd: SCSI cmd to abort from Lower Level. | ||
629 | * | ||
630 | * Notes: | ||
631 | * This function will not return until the user's completion function | ||
632 | * has been called. there is no timeout on this operation. if the | ||
633 | * author of the low-level driver wishes this operation to be timed, | ||
634 | * they can provide this facility themselves. helper functions in | ||
635 | * scsi_error.c can be supplied to make this easier to do. | ||
636 | */ | ||
637 | static int scsi_try_to_abort_cmd(struct scsi_cmnd *scmd) | ||
638 | { | ||
639 | /* | ||
640 | * scsi_done was called just after the command timed out and before | ||
641 | * we had a chance to process it. (db) | ||
642 | */ | ||
643 | if (scmd->serial_number == 0) | ||
644 | return SUCCESS; | ||
645 | return __scsi_try_to_abort_cmd(scmd); | ||
646 | } | ||
647 | |||
648 | static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd) | 626 | static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd) |
649 | { | 627 | { |
650 | if (__scsi_try_to_abort_cmd(scmd) != SUCCESS) | 628 | if (scsi_try_to_abort_cmd(scmd) != SUCCESS) |
651 | if (scsi_try_bus_device_reset(scmd) != SUCCESS) | 629 | if (scsi_try_bus_device_reset(scmd) != SUCCESS) |
652 | if (scsi_try_target_reset(scmd) != SUCCESS) | 630 | if (scsi_try_target_reset(scmd) != SUCCESS) |
653 | if (scsi_try_bus_reset(scmd) != SUCCESS) | 631 | if (scsi_try_bus_reset(scmd) != SUCCESS) |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index eafeeda6e194..4a3842212c50 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -1403,11 +1403,6 @@ static void scsi_softirq_done(struct request *rq) | |||
1403 | 1403 | ||
1404 | INIT_LIST_HEAD(&cmd->eh_entry); | 1404 | INIT_LIST_HEAD(&cmd->eh_entry); |
1405 | 1405 | ||
1406 | /* | ||
1407 | * Set the serial numbers back to zero | ||
1408 | */ | ||
1409 | cmd->serial_number = 0; | ||
1410 | |||
1411 | atomic_inc(&cmd->device->iodone_cnt); | 1406 | atomic_inc(&cmd->device->iodone_cnt); |
1412 | if (cmd->result) | 1407 | if (cmd->result) |
1413 | atomic_inc(&cmd->device->ioerr_cnt); | 1408 | atomic_inc(&cmd->device->ioerr_cnt); |
@@ -1642,9 +1637,8 @@ struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost, | |||
1642 | 1637 | ||
1643 | blk_queue_max_segment_size(q, dma_get_max_seg_size(dev)); | 1638 | blk_queue_max_segment_size(q, dma_get_max_seg_size(dev)); |
1644 | 1639 | ||
1645 | /* New queue, no concurrency on queue_flags */ | ||
1646 | if (!shost->use_clustering) | 1640 | if (!shost->use_clustering) |
1647 | queue_flag_clear_unlocked(QUEUE_FLAG_CLUSTER, q); | 1641 | q->limits.cluster = 0; |
1648 | 1642 | ||
1649 | /* | 1643 | /* |
1650 | * set a reasonable default alignment on word boundaries: the | 1644 | * set a reasonable default alignment on word boundaries: the |
diff --git a/drivers/serial/kgdboc.c b/drivers/serial/kgdboc.c index 3374618300af..25a8bc565f40 100644 --- a/drivers/serial/kgdboc.c +++ b/drivers/serial/kgdboc.c | |||
@@ -90,7 +90,8 @@ static DECLARE_WORK(kgdboc_restore_input_work, kgdboc_restore_input_helper); | |||
90 | 90 | ||
91 | static void kgdboc_restore_input(void) | 91 | static void kgdboc_restore_input(void) |
92 | { | 92 | { |
93 | schedule_work(&kgdboc_restore_input_work); | 93 | if (likely(system_state == SYSTEM_RUNNING)) |
94 | schedule_work(&kgdboc_restore_input_work); | ||
94 | } | 95 | } |
95 | 96 | ||
96 | static int kgdboc_register_kbd(char **cptr) | 97 | static int kgdboc_register_kbd(char **cptr) |
diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c index e5e9e6735f7d..9739431092d1 100644 --- a/drivers/sh/intc/core.c +++ b/drivers/sh/intc/core.c | |||
@@ -198,6 +198,7 @@ int __init register_intc_controller(struct intc_desc *desc) | |||
198 | list_add_tail(&d->list, &intc_list); | 198 | list_add_tail(&d->list, &intc_list); |
199 | 199 | ||
200 | raw_spin_lock_init(&d->lock); | 200 | raw_spin_lock_init(&d->lock); |
201 | INIT_RADIX_TREE(&d->tree, GFP_ATOMIC); | ||
201 | 202 | ||
202 | d->index = nr_intc_controllers; | 203 | d->index = nr_intc_controllers; |
203 | 204 | ||
diff --git a/drivers/spi/coldfire_qspi.c b/drivers/spi/coldfire_qspi.c index 052b3c7fa6a0..8856bcca9d29 100644 --- a/drivers/spi/coldfire_qspi.c +++ b/drivers/spi/coldfire_qspi.c | |||
@@ -317,7 +317,7 @@ static void mcfqspi_work(struct work_struct *work) | |||
317 | msg = container_of(mcfqspi->msgq.next, struct spi_message, | 317 | msg = container_of(mcfqspi->msgq.next, struct spi_message, |
318 | queue); | 318 | queue); |
319 | 319 | ||
320 | list_del_init(&mcfqspi->msgq); | 320 | list_del_init(&msg->queue); |
321 | spin_unlock_irqrestore(&mcfqspi->lock, flags); | 321 | spin_unlock_irqrestore(&mcfqspi->lock, flags); |
322 | 322 | ||
323 | spi = msg->spi; | 323 | spi = msg->spi; |
diff --git a/drivers/spi/dw_spi.c b/drivers/spi/dw_spi.c index 90439314cf67..0838c79861e4 100644 --- a/drivers/spi/dw_spi.c +++ b/drivers/spi/dw_spi.c | |||
@@ -413,6 +413,11 @@ static void poll_transfer(struct dw_spi *dws) | |||
413 | { | 413 | { |
414 | while (dws->write(dws)) | 414 | while (dws->write(dws)) |
415 | dws->read(dws); | 415 | dws->read(dws); |
416 | /* | ||
417 | * There is a possibility that the last word of a transaction | ||
418 | * will be lost if data is not ready. Re-read to solve this issue. | ||
419 | */ | ||
420 | dws->read(dws); | ||
416 | 421 | ||
417 | transfer_complete(dws); | 422 | transfer_complete(dws); |
418 | } | 423 | } |
diff --git a/drivers/spi/mpc52xx_spi.c b/drivers/spi/mpc52xx_spi.c index ec9f0b1bf864..84439f655601 100644 --- a/drivers/spi/mpc52xx_spi.c +++ b/drivers/spi/mpc52xx_spi.c | |||
@@ -563,7 +563,7 @@ static struct of_platform_driver mpc52xx_spi_of_driver = { | |||
563 | .of_match_table = mpc52xx_spi_match, | 563 | .of_match_table = mpc52xx_spi_match, |
564 | }, | 564 | }, |
565 | .probe = mpc52xx_spi_probe, | 565 | .probe = mpc52xx_spi_probe, |
566 | .remove = __exit_p(mpc52xx_spi_remove), | 566 | .remove = __devexit_p(mpc52xx_spi_remove), |
567 | }; | 567 | }; |
568 | 568 | ||
569 | static int __init mpc52xx_spi_init(void) | 569 | static int __init mpc52xx_spi_init(void) |
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index 2a651e61bfbf..951a160fc27f 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c | |||
@@ -1305,10 +1305,49 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev) | |||
1305 | /* work with hotplug and coldplug */ | 1305 | /* work with hotplug and coldplug */ |
1306 | MODULE_ALIAS("platform:omap2_mcspi"); | 1306 | MODULE_ALIAS("platform:omap2_mcspi"); |
1307 | 1307 | ||
1308 | #ifdef CONFIG_SUSPEND | ||
1309 | /* | ||
1310 | * When SPI wake up from off-mode, CS is in activate state. If it was in | ||
1311 | * unactive state when driver was suspend, then force it to unactive state at | ||
1312 | * wake up. | ||
1313 | */ | ||
1314 | static int omap2_mcspi_resume(struct device *dev) | ||
1315 | { | ||
1316 | struct spi_master *master = dev_get_drvdata(dev); | ||
1317 | struct omap2_mcspi *mcspi = spi_master_get_devdata(master); | ||
1318 | struct omap2_mcspi_cs *cs; | ||
1319 | |||
1320 | omap2_mcspi_enable_clocks(mcspi); | ||
1321 | list_for_each_entry(cs, &omap2_mcspi_ctx[master->bus_num - 1].cs, | ||
1322 | node) { | ||
1323 | if ((cs->chconf0 & OMAP2_MCSPI_CHCONF_FORCE) == 0) { | ||
1324 | |||
1325 | /* | ||
1326 | * We need to toggle CS state for OMAP take this | ||
1327 | * change in account. | ||
1328 | */ | ||
1329 | MOD_REG_BIT(cs->chconf0, OMAP2_MCSPI_CHCONF_FORCE, 1); | ||
1330 | __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); | ||
1331 | MOD_REG_BIT(cs->chconf0, OMAP2_MCSPI_CHCONF_FORCE, 0); | ||
1332 | __raw_writel(cs->chconf0, cs->base + OMAP2_MCSPI_CHCONF0); | ||
1333 | } | ||
1334 | } | ||
1335 | omap2_mcspi_disable_clocks(mcspi); | ||
1336 | return 0; | ||
1337 | } | ||
1338 | #else | ||
1339 | #define omap2_mcspi_resume NULL | ||
1340 | #endif | ||
1341 | |||
1342 | static const struct dev_pm_ops omap2_mcspi_pm_ops = { | ||
1343 | .resume = omap2_mcspi_resume, | ||
1344 | }; | ||
1345 | |||
1308 | static struct platform_driver omap2_mcspi_driver = { | 1346 | static struct platform_driver omap2_mcspi_driver = { |
1309 | .driver = { | 1347 | .driver = { |
1310 | .name = "omap2_mcspi", | 1348 | .name = "omap2_mcspi", |
1311 | .owner = THIS_MODULE, | 1349 | .owner = THIS_MODULE, |
1350 | .pm = &omap2_mcspi_pm_ops | ||
1312 | }, | 1351 | }, |
1313 | .remove = __exit_p(omap2_mcspi_remove), | 1352 | .remove = __exit_p(omap2_mcspi_remove), |
1314 | }; | 1353 | }; |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 709c836607de..b02d0cbce890 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -584,8 +584,7 @@ void spi_unregister_master(struct spi_master *master) | |||
584 | list_del(&master->list); | 584 | list_del(&master->list); |
585 | mutex_unlock(&board_lock); | 585 | mutex_unlock(&board_lock); |
586 | 586 | ||
587 | dummy = device_for_each_child(master->dev.parent, &master->dev, | 587 | dummy = device_for_each_child(&master->dev, NULL, __unregister); |
588 | __unregister); | ||
589 | device_unregister(&master->dev); | 588 | device_unregister(&master->dev); |
590 | } | 589 | } |
591 | EXPORT_SYMBOL_GPL(spi_unregister_master); | 590 | EXPORT_SYMBOL_GPL(spi_unregister_master); |
diff --git a/drivers/spi/spi_fsl_espi.c b/drivers/spi/spi_fsl_espi.c index e3b4f6451966..a99e2333b949 100644 --- a/drivers/spi/spi_fsl_espi.c +++ b/drivers/spi/spi_fsl_espi.c | |||
@@ -258,18 +258,18 @@ static int fsl_espi_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
258 | return mpc8xxx_spi->count; | 258 | return mpc8xxx_spi->count; |
259 | } | 259 | } |
260 | 260 | ||
261 | static void fsl_espi_addr2cmd(unsigned int addr, u8 *cmd) | 261 | static inline void fsl_espi_addr2cmd(unsigned int addr, u8 *cmd) |
262 | { | 262 | { |
263 | if (cmd[1] && cmd[2] && cmd[3]) { | 263 | if (cmd) { |
264 | cmd[1] = (u8)(addr >> 16); | 264 | cmd[1] = (u8)(addr >> 16); |
265 | cmd[2] = (u8)(addr >> 8); | 265 | cmd[2] = (u8)(addr >> 8); |
266 | cmd[3] = (u8)(addr >> 0); | 266 | cmd[3] = (u8)(addr >> 0); |
267 | } | 267 | } |
268 | } | 268 | } |
269 | 269 | ||
270 | static unsigned int fsl_espi_cmd2addr(u8 *cmd) | 270 | static inline unsigned int fsl_espi_cmd2addr(u8 *cmd) |
271 | { | 271 | { |
272 | if (cmd[1] && cmd[2] && cmd[3]) | 272 | if (cmd) |
273 | return cmd[1] << 16 | cmd[2] << 8 | cmd[3] << 0; | 273 | return cmd[1] << 16 | cmd[2] << 8 | cmd[3] << 0; |
274 | 274 | ||
275 | return 0; | 275 | return 0; |
@@ -395,9 +395,11 @@ static void fsl_espi_rw_trans(struct spi_message *m, | |||
395 | } | 395 | } |
396 | } | 396 | } |
397 | 397 | ||
398 | addr = fsl_espi_cmd2addr(local_buf); | 398 | if (pos > 0) { |
399 | addr += pos; | 399 | addr = fsl_espi_cmd2addr(local_buf); |
400 | fsl_espi_addr2cmd(addr, local_buf); | 400 | addr += pos; |
401 | fsl_espi_addr2cmd(addr, local_buf); | ||
402 | } | ||
401 | 403 | ||
402 | espi_trans->n_tx = n_tx; | 404 | espi_trans->n_tx = n_tx; |
403 | espi_trans->n_rx = trans_len; | 405 | espi_trans->n_rx = trans_len; |
@@ -507,16 +509,29 @@ void fsl_espi_cpu_irq(struct mpc8xxx_spi *mspi, u32 events) | |||
507 | 509 | ||
508 | /* We need handle RX first */ | 510 | /* We need handle RX first */ |
509 | if (events & SPIE_NE) { | 511 | if (events & SPIE_NE) { |
510 | u32 rx_data; | 512 | u32 rx_data, tmp; |
513 | u8 rx_data_8; | ||
511 | 514 | ||
512 | /* Spin until RX is done */ | 515 | /* Spin until RX is done */ |
513 | while (SPIE_RXCNT(events) < min(4, mspi->len)) { | 516 | while (SPIE_RXCNT(events) < min(4, mspi->len)) { |
514 | cpu_relax(); | 517 | cpu_relax(); |
515 | events = mpc8xxx_spi_read_reg(®_base->event); | 518 | events = mpc8xxx_spi_read_reg(®_base->event); |
516 | } | 519 | } |
517 | mspi->len -= 4; | ||
518 | 520 | ||
519 | rx_data = mpc8xxx_spi_read_reg(®_base->receive); | 521 | if (mspi->len >= 4) { |
522 | rx_data = mpc8xxx_spi_read_reg(®_base->receive); | ||
523 | } else { | ||
524 | tmp = mspi->len; | ||
525 | rx_data = 0; | ||
526 | while (tmp--) { | ||
527 | rx_data_8 = in_8((u8 *)®_base->receive); | ||
528 | rx_data |= (rx_data_8 << (tmp * 8)); | ||
529 | } | ||
530 | |||
531 | rx_data <<= (4 - mspi->len) * 8; | ||
532 | } | ||
533 | |||
534 | mspi->len -= 4; | ||
520 | 535 | ||
521 | if (mspi->rx) | 536 | if (mspi->rx) |
522 | mspi->get_rx(rx_data, mspi); | 537 | mspi->get_rx(rx_data, mspi); |
diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c index e7f1d5778cec..52389308f333 100644 --- a/drivers/staging/cx25821/cx25821-video.c +++ b/drivers/staging/cx25821/cx25821-video.c | |||
@@ -92,7 +92,7 @@ int cx25821_get_format_size(void) | |||
92 | return ARRAY_SIZE(formats); | 92 | return ARRAY_SIZE(formats); |
93 | } | 93 | } |
94 | 94 | ||
95 | struct cx25821_fmt *format_by_fourcc(unsigned int fourcc) | 95 | struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc) |
96 | { | 96 | { |
97 | unsigned int i; | 97 | unsigned int i; |
98 | 98 | ||
@@ -848,7 +848,7 @@ static int video_open(struct file *file) | |||
848 | pix_format = | 848 | pix_format = |
849 | (dev->channels[ch_id].pixel_formats == | 849 | (dev->channels[ch_id].pixel_formats == |
850 | PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV; | 850 | PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV; |
851 | fh->fmt = format_by_fourcc(pix_format); | 851 | fh->fmt = cx25821_format_by_fourcc(pix_format); |
852 | 852 | ||
853 | v4l2_prio_open(&dev->channels[ch_id].prio, &fh->prio); | 853 | v4l2_prio_open(&dev->channels[ch_id].prio, &fh->prio); |
854 | 854 | ||
@@ -1010,7 +1010,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, | |||
1010 | if (0 != err) | 1010 | if (0 != err) |
1011 | return err; | 1011 | return err; |
1012 | 1012 | ||
1013 | fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat); | 1013 | fh->fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); |
1014 | fh->vidq.field = f->fmt.pix.field; | 1014 | fh->vidq.field = f->fmt.pix.field; |
1015 | 1015 | ||
1016 | /* check if width and height is valid based on set standard */ | 1016 | /* check if width and height is valid based on set standard */ |
@@ -1119,7 +1119,7 @@ int cx25821_vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_fo | |||
1119 | enum v4l2_field field; | 1119 | enum v4l2_field field; |
1120 | unsigned int maxw, maxh; | 1120 | unsigned int maxw, maxh; |
1121 | 1121 | ||
1122 | fmt = format_by_fourcc(f->fmt.pix.pixelformat); | 1122 | fmt = cx25821_format_by_fourcc(f->fmt.pix.pixelformat); |
1123 | if (NULL == fmt) | 1123 | if (NULL == fmt) |
1124 | return -EINVAL; | 1124 | return -EINVAL; |
1125 | 1125 | ||
diff --git a/drivers/staging/cx25821/cx25821-video.h b/drivers/staging/cx25821/cx25821-video.h index cc6034b1a95d..a2415d33235b 100644 --- a/drivers/staging/cx25821/cx25821-video.h +++ b/drivers/staging/cx25821/cx25821-video.h | |||
@@ -87,7 +87,7 @@ extern unsigned int vid_limit; | |||
87 | 87 | ||
88 | #define FORMAT_FLAGS_PACKED 0x01 | 88 | #define FORMAT_FLAGS_PACKED 0x01 |
89 | extern struct cx25821_fmt formats[]; | 89 | extern struct cx25821_fmt formats[]; |
90 | extern struct cx25821_fmt *format_by_fourcc(unsigned int fourcc); | 90 | extern struct cx25821_fmt *cx25821_format_by_fourcc(unsigned int fourcc); |
91 | extern struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM]; | 91 | extern struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM]; |
92 | 92 | ||
93 | extern void cx25821_dump_video_queue(struct cx25821_dev *dev, | 93 | extern void cx25821_dump_video_queue(struct cx25821_dev *dev, |
diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 8c3c057aa847..d0e9e0207539 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c | |||
@@ -435,12 +435,6 @@ static int zram_make_request(struct request_queue *queue, struct bio *bio) | |||
435 | int ret = 0; | 435 | int ret = 0; |
436 | struct zram *zram = queue->queuedata; | 436 | struct zram *zram = queue->queuedata; |
437 | 437 | ||
438 | if (unlikely(!zram->init_done)) { | ||
439 | set_bit(BIO_UPTODATE, &bio->bi_flags); | ||
440 | bio_endio(bio, 0); | ||
441 | return 0; | ||
442 | } | ||
443 | |||
444 | if (!valid_io_request(zram, bio)) { | 438 | if (!valid_io_request(zram, bio)) { |
445 | zram_stat64_inc(zram, &zram->stats.invalid_io); | 439 | zram_stat64_inc(zram, &zram->stats.invalid_io); |
446 | bio_io_error(bio); | 440 | bio_io_error(bio); |
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 81b46585edf7..c5f8e5bda2b2 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c | |||
@@ -716,8 +716,8 @@ static void __gsm_data_queue(struct gsm_dlci *dlci, struct gsm_msg *msg) | |||
716 | if (msg->len < 128) | 716 | if (msg->len < 128) |
717 | *--dp = (msg->len << 1) | EA; | 717 | *--dp = (msg->len << 1) | EA; |
718 | else { | 718 | else { |
719 | *--dp = ((msg->len & 127) << 1) | EA; | 719 | *--dp = (msg->len >> 7); /* bits 7 - 15 */ |
720 | *--dp = (msg->len >> 6) & 0xfe; | 720 | *--dp = (msg->len & 127) << 1; /* bits 0 - 6 */ |
721 | } | 721 | } |
722 | } | 722 | } |
723 | 723 | ||
@@ -968,6 +968,8 @@ static void gsm_control_reply(struct gsm_mux *gsm, int cmd, u8 *data, | |||
968 | { | 968 | { |
969 | struct gsm_msg *msg; | 969 | struct gsm_msg *msg; |
970 | msg = gsm_data_alloc(gsm, 0, dlen + 2, gsm->ftype); | 970 | msg = gsm_data_alloc(gsm, 0, dlen + 2, gsm->ftype); |
971 | if (msg == NULL) | ||
972 | return; | ||
971 | msg->data[0] = (cmd & 0xFE) << 1 | EA; /* Clear C/R */ | 973 | msg->data[0] = (cmd & 0xFE) << 1 | EA; /* Clear C/R */ |
972 | msg->data[1] = (dlen << 1) | EA; | 974 | msg->data[1] = (dlen << 1) | EA; |
973 | memcpy(msg->data + 2, data, dlen); | 975 | memcpy(msg->data + 2, data, dlen); |
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 44447f54942f..99ac70e32556 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c | |||
@@ -2206,8 +2206,11 @@ static int uea_boot(struct uea_softc *sc) | |||
2206 | goto err1; | 2206 | goto err1; |
2207 | } | 2207 | } |
2208 | 2208 | ||
2209 | sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm"); | 2209 | /* Create worker thread, but don't start it here. Start it after |
2210 | if (sc->kthread == ERR_PTR(-ENOMEM)) { | 2210 | * all usbatm generic initialization is done. |
2211 | */ | ||
2212 | sc->kthread = kthread_create(uea_kthread, sc, "ueagle-atm"); | ||
2213 | if (IS_ERR(sc->kthread)) { | ||
2211 | uea_err(INS_TO_USBDEV(sc), "failed to create thread\n"); | 2214 | uea_err(INS_TO_USBDEV(sc), "failed to create thread\n"); |
2212 | goto err2; | 2215 | goto err2; |
2213 | } | 2216 | } |
@@ -2624,6 +2627,7 @@ static struct usbatm_driver uea_usbatm_driver = { | |||
2624 | static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id) | 2627 | static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id) |
2625 | { | 2628 | { |
2626 | struct usb_device *usb = interface_to_usbdev(intf); | 2629 | struct usb_device *usb = interface_to_usbdev(intf); |
2630 | int ret; | ||
2627 | 2631 | ||
2628 | uea_enters(usb); | 2632 | uea_enters(usb); |
2629 | uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) Rev (%#X): %s\n", | 2633 | uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) Rev (%#X): %s\n", |
@@ -2637,7 +2641,19 @@ static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
2637 | if (UEA_IS_PREFIRM(id)) | 2641 | if (UEA_IS_PREFIRM(id)) |
2638 | return uea_load_firmware(usb, UEA_CHIP_VERSION(id)); | 2642 | return uea_load_firmware(usb, UEA_CHIP_VERSION(id)); |
2639 | 2643 | ||
2640 | return usbatm_usb_probe(intf, id, &uea_usbatm_driver); | 2644 | ret = usbatm_usb_probe(intf, id, &uea_usbatm_driver); |
2645 | if (ret == 0) { | ||
2646 | struct usbatm_data *usbatm = usb_get_intfdata(intf); | ||
2647 | struct uea_softc *sc = usbatm->driver_data; | ||
2648 | |||
2649 | /* Ensure carrier is initialized to off as early as possible */ | ||
2650 | UPDATE_ATM_SIGNAL(ATM_PHY_SIG_LOST); | ||
2651 | |||
2652 | /* Only start the worker thread when all init is done */ | ||
2653 | wake_up_process(sc->kthread); | ||
2654 | } | ||
2655 | |||
2656 | return ret; | ||
2641 | } | 2657 | } |
2642 | 2658 | ||
2643 | static void uea_disconnect(struct usb_interface *intf) | 2659 | static void uea_disconnect(struct usb_interface *intf) |
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 05bf5a27b5b0..989e16e4ab5c 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c | |||
@@ -951,7 +951,9 @@ static int usbatm_atm_init(struct usbatm_data *instance) | |||
951 | * condition: callbacks we register can be executed at once, before we have | 951 | * condition: callbacks we register can be executed at once, before we have |
952 | * initialized the struct atm_dev. To protect against this, all callbacks | 952 | * initialized the struct atm_dev. To protect against this, all callbacks |
953 | * abort if atm_dev->dev_data is NULL. */ | 953 | * abort if atm_dev->dev_data is NULL. */ |
954 | atm_dev = atm_dev_register(instance->driver_name, &usbatm_atm_devops, -1, NULL); | 954 | atm_dev = atm_dev_register(instance->driver_name, |
955 | &instance->usb_intf->dev, &usbatm_atm_devops, | ||
956 | -1, NULL); | ||
955 | if (!atm_dev) { | 957 | if (!atm_dev) { |
956 | usb_err(instance, "%s: failed to register ATM device!\n", __func__); | 958 | usb_err(instance, "%s: failed to register ATM device!\n", __func__); |
957 | return -1; | 959 | return -1; |
@@ -966,14 +968,6 @@ static int usbatm_atm_init(struct usbatm_data *instance) | |||
966 | /* temp init ATM device, set to 128kbit */ | 968 | /* temp init ATM device, set to 128kbit */ |
967 | atm_dev->link_rate = 128 * 1000 / 424; | 969 | atm_dev->link_rate = 128 * 1000 / 424; |
968 | 970 | ||
969 | ret = sysfs_create_link(&atm_dev->class_dev.kobj, | ||
970 | &instance->usb_intf->dev.kobj, "device"); | ||
971 | if (ret) { | ||
972 | atm_err(instance, "%s: sysfs_create_link failed: %d\n", | ||
973 | __func__, ret); | ||
974 | goto fail_sysfs; | ||
975 | } | ||
976 | |||
977 | if (instance->driver->atm_start && ((ret = instance->driver->atm_start(instance, atm_dev)) < 0)) { | 971 | if (instance->driver->atm_start && ((ret = instance->driver->atm_start(instance, atm_dev)) < 0)) { |
978 | atm_err(instance, "%s: atm_start failed: %d!\n", __func__, ret); | 972 | atm_err(instance, "%s: atm_start failed: %d!\n", __func__, ret); |
979 | goto fail; | 973 | goto fail; |
@@ -992,8 +986,6 @@ static int usbatm_atm_init(struct usbatm_data *instance) | |||
992 | return 0; | 986 | return 0; |
993 | 987 | ||
994 | fail: | 988 | fail: |
995 | sysfs_remove_link(&atm_dev->class_dev.kobj, "device"); | ||
996 | fail_sysfs: | ||
997 | instance->atm_dev = NULL; | 989 | instance->atm_dev = NULL; |
998 | atm_dev_deregister(atm_dev); /* usbatm_atm_dev_close will eventually be called */ | 990 | atm_dev_deregister(atm_dev); /* usbatm_atm_dev_close will eventually be called */ |
999 | return ret; | 991 | return ret; |
@@ -1329,7 +1321,6 @@ void usbatm_usb_disconnect(struct usb_interface *intf) | |||
1329 | 1321 | ||
1330 | /* ATM finalize */ | 1322 | /* ATM finalize */ |
1331 | if (instance->atm_dev) { | 1323 | if (instance->atm_dev) { |
1332 | sysfs_remove_link(&instance->atm_dev->class_dev.kobj, "device"); | ||
1333 | atm_dev_deregister(instance->atm_dev); | 1324 | atm_dev_deregister(instance->atm_dev); |
1334 | instance->atm_dev = NULL; | 1325 | instance->atm_dev = NULL; |
1335 | } | 1326 | } |
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index 9eed5b52d9de..bcc24779ba0e 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig | |||
@@ -107,11 +107,19 @@ config USB_SUSPEND | |||
107 | If you are unsure about this, say N here. | 107 | If you are unsure about this, say N here. |
108 | 108 | ||
109 | config USB_OTG | 109 | config USB_OTG |
110 | bool | 110 | bool "OTG support" |
111 | depends on USB && EXPERIMENTAL | 111 | depends on USB && EXPERIMENTAL |
112 | depends on USB_SUSPEND | 112 | depends on USB_SUSPEND |
113 | default n | 113 | default n |
114 | 114 | help | |
115 | The most notable feature of USB OTG is support for a | ||
116 | "Dual-Role" device, which can act as either a device | ||
117 | or a host. The initial role is decided by the type of | ||
118 | plug inserted and can be changed later when two dual | ||
119 | role devices talk to each other. | ||
120 | |||
121 | Select this only if your board has Mini-AB/Micro-AB | ||
122 | connector. | ||
115 | 123 | ||
116 | config USB_OTG_WHITELIST | 124 | config USB_OTG_WHITELIST |
117 | bool "Rely on OTG Targeted Peripherals List" | 125 | bool "Rely on OTG Targeted Peripherals List" |
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 7b5cc16e4a0b..8572dad5ecbb 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
@@ -1047,9 +1047,9 @@ composite_unbind(struct usb_gadget *gadget) | |||
1047 | kfree(cdev->req->buf); | 1047 | kfree(cdev->req->buf); |
1048 | usb_ep_free_request(gadget->ep0, cdev->req); | 1048 | usb_ep_free_request(gadget->ep0, cdev->req); |
1049 | } | 1049 | } |
1050 | device_remove_file(&gadget->dev, &dev_attr_suspended); | ||
1050 | kfree(cdev); | 1051 | kfree(cdev); |
1051 | set_gadget_data(gadget, NULL); | 1052 | set_gadget_data(gadget, NULL); |
1052 | device_remove_file(&gadget->dev, &dev_attr_suspended); | ||
1053 | composite = NULL; | 1053 | composite = NULL; |
1054 | } | 1054 | } |
1055 | 1055 | ||
@@ -1107,14 +1107,6 @@ static int composite_bind(struct usb_gadget *gadget) | |||
1107 | */ | 1107 | */ |
1108 | usb_ep_autoconfig_reset(cdev->gadget); | 1108 | usb_ep_autoconfig_reset(cdev->gadget); |
1109 | 1109 | ||
1110 | /* standardized runtime overrides for device ID data */ | ||
1111 | if (idVendor) | ||
1112 | cdev->desc.idVendor = cpu_to_le16(idVendor); | ||
1113 | if (idProduct) | ||
1114 | cdev->desc.idProduct = cpu_to_le16(idProduct); | ||
1115 | if (bcdDevice) | ||
1116 | cdev->desc.bcdDevice = cpu_to_le16(bcdDevice); | ||
1117 | |||
1118 | /* composite gadget needs to assign strings for whole device (like | 1110 | /* composite gadget needs to assign strings for whole device (like |
1119 | * serial number), register function drivers, potentially update | 1111 | * serial number), register function drivers, potentially update |
1120 | * power state and consumption, etc | 1112 | * power state and consumption, etc |
@@ -1126,6 +1118,14 @@ static int composite_bind(struct usb_gadget *gadget) | |||
1126 | cdev->desc = *composite->dev; | 1118 | cdev->desc = *composite->dev; |
1127 | cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket; | 1119 | cdev->desc.bMaxPacketSize0 = gadget->ep0->maxpacket; |
1128 | 1120 | ||
1121 | /* standardized runtime overrides for device ID data */ | ||
1122 | if (idVendor) | ||
1123 | cdev->desc.idVendor = cpu_to_le16(idVendor); | ||
1124 | if (idProduct) | ||
1125 | cdev->desc.idProduct = cpu_to_le16(idProduct); | ||
1126 | if (bcdDevice) | ||
1127 | cdev->desc.bcdDevice = cpu_to_le16(bcdDevice); | ||
1128 | |||
1129 | /* stirng overrides */ | 1129 | /* stirng overrides */ |
1130 | if (iManufacturer || !cdev->desc.iManufacturer) { | 1130 | if (iManufacturer || !cdev->desc.iManufacturer) { |
1131 | if (!iManufacturer && !composite->iManufacturer && | 1131 | if (!iManufacturer && !composite->iManufacturer && |
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c index 0fae58ef8afe..1d0f45f0e7a6 100644 --- a/drivers/usb/host/xhci-mem.c +++ b/drivers/usb/host/xhci-mem.c | |||
@@ -1680,6 +1680,7 @@ static void xhci_add_in_port(struct xhci_hcd *xhci, unsigned int num_ports, | |||
1680 | xhci->port_array[i] = (u8) -1; | 1680 | xhci->port_array[i] = (u8) -1; |
1681 | } | 1681 | } |
1682 | /* FIXME: Should we disable the port? */ | 1682 | /* FIXME: Should we disable the port? */ |
1683 | continue; | ||
1683 | } | 1684 | } |
1684 | xhci->port_array[i] = major_revision; | 1685 | xhci->port_array[i] = major_revision; |
1685 | if (major_revision == 0x03) | 1686 | if (major_revision == 0x03) |
@@ -1758,16 +1759,20 @@ static int xhci_setup_port_arrays(struct xhci_hcd *xhci, gfp_t flags) | |||
1758 | return -ENOMEM; | 1759 | return -ENOMEM; |
1759 | 1760 | ||
1760 | port_index = 0; | 1761 | port_index = 0; |
1761 | for (i = 0; i < num_ports; i++) | 1762 | for (i = 0; i < num_ports; i++) { |
1762 | if (xhci->port_array[i] != 0x03) { | 1763 | if (xhci->port_array[i] == 0x03 || |
1763 | xhci->usb2_ports[port_index] = | 1764 | xhci->port_array[i] == 0 || |
1764 | &xhci->op_regs->port_status_base + | 1765 | xhci->port_array[i] == -1) |
1765 | NUM_PORT_REGS*i; | 1766 | continue; |
1766 | xhci_dbg(xhci, "USB 2.0 port at index %u, " | 1767 | |
1767 | "addr = %p\n", i, | 1768 | xhci->usb2_ports[port_index] = |
1768 | xhci->usb2_ports[port_index]); | 1769 | &xhci->op_regs->port_status_base + |
1769 | port_index++; | 1770 | NUM_PORT_REGS*i; |
1770 | } | 1771 | xhci_dbg(xhci, "USB 2.0 port at index %u, " |
1772 | "addr = %p\n", i, | ||
1773 | xhci->usb2_ports[port_index]); | ||
1774 | port_index++; | ||
1775 | } | ||
1771 | } | 1776 | } |
1772 | if (xhci->num_usb3_ports) { | 1777 | if (xhci->num_usb3_ports) { |
1773 | xhci->usb3_ports = kmalloc(sizeof(*xhci->usb3_ports)* | 1778 | xhci->usb3_ports = kmalloc(sizeof(*xhci->usb3_ports)* |
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index 796e2f68f749..4ff21587ab03 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c | |||
@@ -3,7 +3,7 @@ | |||
3 | /* | 3 | /* |
4 | * uss720.c -- USS720 USB Parport Cable. | 4 | * uss720.c -- USS720 USB Parport Cable. |
5 | * | 5 | * |
6 | * Copyright (C) 1999, 2005 | 6 | * Copyright (C) 1999, 2005, 2010 |
7 | * Thomas Sailer (t.sailer@alumni.ethz.ch) | 7 | * Thomas Sailer (t.sailer@alumni.ethz.ch) |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
@@ -776,6 +776,8 @@ static const struct usb_device_id uss720_table[] = { | |||
776 | { USB_DEVICE(0x0557, 0x2001) }, | 776 | { USB_DEVICE(0x0557, 0x2001) }, |
777 | { USB_DEVICE(0x0729, 0x1284) }, | 777 | { USB_DEVICE(0x0729, 0x1284) }, |
778 | { USB_DEVICE(0x1293, 0x0002) }, | 778 | { USB_DEVICE(0x1293, 0x0002) }, |
779 | { USB_DEVICE(0x1293, 0x0002) }, | ||
780 | { USB_DEVICE(0x050d, 0x0002) }, | ||
779 | { } /* Terminating entry */ | 781 | { } /* Terminating entry */ |
780 | }; | 782 | }; |
781 | 783 | ||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 6a50965e23f2..2dec50013528 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -796,6 +796,7 @@ static struct usb_device_id id_table_combined [] = { | |||
796 | { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LOGBOOKML_PID) }, | 796 | { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LOGBOOKML_PID) }, |
797 | { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LS_LOGBOOK_PID) }, | 797 | { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_LS_LOGBOOK_PID) }, |
798 | { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) }, | 798 | { USB_DEVICE(FTDI_VID, FTDI_SCIENCESCOPE_HS_LOGBOOK_PID) }, |
799 | { USB_DEVICE(FTDI_VID, FTDI_DOTEC_PID) }, | ||
799 | { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID), | 800 | { USB_DEVICE(QIHARDWARE_VID, MILKYMISTONE_JTAGSERIAL_PID), |
800 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 801 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
801 | { }, /* Optional parameter entry */ | 802 | { }, /* Optional parameter entry */ |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 1286f1e23d8c..bf0867285481 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
@@ -1081,6 +1081,11 @@ | |||
1081 | #define MJSG_HD_RADIO_PID 0x937C | 1081 | #define MJSG_HD_RADIO_PID 0x937C |
1082 | 1082 | ||
1083 | /* | 1083 | /* |
1084 | * D.O.Tec products (http://www.directout.eu) | ||
1085 | */ | ||
1086 | #define FTDI_DOTEC_PID 0x9868 | ||
1087 | |||
1088 | /* | ||
1084 | * Xverve Signalyzer tools (http://www.signalyzer.com/) | 1089 | * Xverve Signalyzer tools (http://www.signalyzer.com/) |
1085 | */ | 1090 | */ |
1086 | #define XVERVE_SIGNALYZER_ST_PID 0xBCA0 | 1091 | #define XVERVE_SIGNALYZER_ST_PID 0xBCA0 |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 6ccdd3dd5259..fcc1e32ce256 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -481,6 +481,13 @@ UNUSUAL_DEV( 0x04e8, 0x507c, 0x0220, 0x0220, | |||
481 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 481 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
482 | US_FL_MAX_SECTORS_64), | 482 | US_FL_MAX_SECTORS_64), |
483 | 483 | ||
484 | /* Reported by Vitaly Kuznetsov <vitty@altlinux.ru> */ | ||
485 | UNUSUAL_DEV( 0x04e8, 0x5122, 0x0000, 0x9999, | ||
486 | "Samsung", | ||
487 | "YP-CP3", | ||
488 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
489 | US_FL_MAX_SECTORS_64 | US_FL_BULK_IGNORE_TAG), | ||
490 | |||
484 | /* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>. | 491 | /* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>. |
485 | * Device uses standards-violating 32-byte Bulk Command Block Wrappers and | 492 | * Device uses standards-violating 32-byte Bulk Command Block Wrappers and |
486 | * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011. | 493 | * reports itself as "Proprietary SCSI Bulk." Cf. device entry 0x084d:0x0011. |
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 94701ff3a23a..159c77a5746f 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
@@ -884,6 +884,7 @@ static int log_write(void __user *log_base, | |||
884 | int r; | 884 | int r; |
885 | if (!write_length) | 885 | if (!write_length) |
886 | return 0; | 886 | return 0; |
887 | write_length += write_address % VHOST_PAGE_SIZE; | ||
887 | write_address /= VHOST_PAGE_SIZE; | 888 | write_address /= VHOST_PAGE_SIZE; |
888 | for (;;) { | 889 | for (;;) { |
889 | u64 base = (u64)(unsigned long)log_base; | 890 | u64 base = (u64)(unsigned long)log_base; |
@@ -897,7 +898,7 @@ static int log_write(void __user *log_base, | |||
897 | if (write_length <= VHOST_PAGE_SIZE) | 898 | if (write_length <= VHOST_PAGE_SIZE) |
898 | break; | 899 | break; |
899 | write_length -= VHOST_PAGE_SIZE; | 900 | write_length -= VHOST_PAGE_SIZE; |
900 | write_address += VHOST_PAGE_SIZE; | 901 | write_address += 1; |
901 | } | 902 | } |
902 | return r; | 903 | return r; |
903 | } | 904 | } |
diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c index a4f4546f0be0..397d15eb1ea8 100644 --- a/drivers/video/backlight/cr_bllcd.c +++ b/drivers/video/backlight/cr_bllcd.c | |||
@@ -242,6 +242,7 @@ static int cr_backlight_remove(struct platform_device *pdev) | |||
242 | backlight_device_unregister(crp->cr_backlight_device); | 242 | backlight_device_unregister(crp->cr_backlight_device); |
243 | lcd_device_unregister(crp->cr_lcd_device); | 243 | lcd_device_unregister(crp->cr_lcd_device); |
244 | pci_dev_put(lpc_dev); | 244 | pci_dev_put(lpc_dev); |
245 | kfree(crp); | ||
245 | 246 | ||
246 | return 0; | 247 | return 0; |
247 | } | 248 | } |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 0e6aa3d96a42..4ac1201ad6c2 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -1458,7 +1458,7 @@ static bool apertures_overlap(struct aperture *gen, struct aperture *hw) | |||
1458 | if (gen->base == hw->base) | 1458 | if (gen->base == hw->base) |
1459 | return true; | 1459 | return true; |
1460 | /* is the generic aperture base inside the hw base->hw base+size */ | 1460 | /* is the generic aperture base inside the hw base->hw base+size */ |
1461 | if (gen->base > hw->base && gen->base <= hw->base + hw->size) | 1461 | if (gen->base > hw->base && gen->base < hw->base + hw->size) |
1462 | return true; | 1462 | return true; |
1463 | return false; | 1463 | return false; |
1464 | } | 1464 | } |
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index 5c363d026f64..1ab2c2588675 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c | |||
@@ -53,11 +53,8 @@ | |||
53 | #define LCDC_SIZE 0x04 | 53 | #define LCDC_SIZE 0x04 |
54 | #define SIZE_XMAX(x) ((((x) >> 4) & 0x3f) << 20) | 54 | #define SIZE_XMAX(x) ((((x) >> 4) & 0x3f) << 20) |
55 | 55 | ||
56 | #ifdef CONFIG_ARCH_MX1 | 56 | #define YMAX_MASK (cpu_is_mx1() ? 0x1ff : 0x3ff) |
57 | #define SIZE_YMAX(y) ((y) & 0x1ff) | 57 | #define SIZE_YMAX(y) ((y) & YMAX_MASK) |
58 | #else | ||
59 | #define SIZE_YMAX(y) ((y) & 0x3ff) | ||
60 | #endif | ||
61 | 58 | ||
62 | #define LCDC_VPW 0x08 | 59 | #define LCDC_VPW 0x08 |
63 | #define VPW_VPW(x) ((x) & 0x3ff) | 60 | #define VPW_VPW(x) ((x) & 0x3ff) |
@@ -623,7 +620,7 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf | |||
623 | if (var->right_margin > 255) | 620 | if (var->right_margin > 255) |
624 | printk(KERN_ERR "%s: invalid right_margin %d\n", | 621 | printk(KERN_ERR "%s: invalid right_margin %d\n", |
625 | info->fix.id, var->right_margin); | 622 | info->fix.id, var->right_margin); |
626 | if (var->yres < 1 || var->yres > 511) | 623 | if (var->yres < 1 || var->yres > YMAX_MASK) |
627 | printk(KERN_ERR "%s: invalid yres %d\n", | 624 | printk(KERN_ERR "%s: invalid yres %d\n", |
628 | info->fix.id, var->yres); | 625 | info->fix.id, var->yres); |
629 | if (var->vsync_len > 100) | 626 | if (var->vsync_len > 100) |
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index 0a4dbdc1693a..de450c1fb869 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/modedb.c | |||
@@ -855,6 +855,7 @@ const struct fb_videomode *fb_find_nearest_mode(const struct fb_videomode *mode, | |||
855 | abs(cmode->yres - mode->yres); | 855 | abs(cmode->yres - mode->yres); |
856 | if (diff > d) { | 856 | if (diff > d) { |
857 | diff = d; | 857 | diff = d; |
858 | diff_refresh = abs(cmode->refresh - mode->refresh); | ||
858 | best = cmode; | 859 | best = cmode; |
859 | } else if (diff == d) { | 860 | } else if (diff == d) { |
860 | d = abs(cmode->refresh - mode->refresh); | 861 | d = abs(cmode->refresh - mode->refresh); |
diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig index 455c6055325d..083c8fe53e24 100644 --- a/drivers/video/omap/Kconfig +++ b/drivers/video/omap/Kconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | config FB_OMAP | 1 | config FB_OMAP |
2 | tristate "OMAP frame buffer support (EXPERIMENTAL)" | 2 | tristate "OMAP frame buffer support (EXPERIMENTAL)" |
3 | depends on FB && ARCH_OMAP && (OMAP2_DSS = "n") | 3 | depends on FB && (OMAP2_DSS = "n") |
4 | 4 | depends on ARCH_OMAP1 || ARCH_OMAP2 || ARCH_OMAP3 | |
5 | select FB_CFB_FILLRECT | 5 | select FB_CFB_FILLRECT |
6 | select FB_CFB_COPYAREA | 6 | select FB_CFB_COPYAREA |
7 | select FB_CFB_IMAGEBLIT | 7 | select FB_CFB_IMAGEBLIT |
diff --git a/drivers/video/omap2/vram.c b/drivers/video/omap2/vram.c index 2fd7e5271be9..9441e2eb3dee 100644 --- a/drivers/video/omap2/vram.c +++ b/drivers/video/omap2/vram.c | |||
@@ -551,7 +551,7 @@ void __init omap_vram_reserve_sdram_memblock(void) | |||
551 | if (!size) | 551 | if (!size) |
552 | return; | 552 | return; |
553 | 553 | ||
554 | size = PAGE_ALIGN(size); | 554 | size = ALIGN(size, SZ_2M); |
555 | 555 | ||
556 | if (paddr) { | 556 | if (paddr) { |
557 | if (paddr & ~PAGE_MASK) { | 557 | if (paddr & ~PAGE_MASK) { |
@@ -576,7 +576,7 @@ void __init omap_vram_reserve_sdram_memblock(void) | |||
576 | return; | 576 | return; |
577 | } | 577 | } |
578 | } else { | 578 | } else { |
579 | paddr = memblock_alloc(size, PAGE_SIZE); | 579 | paddr = memblock_alloc(size, SZ_2M); |
580 | } | 580 | } |
581 | 581 | ||
582 | memblock_free(paddr, size); | 582 | memblock_free(paddr, size); |
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c index d7df10315d8d..fcda0e970113 100644 --- a/drivers/video/sh_mobile_hdmi.c +++ b/drivers/video/sh_mobile_hdmi.c | |||
@@ -787,6 +787,9 @@ static int sh_hdmi_read_edid(struct sh_hdmi *hdmi) | |||
787 | found_rate_error = rate_error; | 787 | found_rate_error = rate_error; |
788 | } | 788 | } |
789 | 789 | ||
790 | hdmi->var.width = hdmi->monspec.max_x * 10; | ||
791 | hdmi->var.height = hdmi->monspec.max_y * 10; | ||
792 | |||
790 | /* | 793 | /* |
791 | * TODO 1: if no ->info is present, postpone running the config until | 794 | * TODO 1: if no ->info is present, postpone running the config until |
792 | * after ->info first gets registered. | 795 | * after ->info first gets registered. |
@@ -960,8 +963,12 @@ static bool sh_hdmi_must_reconfigure(struct sh_hdmi *hdmi) | |||
960 | dev_dbg(info->dev, "Old %ux%u, new %ux%u\n", | 963 | dev_dbg(info->dev, "Old %ux%u, new %ux%u\n", |
961 | mode1.xres, mode1.yres, mode2.xres, mode2.yres); | 964 | mode1.xres, mode1.yres, mode2.xres, mode2.yres); |
962 | 965 | ||
963 | if (fb_mode_is_equal(&mode1, &mode2)) | 966 | if (fb_mode_is_equal(&mode1, &mode2)) { |
967 | /* It can be a different monitor with an equal video-mode */ | ||
968 | old_var->width = new_var->width; | ||
969 | old_var->height = new_var->height; | ||
964 | return false; | 970 | return false; |
971 | } | ||
965 | 972 | ||
966 | dev_dbg(info->dev, "Switching %u -> %u lines\n", | 973 | dev_dbg(info->dev, "Switching %u -> %u lines\n", |
967 | mode1.yres, mode2.yres); | 974 | mode1.yres, mode2.yres); |
@@ -1057,8 +1064,11 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work) | |||
1057 | * on, if we run a resume here, the logo disappears | 1064 | * on, if we run a resume here, the logo disappears |
1058 | */ | 1065 | */ |
1059 | if (lock_fb_info(hdmi->info)) { | 1066 | if (lock_fb_info(hdmi->info)) { |
1060 | sh_hdmi_display_on(hdmi, hdmi->info); | 1067 | struct fb_info *info = hdmi->info; |
1061 | unlock_fb_info(hdmi->info); | 1068 | info->var.width = hdmi->var.width; |
1069 | info->var.height = hdmi->var.height; | ||
1070 | sh_hdmi_display_on(hdmi, info); | ||
1071 | unlock_fb_info(info); | ||
1062 | } | 1072 | } |
1063 | } else { | 1073 | } else { |
1064 | /* New monitor or have to wake up */ | 1074 | /* New monitor or have to wake up */ |
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index b02d97a879d6..c05326b61235 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c | |||
@@ -54,8 +54,8 @@ static int lcdc_shared_regs[] = { | |||
54 | }; | 54 | }; |
55 | #define NR_SHARED_REGS ARRAY_SIZE(lcdc_shared_regs) | 55 | #define NR_SHARED_REGS ARRAY_SIZE(lcdc_shared_regs) |
56 | 56 | ||
57 | #define DEFAULT_XRES 1280 | 57 | #define MAX_XRES 1920 |
58 | #define DEFAULT_YRES 1024 | 58 | #define MAX_YRES 1080 |
59 | 59 | ||
60 | static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = { | 60 | static unsigned long lcdc_offs_mainlcd[NR_CH_REGS] = { |
61 | [LDDCKPAT1R] = 0x400, | 61 | [LDDCKPAT1R] = 0x400, |
@@ -914,22 +914,12 @@ static int sh_mobile_check_var(struct fb_var_screeninfo *var, struct fb_info *in | |||
914 | { | 914 | { |
915 | struct sh_mobile_lcdc_chan *ch = info->par; | 915 | struct sh_mobile_lcdc_chan *ch = info->par; |
916 | 916 | ||
917 | if (var->xres < 160 || var->xres > 1920 || | 917 | if (var->xres > MAX_XRES || var->yres > MAX_YRES || |
918 | var->yres < 120 || var->yres > 1080 || | ||
919 | var->left_margin < 32 || var->left_margin > 320 || | ||
920 | var->right_margin < 12 || var->right_margin > 240 || | ||
921 | var->upper_margin < 12 || var->upper_margin > 120 || | ||
922 | var->lower_margin < 1 || var->lower_margin > 64 || | ||
923 | var->hsync_len < 32 || var->hsync_len > 240 || | ||
924 | var->vsync_len < 2 || var->vsync_len > 64 || | ||
925 | var->pixclock < 6000 || var->pixclock > 40000 || | ||
926 | var->xres * var->yres * (ch->cfg.bpp / 8) * 2 > info->fix.smem_len) { | 918 | var->xres * var->yres * (ch->cfg.bpp / 8) * 2 > info->fix.smem_len) { |
927 | dev_warn(info->dev, "Invalid info: %u %u %u %u %u %u %u %u %u!\n", | 919 | dev_warn(info->dev, "Invalid info: %u-%u-%u-%u x %u-%u-%u-%u @ %ukHz!\n", |
928 | var->xres, var->yres, | 920 | var->left_margin, var->xres, var->right_margin, var->hsync_len, |
929 | var->left_margin, var->right_margin, | 921 | var->upper_margin, var->yres, var->lower_margin, var->vsync_len, |
930 | var->upper_margin, var->lower_margin, | 922 | PICOS2KHZ(var->pixclock)); |
931 | var->hsync_len, var->vsync_len, | ||
932 | var->pixclock); | ||
933 | return -EINVAL; | 923 | return -EINVAL; |
934 | } | 924 | } |
935 | return 0; | 925 | return 0; |
@@ -1226,7 +1216,7 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
1226 | } | 1216 | } |
1227 | 1217 | ||
1228 | if (!mode) | 1218 | if (!mode) |
1229 | max_size = DEFAULT_XRES * DEFAULT_YRES; | 1219 | max_size = MAX_XRES * MAX_YRES; |
1230 | else if (max_cfg) | 1220 | else if (max_cfg) |
1231 | dev_dbg(&pdev->dev, "Found largest videomode %ux%u\n", | 1221 | dev_dbg(&pdev->dev, "Found largest videomode %ux%u\n", |
1232 | max_cfg->xres, max_cfg->yres); | 1222 | max_cfg->xres, max_cfg->yres); |
@@ -1238,12 +1228,14 @@ static int __devinit sh_mobile_lcdc_probe(struct platform_device *pdev) | |||
1238 | mode = &default_720p; | 1228 | mode = &default_720p; |
1239 | num_cfg = 1; | 1229 | num_cfg = 1; |
1240 | } else { | 1230 | } else { |
1241 | num_cfg = ch->cfg.num_cfg; | 1231 | num_cfg = cfg->num_cfg; |
1242 | } | 1232 | } |
1243 | 1233 | ||
1244 | fb_videomode_to_modelist(mode, num_cfg, &info->modelist); | 1234 | fb_videomode_to_modelist(mode, num_cfg, &info->modelist); |
1245 | 1235 | ||
1246 | fb_videomode_to_var(var, mode); | 1236 | fb_videomode_to_var(var, mode); |
1237 | var->width = cfg->lcd_size_cfg.width; | ||
1238 | var->height = cfg->lcd_size_cfg.height; | ||
1247 | /* Default Y virtual resolution is 2x panel size */ | 1239 | /* Default Y virtual resolution is 2x panel size */ |
1248 | var->yres_virtual = var->yres * 2; | 1240 | var->yres_virtual = var->yres * 2; |
1249 | var->activate = FB_ACTIVATE_NOW; | 1241 | var->activate = FB_ACTIVATE_NOW; |
diff --git a/drivers/watchdog/rdc321x_wdt.c b/drivers/watchdog/rdc321x_wdt.c index 428f8a1583e8..3939e53f5f98 100644 --- a/drivers/watchdog/rdc321x_wdt.c +++ b/drivers/watchdog/rdc321x_wdt.c | |||
@@ -231,7 +231,7 @@ static int __devinit rdc321x_wdt_probe(struct platform_device *pdev) | |||
231 | struct resource *r; | 231 | struct resource *r; |
232 | struct rdc321x_wdt_pdata *pdata; | 232 | struct rdc321x_wdt_pdata *pdata; |
233 | 233 | ||
234 | pdata = pdev->dev.platform_data; | 234 | pdata = platform_get_drvdata(pdev); |
235 | if (!pdata) { | 235 | if (!pdata) { |
236 | dev_err(&pdev->dev, "no platform data supplied\n"); | 236 | dev_err(&pdev->dev, "no platform data supplied\n"); |
237 | return -ENODEV; | 237 | return -ENODEV; |
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index d5c1401f0031..d34896cfb19f 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -980,19 +980,11 @@ static int autofs4_root_ioctl_unlocked(struct inode *inode, struct file *filp, | |||
980 | } | 980 | } |
981 | } | 981 | } |
982 | 982 | ||
983 | static DEFINE_MUTEX(autofs4_ioctl_mutex); | ||
984 | |||
985 | static long autofs4_root_ioctl(struct file *filp, | 983 | static long autofs4_root_ioctl(struct file *filp, |
986 | unsigned int cmd, unsigned long arg) | 984 | unsigned int cmd, unsigned long arg) |
987 | { | 985 | { |
988 | long ret; | ||
989 | struct inode *inode = filp->f_dentry->d_inode; | 986 | struct inode *inode = filp->f_dentry->d_inode; |
990 | 987 | return autofs4_root_ioctl_unlocked(inode, filp, cmd, arg); | |
991 | mutex_lock(&autofs4_ioctl_mutex); | ||
992 | ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, arg); | ||
993 | mutex_unlock(&autofs4_ioctl_mutex); | ||
994 | |||
995 | return ret; | ||
996 | } | 988 | } |
997 | 989 | ||
998 | #ifdef CONFIG_COMPAT | 990 | #ifdef CONFIG_COMPAT |
@@ -1002,13 +994,11 @@ static long autofs4_root_compat_ioctl(struct file *filp, | |||
1002 | struct inode *inode = filp->f_path.dentry->d_inode; | 994 | struct inode *inode = filp->f_path.dentry->d_inode; |
1003 | int ret; | 995 | int ret; |
1004 | 996 | ||
1005 | mutex_lock(&autofs4_ioctl_mutex); | ||
1006 | if (cmd == AUTOFS_IOC_READY || cmd == AUTOFS_IOC_FAIL) | 997 | if (cmd == AUTOFS_IOC_READY || cmd == AUTOFS_IOC_FAIL) |
1007 | ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, arg); | 998 | ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, arg); |
1008 | else | 999 | else |
1009 | ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, | 1000 | ret = autofs4_root_ioctl_unlocked(inode, filp, cmd, |
1010 | (unsigned long)compat_ptr(arg)); | 1001 | (unsigned long)compat_ptr(arg)); |
1011 | mutex_unlock(&autofs4_ioctl_mutex); | ||
1012 | 1002 | ||
1013 | return ret; | 1003 | return ret; |
1014 | } | 1004 | } |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index c547cca26a26..51d2e4de34eb 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -696,6 +696,7 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, | |||
696 | __btree_submit_bio_done); | 696 | __btree_submit_bio_done); |
697 | } | 697 | } |
698 | 698 | ||
699 | #ifdef CONFIG_MIGRATION | ||
699 | static int btree_migratepage(struct address_space *mapping, | 700 | static int btree_migratepage(struct address_space *mapping, |
700 | struct page *newpage, struct page *page) | 701 | struct page *newpage, struct page *page) |
701 | { | 702 | { |
@@ -712,12 +713,9 @@ static int btree_migratepage(struct address_space *mapping, | |||
712 | if (page_has_private(page) && | 713 | if (page_has_private(page) && |
713 | !try_to_release_page(page, GFP_KERNEL)) | 714 | !try_to_release_page(page, GFP_KERNEL)) |
714 | return -EAGAIN; | 715 | return -EAGAIN; |
715 | #ifdef CONFIG_MIGRATION | ||
716 | return migrate_page(mapping, newpage, page); | 716 | return migrate_page(mapping, newpage, page); |
717 | #else | ||
718 | return -ENOSYS; | ||
719 | #endif | ||
720 | } | 717 | } |
718 | #endif | ||
721 | 719 | ||
722 | static int btree_writepage(struct page *page, struct writeback_control *wbc) | 720 | static int btree_writepage(struct page *page, struct writeback_control *wbc) |
723 | { | 721 | { |
@@ -1009,7 +1007,10 @@ static int find_and_setup_root(struct btrfs_root *tree_root, | |||
1009 | blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); | 1007 | blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); |
1010 | root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), | 1008 | root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), |
1011 | blocksize, generation); | 1009 | blocksize, generation); |
1012 | BUG_ON(!root->node); | 1010 | if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) { |
1011 | free_extent_buffer(root->node); | ||
1012 | return -EIO; | ||
1013 | } | ||
1013 | root->commit_root = btrfs_root_node(root); | 1014 | root->commit_root = btrfs_root_node(root); |
1014 | return 0; | 1015 | return 0; |
1015 | } | 1016 | } |
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c index 6f0444473594..659f532d26a0 100644 --- a/fs/btrfs/export.c +++ b/fs/btrfs/export.c | |||
@@ -166,7 +166,7 @@ static struct dentry *btrfs_fh_to_dentry(struct super_block *sb, struct fid *fh, | |||
166 | static struct dentry *btrfs_get_parent(struct dentry *child) | 166 | static struct dentry *btrfs_get_parent(struct dentry *child) |
167 | { | 167 | { |
168 | struct inode *dir = child->d_inode; | 168 | struct inode *dir = child->d_inode; |
169 | static struct dentry *dentry; | 169 | struct dentry *dentry; |
170 | struct btrfs_root *root = BTRFS_I(dir)->root; | 170 | struct btrfs_root *root = BTRFS_I(dir)->root; |
171 | struct btrfs_path *path; | 171 | struct btrfs_path *path; |
172 | struct extent_buffer *leaf; | 172 | struct extent_buffer *leaf; |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index bcd59c7dfb57..227e5815d838 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -429,6 +429,7 @@ err: | |||
429 | 429 | ||
430 | static int cache_block_group(struct btrfs_block_group_cache *cache, | 430 | static int cache_block_group(struct btrfs_block_group_cache *cache, |
431 | struct btrfs_trans_handle *trans, | 431 | struct btrfs_trans_handle *trans, |
432 | struct btrfs_root *root, | ||
432 | int load_cache_only) | 433 | int load_cache_only) |
433 | { | 434 | { |
434 | struct btrfs_fs_info *fs_info = cache->fs_info; | 435 | struct btrfs_fs_info *fs_info = cache->fs_info; |
@@ -442,9 +443,12 @@ static int cache_block_group(struct btrfs_block_group_cache *cache, | |||
442 | 443 | ||
443 | /* | 444 | /* |
444 | * We can't do the read from on-disk cache during a commit since we need | 445 | * We can't do the read from on-disk cache during a commit since we need |
445 | * to have the normal tree locking. | 446 | * to have the normal tree locking. Also if we are currently trying to |
447 | * allocate blocks for the tree root we can't do the fast caching since | ||
448 | * we likely hold important locks. | ||
446 | */ | 449 | */ |
447 | if (!trans->transaction->in_commit) { | 450 | if (!trans->transaction->in_commit && |
451 | (root && root != root->fs_info->tree_root)) { | ||
448 | spin_lock(&cache->lock); | 452 | spin_lock(&cache->lock); |
449 | if (cache->cached != BTRFS_CACHE_NO) { | 453 | if (cache->cached != BTRFS_CACHE_NO) { |
450 | spin_unlock(&cache->lock); | 454 | spin_unlock(&cache->lock); |
@@ -2741,6 +2745,7 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group, | |||
2741 | struct btrfs_root *root = block_group->fs_info->tree_root; | 2745 | struct btrfs_root *root = block_group->fs_info->tree_root; |
2742 | struct inode *inode = NULL; | 2746 | struct inode *inode = NULL; |
2743 | u64 alloc_hint = 0; | 2747 | u64 alloc_hint = 0; |
2748 | int dcs = BTRFS_DC_ERROR; | ||
2744 | int num_pages = 0; | 2749 | int num_pages = 0; |
2745 | int retries = 0; | 2750 | int retries = 0; |
2746 | int ret = 0; | 2751 | int ret = 0; |
@@ -2795,6 +2800,8 @@ again: | |||
2795 | 2800 | ||
2796 | spin_lock(&block_group->lock); | 2801 | spin_lock(&block_group->lock); |
2797 | if (block_group->cached != BTRFS_CACHE_FINISHED) { | 2802 | if (block_group->cached != BTRFS_CACHE_FINISHED) { |
2803 | /* We're not cached, don't bother trying to write stuff out */ | ||
2804 | dcs = BTRFS_DC_WRITTEN; | ||
2798 | spin_unlock(&block_group->lock); | 2805 | spin_unlock(&block_group->lock); |
2799 | goto out_put; | 2806 | goto out_put; |
2800 | } | 2807 | } |
@@ -2821,6 +2828,8 @@ again: | |||
2821 | ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, num_pages, | 2828 | ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, num_pages, |
2822 | num_pages, num_pages, | 2829 | num_pages, num_pages, |
2823 | &alloc_hint); | 2830 | &alloc_hint); |
2831 | if (!ret) | ||
2832 | dcs = BTRFS_DC_SETUP; | ||
2824 | btrfs_free_reserved_data_space(inode, num_pages); | 2833 | btrfs_free_reserved_data_space(inode, num_pages); |
2825 | out_put: | 2834 | out_put: |
2826 | iput(inode); | 2835 | iput(inode); |
@@ -2828,10 +2837,7 @@ out_free: | |||
2828 | btrfs_release_path(root, path); | 2837 | btrfs_release_path(root, path); |
2829 | out: | 2838 | out: |
2830 | spin_lock(&block_group->lock); | 2839 | spin_lock(&block_group->lock); |
2831 | if (ret) | 2840 | block_group->disk_cache_state = dcs; |
2832 | block_group->disk_cache_state = BTRFS_DC_ERROR; | ||
2833 | else | ||
2834 | block_group->disk_cache_state = BTRFS_DC_SETUP; | ||
2835 | spin_unlock(&block_group->lock); | 2841 | spin_unlock(&block_group->lock); |
2836 | 2842 | ||
2837 | return ret; | 2843 | return ret; |
@@ -3037,7 +3043,13 @@ static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags) | |||
3037 | 3043 | ||
3038 | u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags) | 3044 | u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags) |
3039 | { | 3045 | { |
3040 | u64 num_devices = root->fs_info->fs_devices->rw_devices; | 3046 | /* |
3047 | * we add in the count of missing devices because we want | ||
3048 | * to make sure that any RAID levels on a degraded FS | ||
3049 | * continue to be honored. | ||
3050 | */ | ||
3051 | u64 num_devices = root->fs_info->fs_devices->rw_devices + | ||
3052 | root->fs_info->fs_devices->missing_devices; | ||
3041 | 3053 | ||
3042 | if (num_devices == 1) | 3054 | if (num_devices == 1) |
3043 | flags &= ~(BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID0); | 3055 | flags &= ~(BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID0); |
@@ -4080,7 +4092,7 @@ static int update_block_group(struct btrfs_trans_handle *trans, | |||
4080 | * space back to the block group, otherwise we will leak space. | 4092 | * space back to the block group, otherwise we will leak space. |
4081 | */ | 4093 | */ |
4082 | if (!alloc && cache->cached == BTRFS_CACHE_NO) | 4094 | if (!alloc && cache->cached == BTRFS_CACHE_NO) |
4083 | cache_block_group(cache, trans, 1); | 4095 | cache_block_group(cache, trans, NULL, 1); |
4084 | 4096 | ||
4085 | byte_in_group = bytenr - cache->key.objectid; | 4097 | byte_in_group = bytenr - cache->key.objectid; |
4086 | WARN_ON(byte_in_group > cache->key.offset); | 4098 | WARN_ON(byte_in_group > cache->key.offset); |
@@ -4930,11 +4942,31 @@ search: | |||
4930 | btrfs_get_block_group(block_group); | 4942 | btrfs_get_block_group(block_group); |
4931 | search_start = block_group->key.objectid; | 4943 | search_start = block_group->key.objectid; |
4932 | 4944 | ||
4945 | /* | ||
4946 | * this can happen if we end up cycling through all the | ||
4947 | * raid types, but we want to make sure we only allocate | ||
4948 | * for the proper type. | ||
4949 | */ | ||
4950 | if (!block_group_bits(block_group, data)) { | ||
4951 | u64 extra = BTRFS_BLOCK_GROUP_DUP | | ||
4952 | BTRFS_BLOCK_GROUP_RAID1 | | ||
4953 | BTRFS_BLOCK_GROUP_RAID10; | ||
4954 | |||
4955 | /* | ||
4956 | * if they asked for extra copies and this block group | ||
4957 | * doesn't provide them, bail. This does allow us to | ||
4958 | * fill raid0 from raid1. | ||
4959 | */ | ||
4960 | if ((data & extra) && !(block_group->flags & extra)) | ||
4961 | goto loop; | ||
4962 | } | ||
4963 | |||
4933 | have_block_group: | 4964 | have_block_group: |
4934 | if (unlikely(block_group->cached == BTRFS_CACHE_NO)) { | 4965 | if (unlikely(block_group->cached == BTRFS_CACHE_NO)) { |
4935 | u64 free_percent; | 4966 | u64 free_percent; |
4936 | 4967 | ||
4937 | ret = cache_block_group(block_group, trans, 1); | 4968 | ret = cache_block_group(block_group, trans, |
4969 | orig_root, 1); | ||
4938 | if (block_group->cached == BTRFS_CACHE_FINISHED) | 4970 | if (block_group->cached == BTRFS_CACHE_FINISHED) |
4939 | goto have_block_group; | 4971 | goto have_block_group; |
4940 | 4972 | ||
@@ -4958,7 +4990,8 @@ have_block_group: | |||
4958 | if (loop > LOOP_CACHING_NOWAIT || | 4990 | if (loop > LOOP_CACHING_NOWAIT || |
4959 | (loop > LOOP_FIND_IDEAL && | 4991 | (loop > LOOP_FIND_IDEAL && |
4960 | atomic_read(&space_info->caching_threads) < 2)) { | 4992 | atomic_read(&space_info->caching_threads) < 2)) { |
4961 | ret = cache_block_group(block_group, trans, 0); | 4993 | ret = cache_block_group(block_group, trans, |
4994 | orig_root, 0); | ||
4962 | BUG_ON(ret); | 4995 | BUG_ON(ret); |
4963 | } | 4996 | } |
4964 | found_uncached_bg = true; | 4997 | found_uncached_bg = true; |
@@ -5515,7 +5548,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, | |||
5515 | u64 num_bytes = ins->offset; | 5548 | u64 num_bytes = ins->offset; |
5516 | 5549 | ||
5517 | block_group = btrfs_lookup_block_group(root->fs_info, ins->objectid); | 5550 | block_group = btrfs_lookup_block_group(root->fs_info, ins->objectid); |
5518 | cache_block_group(block_group, trans, 0); | 5551 | cache_block_group(block_group, trans, NULL, 0); |
5519 | caching_ctl = get_caching_control(block_group); | 5552 | caching_ctl = get_caching_control(block_group); |
5520 | 5553 | ||
5521 | if (!caching_ctl) { | 5554 | if (!caching_ctl) { |
@@ -6300,9 +6333,13 @@ int btrfs_drop_snapshot(struct btrfs_root *root, | |||
6300 | NULL, NULL); | 6333 | NULL, NULL); |
6301 | BUG_ON(ret < 0); | 6334 | BUG_ON(ret < 0); |
6302 | if (ret > 0) { | 6335 | if (ret > 0) { |
6303 | ret = btrfs_del_orphan_item(trans, tree_root, | 6336 | /* if we fail to delete the orphan item this time |
6304 | root->root_key.objectid); | 6337 | * around, it'll get picked up the next time. |
6305 | BUG_ON(ret); | 6338 | * |
6339 | * The most common failure here is just -ENOENT. | ||
6340 | */ | ||
6341 | btrfs_del_orphan_item(trans, tree_root, | ||
6342 | root->root_key.objectid); | ||
6306 | } | 6343 | } |
6307 | } | 6344 | } |
6308 | 6345 | ||
@@ -7878,7 +7915,14 @@ static u64 update_block_group_flags(struct btrfs_root *root, u64 flags) | |||
7878 | u64 stripped = BTRFS_BLOCK_GROUP_RAID0 | | 7915 | u64 stripped = BTRFS_BLOCK_GROUP_RAID0 | |
7879 | BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10; | 7916 | BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10; |
7880 | 7917 | ||
7881 | num_devices = root->fs_info->fs_devices->rw_devices; | 7918 | /* |
7919 | * we add in the count of missing devices because we want | ||
7920 | * to make sure that any RAID levels on a degraded FS | ||
7921 | * continue to be honored. | ||
7922 | */ | ||
7923 | num_devices = root->fs_info->fs_devices->rw_devices + | ||
7924 | root->fs_info->fs_devices->missing_devices; | ||
7925 | |||
7882 | if (num_devices == 1) { | 7926 | if (num_devices == 1) { |
7883 | stripped |= BTRFS_BLOCK_GROUP_DUP; | 7927 | stripped |= BTRFS_BLOCK_GROUP_DUP; |
7884 | stripped = flags & ~stripped; | 7928 | stripped = flags & ~stripped; |
@@ -8247,7 +8291,6 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
8247 | break; | 8291 | break; |
8248 | if (ret != 0) | 8292 | if (ret != 0) |
8249 | goto error; | 8293 | goto error; |
8250 | |||
8251 | leaf = path->nodes[0]; | 8294 | leaf = path->nodes[0]; |
8252 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); | 8295 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); |
8253 | cache = kzalloc(sizeof(*cache), GFP_NOFS); | 8296 | cache = kzalloc(sizeof(*cache), GFP_NOFS); |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index c1faded5fca0..66836d85763b 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -48,30 +48,34 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages, | |||
48 | struct page **prepared_pages, | 48 | struct page **prepared_pages, |
49 | struct iov_iter *i) | 49 | struct iov_iter *i) |
50 | { | 50 | { |
51 | size_t copied; | 51 | size_t copied = 0; |
52 | int pg = 0; | 52 | int pg = 0; |
53 | int offset = pos & (PAGE_CACHE_SIZE - 1); | 53 | int offset = pos & (PAGE_CACHE_SIZE - 1); |
54 | int total_copied = 0; | ||
54 | 55 | ||
55 | while (write_bytes > 0) { | 56 | while (write_bytes > 0) { |
56 | size_t count = min_t(size_t, | 57 | size_t count = min_t(size_t, |
57 | PAGE_CACHE_SIZE - offset, write_bytes); | 58 | PAGE_CACHE_SIZE - offset, write_bytes); |
58 | struct page *page = prepared_pages[pg]; | 59 | struct page *page = prepared_pages[pg]; |
59 | again: | 60 | /* |
60 | if (unlikely(iov_iter_fault_in_readable(i, count))) | 61 | * Copy data from userspace to the current page |
61 | return -EFAULT; | 62 | * |
62 | 63 | * Disable pagefault to avoid recursive lock since | |
63 | /* Copy data from userspace to the current page */ | 64 | * the pages are already locked |
64 | copied = iov_iter_copy_from_user(page, i, offset, count); | 65 | */ |
66 | pagefault_disable(); | ||
67 | copied = iov_iter_copy_from_user_atomic(page, i, offset, count); | ||
68 | pagefault_enable(); | ||
65 | 69 | ||
66 | /* Flush processor's dcache for this page */ | 70 | /* Flush processor's dcache for this page */ |
67 | flush_dcache_page(page); | 71 | flush_dcache_page(page); |
68 | iov_iter_advance(i, copied); | 72 | iov_iter_advance(i, copied); |
69 | write_bytes -= copied; | 73 | write_bytes -= copied; |
74 | total_copied += copied; | ||
70 | 75 | ||
76 | /* Return to btrfs_file_aio_write to fault page */ | ||
71 | if (unlikely(copied == 0)) { | 77 | if (unlikely(copied == 0)) { |
72 | count = min_t(size_t, PAGE_CACHE_SIZE - offset, | 78 | break; |
73 | iov_iter_single_seg_count(i)); | ||
74 | goto again; | ||
75 | } | 79 | } |
76 | 80 | ||
77 | if (unlikely(copied < PAGE_CACHE_SIZE - offset)) { | 81 | if (unlikely(copied < PAGE_CACHE_SIZE - offset)) { |
@@ -81,7 +85,7 @@ again: | |||
81 | offset = 0; | 85 | offset = 0; |
82 | } | 86 | } |
83 | } | 87 | } |
84 | return 0; | 88 | return total_copied; |
85 | } | 89 | } |
86 | 90 | ||
87 | /* | 91 | /* |
@@ -854,6 +858,8 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
854 | unsigned long last_index; | 858 | unsigned long last_index; |
855 | int will_write; | 859 | int will_write; |
856 | int buffered = 0; | 860 | int buffered = 0; |
861 | int copied = 0; | ||
862 | int dirty_pages = 0; | ||
857 | 863 | ||
858 | will_write = ((file->f_flags & O_DSYNC) || IS_SYNC(inode) || | 864 | will_write = ((file->f_flags & O_DSYNC) || IS_SYNC(inode) || |
859 | (file->f_flags & O_DIRECT)); | 865 | (file->f_flags & O_DIRECT)); |
@@ -970,7 +976,17 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
970 | WARN_ON(num_pages > nrptrs); | 976 | WARN_ON(num_pages > nrptrs); |
971 | memset(pages, 0, sizeof(struct page *) * nrptrs); | 977 | memset(pages, 0, sizeof(struct page *) * nrptrs); |
972 | 978 | ||
973 | ret = btrfs_delalloc_reserve_space(inode, write_bytes); | 979 | /* |
980 | * Fault pages before locking them in prepare_pages | ||
981 | * to avoid recursive lock | ||
982 | */ | ||
983 | if (unlikely(iov_iter_fault_in_readable(&i, write_bytes))) { | ||
984 | ret = -EFAULT; | ||
985 | goto out; | ||
986 | } | ||
987 | |||
988 | ret = btrfs_delalloc_reserve_space(inode, | ||
989 | num_pages << PAGE_CACHE_SHIFT); | ||
974 | if (ret) | 990 | if (ret) |
975 | goto out; | 991 | goto out; |
976 | 992 | ||
@@ -978,37 +994,49 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
978 | pos, first_index, last_index, | 994 | pos, first_index, last_index, |
979 | write_bytes); | 995 | write_bytes); |
980 | if (ret) { | 996 | if (ret) { |
981 | btrfs_delalloc_release_space(inode, write_bytes); | 997 | btrfs_delalloc_release_space(inode, |
998 | num_pages << PAGE_CACHE_SHIFT); | ||
982 | goto out; | 999 | goto out; |
983 | } | 1000 | } |
984 | 1001 | ||
985 | ret = btrfs_copy_from_user(pos, num_pages, | 1002 | copied = btrfs_copy_from_user(pos, num_pages, |
986 | write_bytes, pages, &i); | 1003 | write_bytes, pages, &i); |
987 | if (ret == 0) { | 1004 | dirty_pages = (copied + PAGE_CACHE_SIZE - 1) >> |
1005 | PAGE_CACHE_SHIFT; | ||
1006 | |||
1007 | if (num_pages > dirty_pages) { | ||
1008 | if (copied > 0) | ||
1009 | atomic_inc( | ||
1010 | &BTRFS_I(inode)->outstanding_extents); | ||
1011 | btrfs_delalloc_release_space(inode, | ||
1012 | (num_pages - dirty_pages) << | ||
1013 | PAGE_CACHE_SHIFT); | ||
1014 | } | ||
1015 | |||
1016 | if (copied > 0) { | ||
988 | dirty_and_release_pages(NULL, root, file, pages, | 1017 | dirty_and_release_pages(NULL, root, file, pages, |
989 | num_pages, pos, write_bytes); | 1018 | dirty_pages, pos, copied); |
990 | } | 1019 | } |
991 | 1020 | ||
992 | btrfs_drop_pages(pages, num_pages); | 1021 | btrfs_drop_pages(pages, num_pages); |
993 | if (ret) { | ||
994 | btrfs_delalloc_release_space(inode, write_bytes); | ||
995 | goto out; | ||
996 | } | ||
997 | 1022 | ||
998 | if (will_write) { | 1023 | if (copied > 0) { |
999 | filemap_fdatawrite_range(inode->i_mapping, pos, | 1024 | if (will_write) { |
1000 | pos + write_bytes - 1); | 1025 | filemap_fdatawrite_range(inode->i_mapping, pos, |
1001 | } else { | 1026 | pos + copied - 1); |
1002 | balance_dirty_pages_ratelimited_nr(inode->i_mapping, | 1027 | } else { |
1003 | num_pages); | 1028 | balance_dirty_pages_ratelimited_nr( |
1004 | if (num_pages < | 1029 | inode->i_mapping, |
1005 | (root->leafsize >> PAGE_CACHE_SHIFT) + 1) | 1030 | dirty_pages); |
1006 | btrfs_btree_balance_dirty(root, 1); | 1031 | if (dirty_pages < |
1007 | btrfs_throttle(root); | 1032 | (root->leafsize >> PAGE_CACHE_SHIFT) + 1) |
1033 | btrfs_btree_balance_dirty(root, 1); | ||
1034 | btrfs_throttle(root); | ||
1035 | } | ||
1008 | } | 1036 | } |
1009 | 1037 | ||
1010 | pos += write_bytes; | 1038 | pos += copied; |
1011 | num_written += write_bytes; | 1039 | num_written += copied; |
1012 | 1040 | ||
1013 | cond_resched(); | 1041 | cond_resched(); |
1014 | } | 1042 | } |
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 22ee0dc2e6b8..60d684266959 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
@@ -290,7 +290,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, | |||
290 | (unsigned long long)BTRFS_I(inode)->generation, | 290 | (unsigned long long)BTRFS_I(inode)->generation, |
291 | (unsigned long long)generation, | 291 | (unsigned long long)generation, |
292 | (unsigned long long)block_group->key.objectid); | 292 | (unsigned long long)block_group->key.objectid); |
293 | goto out; | 293 | goto free_cache; |
294 | } | 294 | } |
295 | 295 | ||
296 | if (!num_entries) | 296 | if (!num_entries) |
@@ -524,6 +524,12 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
524 | return 0; | 524 | return 0; |
525 | } | 525 | } |
526 | 526 | ||
527 | node = rb_first(&block_group->free_space_offset); | ||
528 | if (!node) { | ||
529 | iput(inode); | ||
530 | return 0; | ||
531 | } | ||
532 | |||
527 | last_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT; | 533 | last_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT; |
528 | filemap_write_and_wait(inode->i_mapping); | 534 | filemap_write_and_wait(inode->i_mapping); |
529 | btrfs_wait_ordered_range(inode, inode->i_size & | 535 | btrfs_wait_ordered_range(inode, inode->i_size & |
@@ -543,10 +549,6 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
543 | */ | 549 | */ |
544 | first_page_offset = (sizeof(u32) * num_checksums) + sizeof(u64); | 550 | first_page_offset = (sizeof(u32) * num_checksums) + sizeof(u64); |
545 | 551 | ||
546 | node = rb_first(&block_group->free_space_offset); | ||
547 | if (!node) | ||
548 | goto out_free; | ||
549 | |||
550 | /* | 552 | /* |
551 | * Lock all pages first so we can lock the extent safely. | 553 | * Lock all pages first so we can lock the extent safely. |
552 | * | 554 | * |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 8039390bd6a6..72f31ecb5c90 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -495,7 +495,7 @@ again: | |||
495 | add_async_extent(async_cow, start, num_bytes, | 495 | add_async_extent(async_cow, start, num_bytes, |
496 | total_compressed, pages, nr_pages_ret); | 496 | total_compressed, pages, nr_pages_ret); |
497 | 497 | ||
498 | if (start + num_bytes < end && start + num_bytes < actual_end) { | 498 | if (start + num_bytes < end) { |
499 | start += num_bytes; | 499 | start += num_bytes; |
500 | pages = NULL; | 500 | pages = NULL; |
501 | cond_resched(); | 501 | cond_resched(); |
@@ -5712,9 +5712,9 @@ static void btrfs_end_dio_bio(struct bio *bio, int err) | |||
5712 | 5712 | ||
5713 | if (err) { | 5713 | if (err) { |
5714 | printk(KERN_ERR "btrfs direct IO failed ino %lu rw %lu " | 5714 | printk(KERN_ERR "btrfs direct IO failed ino %lu rw %lu " |
5715 | "disk_bytenr %lu len %u err no %d\n", | 5715 | "sector %#Lx len %u err no %d\n", |
5716 | dip->inode->i_ino, bio->bi_rw, bio->bi_sector, | 5716 | dip->inode->i_ino, bio->bi_rw, |
5717 | bio->bi_size, err); | 5717 | (unsigned long long)bio->bi_sector, bio->bi_size, err); |
5718 | dip->errors = 1; | 5718 | dip->errors = 1; |
5719 | 5719 | ||
5720 | /* | 5720 | /* |
@@ -5934,8 +5934,7 @@ free_ordered: | |||
5934 | */ | 5934 | */ |
5935 | if (write) { | 5935 | if (write) { |
5936 | struct btrfs_ordered_extent *ordered; | 5936 | struct btrfs_ordered_extent *ordered; |
5937 | ordered = btrfs_lookup_ordered_extent(inode, | 5937 | ordered = btrfs_lookup_ordered_extent(inode, file_offset); |
5938 | dip->logical_offset); | ||
5939 | if (!test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags) && | 5938 | if (!test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags) && |
5940 | !test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags)) | 5939 | !test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags)) |
5941 | btrfs_free_reserved_extent(root, ordered->start, | 5940 | btrfs_free_reserved_extent(root, ordered->start, |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index f1c9bb4079ed..f87552a1d7ea 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -947,23 +947,42 @@ out: | |||
947 | 947 | ||
948 | static noinline int btrfs_ioctl_snap_create(struct file *file, | 948 | static noinline int btrfs_ioctl_snap_create(struct file *file, |
949 | void __user *arg, int subvol, | 949 | void __user *arg, int subvol, |
950 | int async) | 950 | int v2) |
951 | { | 951 | { |
952 | struct btrfs_ioctl_vol_args *vol_args = NULL; | 952 | struct btrfs_ioctl_vol_args *vol_args = NULL; |
953 | struct btrfs_ioctl_async_vol_args *async_vol_args = NULL; | 953 | struct btrfs_ioctl_vol_args_v2 *vol_args_v2 = NULL; |
954 | char *name; | 954 | char *name; |
955 | u64 fd; | 955 | u64 fd; |
956 | u64 transid = 0; | ||
957 | int ret; | 956 | int ret; |
958 | 957 | ||
959 | if (async) { | 958 | if (v2) { |
960 | async_vol_args = memdup_user(arg, sizeof(*async_vol_args)); | 959 | u64 transid = 0; |
961 | if (IS_ERR(async_vol_args)) | 960 | u64 *ptr = NULL; |
962 | return PTR_ERR(async_vol_args); | ||
963 | 961 | ||
964 | name = async_vol_args->name; | 962 | vol_args_v2 = memdup_user(arg, sizeof(*vol_args_v2)); |
965 | fd = async_vol_args->fd; | 963 | if (IS_ERR(vol_args_v2)) |
966 | async_vol_args->name[BTRFS_SNAPSHOT_NAME_MAX] = '\0'; | 964 | return PTR_ERR(vol_args_v2); |
965 | |||
966 | if (vol_args_v2->flags & ~BTRFS_SUBVOL_CREATE_ASYNC) { | ||
967 | ret = -EINVAL; | ||
968 | goto out; | ||
969 | } | ||
970 | |||
971 | name = vol_args_v2->name; | ||
972 | fd = vol_args_v2->fd; | ||
973 | vol_args_v2->name[BTRFS_SUBVOL_NAME_MAX] = '\0'; | ||
974 | |||
975 | if (vol_args_v2->flags & BTRFS_SUBVOL_CREATE_ASYNC) | ||
976 | ptr = &transid; | ||
977 | |||
978 | ret = btrfs_ioctl_snap_create_transid(file, name, fd, | ||
979 | subvol, ptr); | ||
980 | |||
981 | if (ret == 0 && ptr && | ||
982 | copy_to_user(arg + | ||
983 | offsetof(struct btrfs_ioctl_vol_args_v2, | ||
984 | transid), ptr, sizeof(*ptr))) | ||
985 | ret = -EFAULT; | ||
967 | } else { | 986 | } else { |
968 | vol_args = memdup_user(arg, sizeof(*vol_args)); | 987 | vol_args = memdup_user(arg, sizeof(*vol_args)); |
969 | if (IS_ERR(vol_args)) | 988 | if (IS_ERR(vol_args)) |
@@ -971,20 +990,13 @@ static noinline int btrfs_ioctl_snap_create(struct file *file, | |||
971 | name = vol_args->name; | 990 | name = vol_args->name; |
972 | fd = vol_args->fd; | 991 | fd = vol_args->fd; |
973 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; | 992 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; |
974 | } | ||
975 | |||
976 | ret = btrfs_ioctl_snap_create_transid(file, name, fd, | ||
977 | subvol, &transid); | ||
978 | 993 | ||
979 | if (!ret && async) { | 994 | ret = btrfs_ioctl_snap_create_transid(file, name, fd, |
980 | if (copy_to_user(arg + | 995 | subvol, NULL); |
981 | offsetof(struct btrfs_ioctl_async_vol_args, | ||
982 | transid), &transid, sizeof(transid))) | ||
983 | return -EFAULT; | ||
984 | } | 996 | } |
985 | 997 | out: | |
986 | kfree(vol_args); | 998 | kfree(vol_args); |
987 | kfree(async_vol_args); | 999 | kfree(vol_args_v2); |
988 | 1000 | ||
989 | return ret; | 1001 | return ret; |
990 | } | 1002 | } |
@@ -2246,7 +2258,7 @@ long btrfs_ioctl(struct file *file, unsigned int | |||
2246 | return btrfs_ioctl_getversion(file, argp); | 2258 | return btrfs_ioctl_getversion(file, argp); |
2247 | case BTRFS_IOC_SNAP_CREATE: | 2259 | case BTRFS_IOC_SNAP_CREATE: |
2248 | return btrfs_ioctl_snap_create(file, argp, 0, 0); | 2260 | return btrfs_ioctl_snap_create(file, argp, 0, 0); |
2249 | case BTRFS_IOC_SNAP_CREATE_ASYNC: | 2261 | case BTRFS_IOC_SNAP_CREATE_V2: |
2250 | return btrfs_ioctl_snap_create(file, argp, 0, 1); | 2262 | return btrfs_ioctl_snap_create(file, argp, 0, 1); |
2251 | case BTRFS_IOC_SUBVOL_CREATE: | 2263 | case BTRFS_IOC_SUBVOL_CREATE: |
2252 | return btrfs_ioctl_snap_create(file, argp, 1, 0); | 2264 | return btrfs_ioctl_snap_create(file, argp, 1, 0); |
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index 17c99ebdf960..c344d12c646b 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h | |||
@@ -30,11 +30,15 @@ struct btrfs_ioctl_vol_args { | |||
30 | char name[BTRFS_PATH_NAME_MAX + 1]; | 30 | char name[BTRFS_PATH_NAME_MAX + 1]; |
31 | }; | 31 | }; |
32 | 32 | ||
33 | #define BTRFS_SNAPSHOT_NAME_MAX 4079 | 33 | #define BTRFS_SUBVOL_CREATE_ASYNC (1ULL << 0) |
34 | struct btrfs_ioctl_async_vol_args { | 34 | |
35 | #define BTRFS_SUBVOL_NAME_MAX 4039 | ||
36 | struct btrfs_ioctl_vol_args_v2 { | ||
35 | __s64 fd; | 37 | __s64 fd; |
36 | __u64 transid; | 38 | __u64 transid; |
37 | char name[BTRFS_SNAPSHOT_NAME_MAX + 1]; | 39 | __u64 flags; |
40 | __u64 unused[4]; | ||
41 | char name[BTRFS_SUBVOL_NAME_MAX + 1]; | ||
38 | }; | 42 | }; |
39 | 43 | ||
40 | #define BTRFS_INO_LOOKUP_PATH_MAX 4080 | 44 | #define BTRFS_INO_LOOKUP_PATH_MAX 4080 |
@@ -187,6 +191,6 @@ struct btrfs_ioctl_space_args { | |||
187 | struct btrfs_ioctl_space_args) | 191 | struct btrfs_ioctl_space_args) |
188 | #define BTRFS_IOC_START_SYNC _IOR(BTRFS_IOCTL_MAGIC, 24, __u64) | 192 | #define BTRFS_IOC_START_SYNC _IOR(BTRFS_IOCTL_MAGIC, 24, __u64) |
189 | #define BTRFS_IOC_WAIT_SYNC _IOW(BTRFS_IOCTL_MAGIC, 22, __u64) | 193 | #define BTRFS_IOC_WAIT_SYNC _IOW(BTRFS_IOCTL_MAGIC, 22, __u64) |
190 | #define BTRFS_IOC_SNAP_CREATE_ASYNC _IOW(BTRFS_IOCTL_MAGIC, 23, \ | 194 | #define BTRFS_IOC_SNAP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 23, \ |
191 | struct btrfs_ioctl_async_vol_args) | 195 | struct btrfs_ioctl_vol_args_v2) |
192 | #endif | 196 | #endif |
diff --git a/fs/btrfs/orphan.c b/fs/btrfs/orphan.c index 79cba5fbc28e..f8be250963a0 100644 --- a/fs/btrfs/orphan.c +++ b/fs/btrfs/orphan.c | |||
@@ -56,8 +56,12 @@ int btrfs_del_orphan_item(struct btrfs_trans_handle *trans, | |||
56 | return -ENOMEM; | 56 | return -ENOMEM; |
57 | 57 | ||
58 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); | 58 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); |
59 | if (ret) | 59 | if (ret < 0) |
60 | goto out; | 60 | goto out; |
61 | if (ret) { | ||
62 | ret = -ENOENT; | ||
63 | goto out; | ||
64 | } | ||
61 | 65 | ||
62 | ret = btrfs_del_item(trans, root, path); | 66 | ret = btrfs_del_item(trans, root, path); |
63 | 67 | ||
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index dbb51ea7a13c..883c6fa1367e 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -685,9 +685,9 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
685 | mutex_unlock(&root->d_inode->i_mutex); | 685 | mutex_unlock(&root->d_inode->i_mutex); |
686 | 686 | ||
687 | if (IS_ERR(new_root)) { | 687 | if (IS_ERR(new_root)) { |
688 | dput(root); | ||
688 | deactivate_locked_super(s); | 689 | deactivate_locked_super(s); |
689 | error = PTR_ERR(new_root); | 690 | error = PTR_ERR(new_root); |
690 | dput(root); | ||
691 | goto error_free_subvol_name; | 691 | goto error_free_subvol_name; |
692 | } | 692 | } |
693 | if (!new_root->d_inode) { | 693 | if (!new_root->d_inode) { |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index cc04dc1445d6..6b9884507837 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -412,12 +412,16 @@ static noinline int device_list_add(const char *path, | |||
412 | 412 | ||
413 | device->fs_devices = fs_devices; | 413 | device->fs_devices = fs_devices; |
414 | fs_devices->num_devices++; | 414 | fs_devices->num_devices++; |
415 | } else if (strcmp(device->name, path)) { | 415 | } else if (!device->name || strcmp(device->name, path)) { |
416 | name = kstrdup(path, GFP_NOFS); | 416 | name = kstrdup(path, GFP_NOFS); |
417 | if (!name) | 417 | if (!name) |
418 | return -ENOMEM; | 418 | return -ENOMEM; |
419 | kfree(device->name); | 419 | kfree(device->name); |
420 | device->name = name; | 420 | device->name = name; |
421 | if (device->missing) { | ||
422 | fs_devices->missing_devices--; | ||
423 | device->missing = 0; | ||
424 | } | ||
421 | } | 425 | } |
422 | 426 | ||
423 | if (found_transid > fs_devices->latest_trans) { | 427 | if (found_transid > fs_devices->latest_trans) { |
@@ -1236,6 +1240,9 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
1236 | 1240 | ||
1237 | device->fs_devices->num_devices--; | 1241 | device->fs_devices->num_devices--; |
1238 | 1242 | ||
1243 | if (device->missing) | ||
1244 | root->fs_info->fs_devices->missing_devices--; | ||
1245 | |||
1239 | next_device = list_entry(root->fs_info->fs_devices->devices.next, | 1246 | next_device = list_entry(root->fs_info->fs_devices->devices.next, |
1240 | struct btrfs_device, dev_list); | 1247 | struct btrfs_device, dev_list); |
1241 | if (device->bdev == root->fs_info->sb->s_bdev) | 1248 | if (device->bdev == root->fs_info->sb->s_bdev) |
@@ -3080,7 +3087,9 @@ static struct btrfs_device *add_missing_dev(struct btrfs_root *root, | |||
3080 | device->devid = devid; | 3087 | device->devid = devid; |
3081 | device->work.func = pending_bios_fn; | 3088 | device->work.func = pending_bios_fn; |
3082 | device->fs_devices = fs_devices; | 3089 | device->fs_devices = fs_devices; |
3090 | device->missing = 1; | ||
3083 | fs_devices->num_devices++; | 3091 | fs_devices->num_devices++; |
3092 | fs_devices->missing_devices++; | ||
3084 | spin_lock_init(&device->io_lock); | 3093 | spin_lock_init(&device->io_lock); |
3085 | INIT_LIST_HEAD(&device->dev_alloc_list); | 3094 | INIT_LIST_HEAD(&device->dev_alloc_list); |
3086 | memcpy(device->uuid, dev_uuid, BTRFS_UUID_SIZE); | 3095 | memcpy(device->uuid, dev_uuid, BTRFS_UUID_SIZE); |
@@ -3278,6 +3287,15 @@ static int read_one_dev(struct btrfs_root *root, | |||
3278 | device = add_missing_dev(root, devid, dev_uuid); | 3287 | device = add_missing_dev(root, devid, dev_uuid); |
3279 | if (!device) | 3288 | if (!device) |
3280 | return -ENOMEM; | 3289 | return -ENOMEM; |
3290 | } else if (!device->missing) { | ||
3291 | /* | ||
3292 | * this happens when a device that was properly setup | ||
3293 | * in the device info lists suddenly goes bad. | ||
3294 | * device->bdev is NULL, and so we have to set | ||
3295 | * device->missing to one here | ||
3296 | */ | ||
3297 | root->fs_info->fs_devices->missing_devices++; | ||
3298 | device->missing = 1; | ||
3281 | } | 3299 | } |
3282 | } | 3300 | } |
3283 | 3301 | ||
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 2b638b6e4eea..2740db49eb04 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h | |||
@@ -44,6 +44,7 @@ struct btrfs_device { | |||
44 | 44 | ||
45 | int writeable; | 45 | int writeable; |
46 | int in_fs_metadata; | 46 | int in_fs_metadata; |
47 | int missing; | ||
47 | 48 | ||
48 | spinlock_t io_lock; | 49 | spinlock_t io_lock; |
49 | 50 | ||
@@ -93,6 +94,7 @@ struct btrfs_fs_devices { | |||
93 | u64 num_devices; | 94 | u64 num_devices; |
94 | u64 open_devices; | 95 | u64 open_devices; |
95 | u64 rw_devices; | 96 | u64 rw_devices; |
97 | u64 missing_devices; | ||
96 | u64 total_rw_bytes; | 98 | u64 total_rw_bytes; |
97 | struct block_device *latest_bdev; | 99 | struct block_device *latest_bdev; |
98 | 100 | ||
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 7d447af84ec4..d902948a90d8 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -40,7 +40,8 @@ int ceph_init_dentry(struct dentry *dentry) | |||
40 | if (dentry->d_fsdata) | 40 | if (dentry->d_fsdata) |
41 | return 0; | 41 | return 0; |
42 | 42 | ||
43 | if (ceph_snap(dentry->d_parent->d_inode) == CEPH_NOSNAP) | 43 | if (dentry->d_parent == NULL || /* nfs fh_to_dentry */ |
44 | ceph_snap(dentry->d_parent->d_inode) == CEPH_NOSNAP) | ||
44 | dentry->d_op = &ceph_dentry_ops; | 45 | dentry->d_op = &ceph_dentry_ops; |
45 | else if (ceph_snap(dentry->d_parent->d_inode) == CEPH_SNAPDIR) | 46 | else if (ceph_snap(dentry->d_parent->d_inode) == CEPH_SNAPDIR) |
46 | dentry->d_op = &ceph_snapdir_dentry_ops; | 47 | dentry->d_op = &ceph_snapdir_dentry_ops; |
@@ -114,8 +115,8 @@ static int __dcache_readdir(struct file *filp, | |||
114 | spin_lock(&dcache_lock); | 115 | spin_lock(&dcache_lock); |
115 | 116 | ||
116 | /* start at beginning? */ | 117 | /* start at beginning? */ |
117 | if (filp->f_pos == 2 || (last && | 118 | if (filp->f_pos == 2 || last == NULL || |
118 | filp->f_pos < ceph_dentry(last)->offset)) { | 119 | filp->f_pos < ceph_dentry(last)->offset) { |
119 | if (list_empty(&parent->d_subdirs)) | 120 | if (list_empty(&parent->d_subdirs)) |
120 | goto out_unlock; | 121 | goto out_unlock; |
121 | p = parent->d_subdirs.prev; | 122 | p = parent->d_subdirs.prev; |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 8d79b8912e31..7d0e4a82d898 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -282,7 +282,8 @@ int ceph_release(struct inode *inode, struct file *file) | |||
282 | static int striped_read(struct inode *inode, | 282 | static int striped_read(struct inode *inode, |
283 | u64 off, u64 len, | 283 | u64 off, u64 len, |
284 | struct page **pages, int num_pages, | 284 | struct page **pages, int num_pages, |
285 | int *checkeof, bool align_to_pages) | 285 | int *checkeof, bool align_to_pages, |
286 | unsigned long buf_align) | ||
286 | { | 287 | { |
287 | struct ceph_fs_client *fsc = ceph_inode_to_client(inode); | 288 | struct ceph_fs_client *fsc = ceph_inode_to_client(inode); |
288 | struct ceph_inode_info *ci = ceph_inode(inode); | 289 | struct ceph_inode_info *ci = ceph_inode(inode); |
@@ -307,7 +308,7 @@ static int striped_read(struct inode *inode, | |||
307 | 308 | ||
308 | more: | 309 | more: |
309 | if (align_to_pages) | 310 | if (align_to_pages) |
310 | page_align = (pos - io_align) & ~PAGE_MASK; | 311 | page_align = (pos - io_align + buf_align) & ~PAGE_MASK; |
311 | else | 312 | else |
312 | page_align = pos & ~PAGE_MASK; | 313 | page_align = pos & ~PAGE_MASK; |
313 | this_len = left; | 314 | this_len = left; |
@@ -376,16 +377,18 @@ static ssize_t ceph_sync_read(struct file *file, char __user *data, | |||
376 | struct inode *inode = file->f_dentry->d_inode; | 377 | struct inode *inode = file->f_dentry->d_inode; |
377 | struct page **pages; | 378 | struct page **pages; |
378 | u64 off = *poff; | 379 | u64 off = *poff; |
379 | int num_pages = calc_pages_for(off, len); | 380 | int num_pages, ret; |
380 | int ret; | ||
381 | 381 | ||
382 | dout("sync_read on file %p %llu~%u %s\n", file, off, len, | 382 | dout("sync_read on file %p %llu~%u %s\n", file, off, len, |
383 | (file->f_flags & O_DIRECT) ? "O_DIRECT" : ""); | 383 | (file->f_flags & O_DIRECT) ? "O_DIRECT" : ""); |
384 | 384 | ||
385 | if (file->f_flags & O_DIRECT) | 385 | if (file->f_flags & O_DIRECT) { |
386 | pages = ceph_get_direct_page_vector(data, num_pages); | 386 | num_pages = calc_pages_for((unsigned long)data, len); |
387 | else | 387 | pages = ceph_get_direct_page_vector(data, num_pages, true); |
388 | } else { | ||
389 | num_pages = calc_pages_for(off, len); | ||
388 | pages = ceph_alloc_page_vector(num_pages, GFP_NOFS); | 390 | pages = ceph_alloc_page_vector(num_pages, GFP_NOFS); |
391 | } | ||
389 | if (IS_ERR(pages)) | 392 | if (IS_ERR(pages)) |
390 | return PTR_ERR(pages); | 393 | return PTR_ERR(pages); |
391 | 394 | ||
@@ -400,7 +403,8 @@ static ssize_t ceph_sync_read(struct file *file, char __user *data, | |||
400 | goto done; | 403 | goto done; |
401 | 404 | ||
402 | ret = striped_read(inode, off, len, pages, num_pages, checkeof, | 405 | ret = striped_read(inode, off, len, pages, num_pages, checkeof, |
403 | file->f_flags & O_DIRECT); | 406 | file->f_flags & O_DIRECT, |
407 | (unsigned long)data & ~PAGE_MASK); | ||
404 | 408 | ||
405 | if (ret >= 0 && (file->f_flags & O_DIRECT) == 0) | 409 | if (ret >= 0 && (file->f_flags & O_DIRECT) == 0) |
406 | ret = ceph_copy_page_vector_to_user(pages, data, off, ret); | 410 | ret = ceph_copy_page_vector_to_user(pages, data, off, ret); |
@@ -409,7 +413,7 @@ static ssize_t ceph_sync_read(struct file *file, char __user *data, | |||
409 | 413 | ||
410 | done: | 414 | done: |
411 | if (file->f_flags & O_DIRECT) | 415 | if (file->f_flags & O_DIRECT) |
412 | ceph_put_page_vector(pages, num_pages); | 416 | ceph_put_page_vector(pages, num_pages, true); |
413 | else | 417 | else |
414 | ceph_release_page_vector(pages, num_pages); | 418 | ceph_release_page_vector(pages, num_pages); |
415 | dout("sync_read result %d\n", ret); | 419 | dout("sync_read result %d\n", ret); |
@@ -456,6 +460,7 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data, | |||
456 | int do_sync = 0; | 460 | int do_sync = 0; |
457 | int check_caps = 0; | 461 | int check_caps = 0; |
458 | int page_align, io_align; | 462 | int page_align, io_align; |
463 | unsigned long buf_align; | ||
459 | int ret; | 464 | int ret; |
460 | struct timespec mtime = CURRENT_TIME; | 465 | struct timespec mtime = CURRENT_TIME; |
461 | 466 | ||
@@ -471,6 +476,7 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data, | |||
471 | pos = *offset; | 476 | pos = *offset; |
472 | 477 | ||
473 | io_align = pos & ~PAGE_MASK; | 478 | io_align = pos & ~PAGE_MASK; |
479 | buf_align = (unsigned long)data & ~PAGE_MASK; | ||
474 | 480 | ||
475 | ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + left); | 481 | ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + left); |
476 | if (ret < 0) | 482 | if (ret < 0) |
@@ -496,12 +502,15 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data, | |||
496 | */ | 502 | */ |
497 | more: | 503 | more: |
498 | len = left; | 504 | len = left; |
499 | if (file->f_flags & O_DIRECT) | 505 | if (file->f_flags & O_DIRECT) { |
500 | /* write from beginning of first page, regardless of | 506 | /* write from beginning of first page, regardless of |
501 | io alignment */ | 507 | io alignment */ |
502 | page_align = (pos - io_align) & ~PAGE_MASK; | 508 | page_align = (pos - io_align + buf_align) & ~PAGE_MASK; |
503 | else | 509 | num_pages = calc_pages_for((unsigned long)data, len); |
510 | } else { | ||
504 | page_align = pos & ~PAGE_MASK; | 511 | page_align = pos & ~PAGE_MASK; |
512 | num_pages = calc_pages_for(pos, len); | ||
513 | } | ||
505 | req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout, | 514 | req = ceph_osdc_new_request(&fsc->client->osdc, &ci->i_layout, |
506 | ceph_vino(inode), pos, &len, | 515 | ceph_vino(inode), pos, &len, |
507 | CEPH_OSD_OP_WRITE, flags, | 516 | CEPH_OSD_OP_WRITE, flags, |
@@ -512,10 +521,8 @@ more: | |||
512 | if (!req) | 521 | if (!req) |
513 | return -ENOMEM; | 522 | return -ENOMEM; |
514 | 523 | ||
515 | num_pages = calc_pages_for(pos, len); | ||
516 | |||
517 | if (file->f_flags & O_DIRECT) { | 524 | if (file->f_flags & O_DIRECT) { |
518 | pages = ceph_get_direct_page_vector(data, num_pages); | 525 | pages = ceph_get_direct_page_vector(data, num_pages, false); |
519 | if (IS_ERR(pages)) { | 526 | if (IS_ERR(pages)) { |
520 | ret = PTR_ERR(pages); | 527 | ret = PTR_ERR(pages); |
521 | goto out; | 528 | goto out; |
@@ -565,7 +572,7 @@ more: | |||
565 | } | 572 | } |
566 | 573 | ||
567 | if (file->f_flags & O_DIRECT) | 574 | if (file->f_flags & O_DIRECT) |
568 | ceph_put_page_vector(pages, num_pages); | 575 | ceph_put_page_vector(pages, num_pages, false); |
569 | else if (file->f_flags & O_SYNC) | 576 | else if (file->f_flags & O_SYNC) |
570 | ceph_release_page_vector(pages, num_pages); | 577 | ceph_release_page_vector(pages, num_pages); |
571 | 578 | ||
diff --git a/fs/ceph/ioctl.h b/fs/ceph/ioctl.h index a6ce54e94eb5..52e8fd74d450 100644 --- a/fs/ceph/ioctl.h +++ b/fs/ceph/ioctl.h | |||
@@ -4,7 +4,7 @@ | |||
4 | #include <linux/ioctl.h> | 4 | #include <linux/ioctl.h> |
5 | #include <linux/types.h> | 5 | #include <linux/types.h> |
6 | 6 | ||
7 | #define CEPH_IOCTL_MAGIC 0x98 | 7 | #define CEPH_IOCTL_MAGIC 0x97 |
8 | 8 | ||
9 | /* just use u64 to align sanely on all archs */ | 9 | /* just use u64 to align sanely on all archs */ |
10 | struct ceph_ioctl_layout { | 10 | struct ceph_ioctl_layout { |
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c index 40abde93c345..476b329867d4 100644 --- a/fs/ceph/locks.c +++ b/fs/ceph/locks.c | |||
@@ -11,40 +11,68 @@ | |||
11 | * Implement fcntl and flock locking functions. | 11 | * Implement fcntl and flock locking functions. |
12 | */ | 12 | */ |
13 | static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file, | 13 | static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file, |
14 | u64 pid, u64 pid_ns, | 14 | int cmd, u8 wait, struct file_lock *fl) |
15 | int cmd, u64 start, u64 length, u8 wait) | ||
16 | { | 15 | { |
17 | struct inode *inode = file->f_dentry->d_inode; | 16 | struct inode *inode = file->f_dentry->d_inode; |
18 | struct ceph_mds_client *mdsc = | 17 | struct ceph_mds_client *mdsc = |
19 | ceph_sb_to_client(inode->i_sb)->mdsc; | 18 | ceph_sb_to_client(inode->i_sb)->mdsc; |
20 | struct ceph_mds_request *req; | 19 | struct ceph_mds_request *req; |
21 | int err; | 20 | int err; |
21 | u64 length = 0; | ||
22 | 22 | ||
23 | req = ceph_mdsc_create_request(mdsc, operation, USE_AUTH_MDS); | 23 | req = ceph_mdsc_create_request(mdsc, operation, USE_AUTH_MDS); |
24 | if (IS_ERR(req)) | 24 | if (IS_ERR(req)) |
25 | return PTR_ERR(req); | 25 | return PTR_ERR(req); |
26 | req->r_inode = igrab(inode); | 26 | req->r_inode = igrab(inode); |
27 | 27 | ||
28 | /* mds requires start and length rather than start and end */ | ||
29 | if (LLONG_MAX == fl->fl_end) | ||
30 | length = 0; | ||
31 | else | ||
32 | length = fl->fl_end - fl->fl_start + 1; | ||
33 | |||
28 | dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " | 34 | dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " |
29 | "length: %llu, wait: %d, type`: %d", (int)lock_type, | 35 | "length: %llu, wait: %d, type`: %d", (int)lock_type, |
30 | (int)operation, pid, start, length, wait, cmd); | 36 | (int)operation, (u64)fl->fl_pid, fl->fl_start, |
37 | length, wait, fl->fl_type); | ||
38 | |||
31 | 39 | ||
32 | req->r_args.filelock_change.rule = lock_type; | 40 | req->r_args.filelock_change.rule = lock_type; |
33 | req->r_args.filelock_change.type = cmd; | 41 | req->r_args.filelock_change.type = cmd; |
34 | req->r_args.filelock_change.pid = cpu_to_le64(pid); | 42 | req->r_args.filelock_change.pid = cpu_to_le64((u64)fl->fl_pid); |
35 | /* This should be adjusted, but I'm not sure if | 43 | /* This should be adjusted, but I'm not sure if |
36 | namespaces actually get id numbers*/ | 44 | namespaces actually get id numbers*/ |
37 | req->r_args.filelock_change.pid_namespace = | 45 | req->r_args.filelock_change.pid_namespace = |
38 | cpu_to_le64((u64)pid_ns); | 46 | cpu_to_le64((u64)(unsigned long)fl->fl_nspid); |
39 | req->r_args.filelock_change.start = cpu_to_le64(start); | 47 | req->r_args.filelock_change.start = cpu_to_le64(fl->fl_start); |
40 | req->r_args.filelock_change.length = cpu_to_le64(length); | 48 | req->r_args.filelock_change.length = cpu_to_le64(length); |
41 | req->r_args.filelock_change.wait = wait; | 49 | req->r_args.filelock_change.wait = wait; |
42 | 50 | ||
43 | err = ceph_mdsc_do_request(mdsc, inode, req); | 51 | err = ceph_mdsc_do_request(mdsc, inode, req); |
52 | |||
53 | if ( operation == CEPH_MDS_OP_GETFILELOCK){ | ||
54 | fl->fl_pid = le64_to_cpu(req->r_reply_info.filelock_reply->pid); | ||
55 | if (CEPH_LOCK_SHARED == req->r_reply_info.filelock_reply->type) | ||
56 | fl->fl_type = F_RDLCK; | ||
57 | else if (CEPH_LOCK_EXCL == req->r_reply_info.filelock_reply->type) | ||
58 | fl->fl_type = F_WRLCK; | ||
59 | else | ||
60 | fl->fl_type = F_UNLCK; | ||
61 | |||
62 | fl->fl_start = le64_to_cpu(req->r_reply_info.filelock_reply->start); | ||
63 | length = le64_to_cpu(req->r_reply_info.filelock_reply->start) + | ||
64 | le64_to_cpu(req->r_reply_info.filelock_reply->length); | ||
65 | if (length >= 1) | ||
66 | fl->fl_end = length -1; | ||
67 | else | ||
68 | fl->fl_end = 0; | ||
69 | |||
70 | } | ||
44 | ceph_mdsc_put_request(req); | 71 | ceph_mdsc_put_request(req); |
45 | dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " | 72 | dout("ceph_lock_message: rule: %d, op: %d, pid: %llu, start: %llu, " |
46 | "length: %llu, wait: %d, type`: %d err code %d", (int)lock_type, | 73 | "length: %llu, wait: %d, type`: %d, err code %d", (int)lock_type, |
47 | (int)operation, pid, start, length, wait, cmd, err); | 74 | (int)operation, (u64)fl->fl_pid, fl->fl_start, |
75 | length, wait, fl->fl_type, err); | ||
48 | return err; | 76 | return err; |
49 | } | 77 | } |
50 | 78 | ||
@@ -54,7 +82,6 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file, | |||
54 | */ | 82 | */ |
55 | int ceph_lock(struct file *file, int cmd, struct file_lock *fl) | 83 | int ceph_lock(struct file *file, int cmd, struct file_lock *fl) |
56 | { | 84 | { |
57 | u64 length; | ||
58 | u8 lock_cmd; | 85 | u8 lock_cmd; |
59 | int err; | 86 | int err; |
60 | u8 wait = 0; | 87 | u8 wait = 0; |
@@ -76,29 +103,20 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl) | |||
76 | else | 103 | else |
77 | lock_cmd = CEPH_LOCK_UNLOCK; | 104 | lock_cmd = CEPH_LOCK_UNLOCK; |
78 | 105 | ||
79 | if (LLONG_MAX == fl->fl_end) | 106 | err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file, lock_cmd, wait, fl); |
80 | length = 0; | ||
81 | else | ||
82 | length = fl->fl_end - fl->fl_start + 1; | ||
83 | |||
84 | err = ceph_lock_message(CEPH_LOCK_FCNTL, op, file, | ||
85 | (u64)fl->fl_pid, | ||
86 | (u64)(unsigned long)fl->fl_nspid, | ||
87 | lock_cmd, fl->fl_start, | ||
88 | length, wait); | ||
89 | if (!err) { | 107 | if (!err) { |
90 | dout("mds locked, locking locally"); | 108 | if ( op != CEPH_MDS_OP_GETFILELOCK ){ |
91 | err = posix_lock_file(file, fl, NULL); | 109 | dout("mds locked, locking locally"); |
92 | if (err && (CEPH_MDS_OP_SETFILELOCK == op)) { | 110 | err = posix_lock_file(file, fl, NULL); |
93 | /* undo! This should only happen if the kernel detects | 111 | if (err && (CEPH_MDS_OP_SETFILELOCK == op)) { |
94 | * local deadlock. */ | 112 | /* undo! This should only happen if the kernel detects |
95 | ceph_lock_message(CEPH_LOCK_FCNTL, op, file, | 113 | * local deadlock. */ |
96 | (u64)fl->fl_pid, | 114 | ceph_lock_message(CEPH_LOCK_FCNTL, op, file, |
97 | (u64)(unsigned long)fl->fl_nspid, | 115 | CEPH_LOCK_UNLOCK, 0, fl); |
98 | CEPH_LOCK_UNLOCK, fl->fl_start, | 116 | dout("got %d on posix_lock_file, undid lock", err); |
99 | length, 0); | 117 | } |
100 | dout("got %d on posix_lock_file, undid lock", err); | ||
101 | } | 118 | } |
119 | |||
102 | } else { | 120 | } else { |
103 | dout("mds returned error code %d", err); | 121 | dout("mds returned error code %d", err); |
104 | } | 122 | } |
@@ -107,7 +125,6 @@ int ceph_lock(struct file *file, int cmd, struct file_lock *fl) | |||
107 | 125 | ||
108 | int ceph_flock(struct file *file, int cmd, struct file_lock *fl) | 126 | int ceph_flock(struct file *file, int cmd, struct file_lock *fl) |
109 | { | 127 | { |
110 | u64 length; | ||
111 | u8 lock_cmd; | 128 | u8 lock_cmd; |
112 | int err; | 129 | int err; |
113 | u8 wait = 1; | 130 | u8 wait = 1; |
@@ -127,26 +144,15 @@ int ceph_flock(struct file *file, int cmd, struct file_lock *fl) | |||
127 | lock_cmd = CEPH_LOCK_EXCL; | 144 | lock_cmd = CEPH_LOCK_EXCL; |
128 | else | 145 | else |
129 | lock_cmd = CEPH_LOCK_UNLOCK; | 146 | lock_cmd = CEPH_LOCK_UNLOCK; |
130 | /* mds requires start and length rather than start and end */ | ||
131 | if (LLONG_MAX == fl->fl_end) | ||
132 | length = 0; | ||
133 | else | ||
134 | length = fl->fl_end - fl->fl_start + 1; | ||
135 | 147 | ||
136 | err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK, | 148 | err = ceph_lock_message(CEPH_LOCK_FLOCK, CEPH_MDS_OP_SETFILELOCK, |
137 | file, (u64)fl->fl_pid, | 149 | file, lock_cmd, wait, fl); |
138 | (u64)(unsigned long)fl->fl_nspid, | ||
139 | lock_cmd, fl->fl_start, | ||
140 | length, wait); | ||
141 | if (!err) { | 150 | if (!err) { |
142 | err = flock_lock_file_wait(file, fl); | 151 | err = flock_lock_file_wait(file, fl); |
143 | if (err) { | 152 | if (err) { |
144 | ceph_lock_message(CEPH_LOCK_FLOCK, | 153 | ceph_lock_message(CEPH_LOCK_FLOCK, |
145 | CEPH_MDS_OP_SETFILELOCK, | 154 | CEPH_MDS_OP_SETFILELOCK, |
146 | file, (u64)fl->fl_pid, | 155 | file, CEPH_LOCK_UNLOCK, 0, fl); |
147 | (u64)(unsigned long)fl->fl_nspid, | ||
148 | CEPH_LOCK_UNLOCK, fl->fl_start, | ||
149 | length, 0); | ||
150 | dout("got %d on flock_lock_file_wait, undid lock", err); | 156 | dout("got %d on flock_lock_file_wait, undid lock", err); |
151 | } | 157 | } |
152 | } else { | 158 | } else { |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 098b18508479..38800eaa81d0 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -202,6 +202,38 @@ out_bad: | |||
202 | } | 202 | } |
203 | 203 | ||
204 | /* | 204 | /* |
205 | * parse fcntl F_GETLK results | ||
206 | */ | ||
207 | static int parse_reply_info_filelock(void **p, void *end, | ||
208 | struct ceph_mds_reply_info_parsed *info) | ||
209 | { | ||
210 | if (*p + sizeof(*info->filelock_reply) > end) | ||
211 | goto bad; | ||
212 | |||
213 | info->filelock_reply = *p; | ||
214 | *p += sizeof(*info->filelock_reply); | ||
215 | |||
216 | if (unlikely(*p != end)) | ||
217 | goto bad; | ||
218 | return 0; | ||
219 | |||
220 | bad: | ||
221 | return -EIO; | ||
222 | } | ||
223 | |||
224 | /* | ||
225 | * parse extra results | ||
226 | */ | ||
227 | static int parse_reply_info_extra(void **p, void *end, | ||
228 | struct ceph_mds_reply_info_parsed *info) | ||
229 | { | ||
230 | if (info->head->op == CEPH_MDS_OP_GETFILELOCK) | ||
231 | return parse_reply_info_filelock(p, end, info); | ||
232 | else | ||
233 | return parse_reply_info_dir(p, end, info); | ||
234 | } | ||
235 | |||
236 | /* | ||
205 | * parse entire mds reply | 237 | * parse entire mds reply |
206 | */ | 238 | */ |
207 | static int parse_reply_info(struct ceph_msg *msg, | 239 | static int parse_reply_info(struct ceph_msg *msg, |
@@ -223,10 +255,10 @@ static int parse_reply_info(struct ceph_msg *msg, | |||
223 | goto out_bad; | 255 | goto out_bad; |
224 | } | 256 | } |
225 | 257 | ||
226 | /* dir content */ | 258 | /* extra */ |
227 | ceph_decode_32_safe(&p, end, len, bad); | 259 | ceph_decode_32_safe(&p, end, len, bad); |
228 | if (len > 0) { | 260 | if (len > 0) { |
229 | err = parse_reply_info_dir(&p, p+len, info); | 261 | err = parse_reply_info_extra(&p, p+len, info); |
230 | if (err < 0) | 262 | if (err < 0) |
231 | goto out_bad; | 263 | goto out_bad; |
232 | } | 264 | } |
@@ -2074,7 +2106,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) | |||
2074 | 2106 | ||
2075 | mutex_lock(&session->s_mutex); | 2107 | mutex_lock(&session->s_mutex); |
2076 | if (err < 0) { | 2108 | if (err < 0) { |
2077 | pr_err("mdsc_handle_reply got corrupt reply mds%d\n", mds); | 2109 | pr_err("mdsc_handle_reply got corrupt reply mds%d(tid:%lld)\n", mds, tid); |
2078 | ceph_msg_dump(msg); | 2110 | ceph_msg_dump(msg); |
2079 | goto out_err; | 2111 | goto out_err; |
2080 | } | 2112 | } |
@@ -2094,7 +2126,8 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) | |||
2094 | mutex_lock(&req->r_fill_mutex); | 2126 | mutex_lock(&req->r_fill_mutex); |
2095 | err = ceph_fill_trace(mdsc->fsc->sb, req, req->r_session); | 2127 | err = ceph_fill_trace(mdsc->fsc->sb, req, req->r_session); |
2096 | if (err == 0) { | 2128 | if (err == 0) { |
2097 | if (result == 0 && rinfo->dir_nr) | 2129 | if (result == 0 && req->r_op != CEPH_MDS_OP_GETFILELOCK && |
2130 | rinfo->dir_nr) | ||
2098 | ceph_readdir_prepopulate(req, req->r_session); | 2131 | ceph_readdir_prepopulate(req, req->r_session); |
2099 | ceph_unreserve_caps(mdsc, &req->r_caps_reservation); | 2132 | ceph_unreserve_caps(mdsc, &req->r_caps_reservation); |
2100 | } | 2133 | } |
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h index 9341fd4f1432..aabe563b54db 100644 --- a/fs/ceph/mds_client.h +++ b/fs/ceph/mds_client.h | |||
@@ -42,26 +42,37 @@ struct ceph_mds_reply_info_in { | |||
42 | }; | 42 | }; |
43 | 43 | ||
44 | /* | 44 | /* |
45 | * parsed info about an mds reply, including information about the | 45 | * parsed info about an mds reply, including information about |
46 | * target inode and/or its parent directory and dentry, and directory | 46 | * either: 1) the target inode and/or its parent directory and dentry, |
47 | * contents (for readdir results). | 47 | * and directory contents (for readdir results), or |
48 | * 2) the file range lock info (for fcntl F_GETLK results). | ||
48 | */ | 49 | */ |
49 | struct ceph_mds_reply_info_parsed { | 50 | struct ceph_mds_reply_info_parsed { |
50 | struct ceph_mds_reply_head *head; | 51 | struct ceph_mds_reply_head *head; |
51 | 52 | ||
53 | /* trace */ | ||
52 | struct ceph_mds_reply_info_in diri, targeti; | 54 | struct ceph_mds_reply_info_in diri, targeti; |
53 | struct ceph_mds_reply_dirfrag *dirfrag; | 55 | struct ceph_mds_reply_dirfrag *dirfrag; |
54 | char *dname; | 56 | char *dname; |
55 | u32 dname_len; | 57 | u32 dname_len; |
56 | struct ceph_mds_reply_lease *dlease; | 58 | struct ceph_mds_reply_lease *dlease; |
57 | 59 | ||
58 | struct ceph_mds_reply_dirfrag *dir_dir; | 60 | /* extra */ |
59 | int dir_nr; | 61 | union { |
60 | char **dir_dname; | 62 | /* for fcntl F_GETLK results */ |
61 | u32 *dir_dname_len; | 63 | struct ceph_filelock *filelock_reply; |
62 | struct ceph_mds_reply_lease **dir_dlease; | 64 | |
63 | struct ceph_mds_reply_info_in *dir_in; | 65 | /* for readdir results */ |
64 | u8 dir_complete, dir_end; | 66 | struct { |
67 | struct ceph_mds_reply_dirfrag *dir_dir; | ||
68 | int dir_nr; | ||
69 | char **dir_dname; | ||
70 | u32 *dir_dname_len; | ||
71 | struct ceph_mds_reply_lease **dir_dlease; | ||
72 | struct ceph_mds_reply_info_in *dir_in; | ||
73 | u8 dir_complete, dir_end; | ||
74 | }; | ||
75 | }; | ||
65 | 76 | ||
66 | /* encoded blob describing snapshot contexts for certain | 77 | /* encoded blob describing snapshot contexts for certain |
67 | operations (e.g., open) */ | 78 | operations (e.g., open) */ |
diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile index adefa60a9bdc..43b19dd39191 100644 --- a/fs/cifs/Makefile +++ b/fs/cifs/Makefile | |||
@@ -6,7 +6,9 @@ obj-$(CONFIG_CIFS) += cifs.o | |||
6 | cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \ | 6 | cifs-y := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o \ |
7 | link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \ | 7 | link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o \ |
8 | md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o \ | 8 | md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o \ |
9 | readdir.o ioctl.o sess.o export.o cifsacl.o | 9 | readdir.o ioctl.o sess.o export.o |
10 | |||
11 | cifs-$(CONFIG_CIFS_ACL) += cifsacl.o | ||
10 | 12 | ||
11 | cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o | 13 | cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o |
12 | 14 | ||
diff --git a/fs/cifs/README b/fs/cifs/README index ee68d1036544..46af99ab3614 100644 --- a/fs/cifs/README +++ b/fs/cifs/README | |||
@@ -337,6 +337,15 @@ A partial list of the supported mount options follows: | |||
337 | wsize default write size (default 57344) | 337 | wsize default write size (default 57344) |
338 | maximum wsize currently allowed by CIFS is 57344 (fourteen | 338 | maximum wsize currently allowed by CIFS is 57344 (fourteen |
339 | 4096 byte pages) | 339 | 4096 byte pages) |
340 | actimeo=n attribute cache timeout in seconds (default 1 second). | ||
341 | After this timeout, the cifs client requests fresh attribute | ||
342 | information from the server. This option allows to tune the | ||
343 | attribute cache timeout to suit the workload needs. Shorter | ||
344 | timeouts mean better the cache coherency, but increased number | ||
345 | of calls to the server. Longer timeouts mean reduced number | ||
346 | of calls to the server at the expense of less stricter cache | ||
347 | coherency checks (i.e. incorrect attribute cache for a short | ||
348 | period of time). | ||
340 | rw mount the network share read-write (note that the | 349 | rw mount the network share read-write (note that the |
341 | server may still consider the share read-only) | 350 | server may still consider the share read-only) |
342 | ro mount network share read-only | 351 | ro mount network share read-only |
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index e9a393c9c2ca..7852cd677051 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h | |||
@@ -48,6 +48,7 @@ struct cifs_sb_info { | |||
48 | struct nls_table *local_nls; | 48 | struct nls_table *local_nls; |
49 | unsigned int rsize; | 49 | unsigned int rsize; |
50 | unsigned int wsize; | 50 | unsigned int wsize; |
51 | unsigned long actimeo; /* attribute cache timeout (jiffies) */ | ||
51 | atomic_t active; | 52 | atomic_t active; |
52 | uid_t mnt_uid; | 53 | uid_t mnt_uid; |
53 | gid_t mnt_gid; | 54 | gid_t mnt_gid; |
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index c6ebea088ac7..a437ec391a01 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c | |||
@@ -30,8 +30,6 @@ | |||
30 | #include "cifs_debug.h" | 30 | #include "cifs_debug.h" |
31 | 31 | ||
32 | 32 | ||
33 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
34 | |||
35 | static struct cifs_wksid wksidarr[NUM_WK_SIDS] = { | 33 | static struct cifs_wksid wksidarr[NUM_WK_SIDS] = { |
36 | {{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"}, | 34 | {{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"}, |
37 | {{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"}, | 35 | {{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"}, |
@@ -774,4 +772,3 @@ int mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode) | |||
774 | 772 | ||
775 | return rc; | 773 | return rc; |
776 | } | 774 | } |
777 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | ||
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h index 6c8096cf5155..c4ae7d036563 100644 --- a/fs/cifs/cifsacl.h +++ b/fs/cifs/cifsacl.h | |||
@@ -74,11 +74,7 @@ struct cifs_wksid { | |||
74 | char sidname[SIDNAMELENGTH]; | 74 | char sidname[SIDNAMELENGTH]; |
75 | } __attribute__((packed)); | 75 | } __attribute__((packed)); |
76 | 76 | ||
77 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
78 | |||
79 | extern int match_sid(struct cifs_sid *); | 77 | extern int match_sid(struct cifs_sid *); |
80 | extern int compare_sids(const struct cifs_sid *, const struct cifs_sid *); | 78 | extern int compare_sids(const struct cifs_sid *, const struct cifs_sid *); |
81 | 79 | ||
82 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | ||
83 | |||
84 | #endif /* _CIFSACL_H */ | 80 | #endif /* _CIFSACL_H */ |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 76c8a906a63e..3936aa7f2c22 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -463,6 +463,8 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) | |||
463 | 463 | ||
464 | seq_printf(s, ",rsize=%d", cifs_sb->rsize); | 464 | seq_printf(s, ",rsize=%d", cifs_sb->rsize); |
465 | seq_printf(s, ",wsize=%d", cifs_sb->wsize); | 465 | seq_printf(s, ",wsize=%d", cifs_sb->wsize); |
466 | /* convert actimeo and display it in seconds */ | ||
467 | seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ); | ||
466 | 468 | ||
467 | return 0; | 469 | return 0; |
468 | } | 470 | } |
@@ -935,7 +937,6 @@ init_cifs(void) | |||
935 | GlobalCurrentXid = 0; | 937 | GlobalCurrentXid = 0; |
936 | GlobalTotalActiveXid = 0; | 938 | GlobalTotalActiveXid = 0; |
937 | GlobalMaxActiveXid = 0; | 939 | GlobalMaxActiveXid = 0; |
938 | memset(Local_System_Name, 0, 15); | ||
939 | spin_lock_init(&cifs_tcp_ses_lock); | 940 | spin_lock_init(&cifs_tcp_ses_lock); |
940 | spin_lock_init(&cifs_file_list_lock); | 941 | spin_lock_init(&cifs_file_list_lock); |
941 | spin_lock_init(&GlobalMid_Lock); | 942 | spin_lock_init(&GlobalMid_Lock); |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index b577bf0a1bb3..7136c0c3e2f9 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -45,6 +45,16 @@ | |||
45 | #define CIFS_MIN_RCV_POOL 4 | 45 | #define CIFS_MIN_RCV_POOL 4 |
46 | 46 | ||
47 | /* | 47 | /* |
48 | * default attribute cache timeout (jiffies) | ||
49 | */ | ||
50 | #define CIFS_DEF_ACTIMEO (1 * HZ) | ||
51 | |||
52 | /* | ||
53 | * max attribute cache timeout (jiffies) - 2^30 | ||
54 | */ | ||
55 | #define CIFS_MAX_ACTIMEO (1 << 30) | ||
56 | |||
57 | /* | ||
48 | * MAX_REQ is the maximum number of requests that WE will send | 58 | * MAX_REQ is the maximum number of requests that WE will send |
49 | * on one socket concurrently. It also matches the most common | 59 | * on one socket concurrently. It also matches the most common |
50 | * value of max multiplex returned by servers. We may | 60 | * value of max multiplex returned by servers. We may |
@@ -746,8 +756,6 @@ GLOBAL_EXTERN unsigned int GlobalTotalActiveXid; /* prot by GlobalMid_Sem */ | |||
746 | GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */ | 756 | GLOBAL_EXTERN unsigned int GlobalMaxActiveXid; /* prot by GlobalMid_Sem */ |
747 | GLOBAL_EXTERN spinlock_t GlobalMid_Lock; /* protects above & list operations */ | 757 | GLOBAL_EXTERN spinlock_t GlobalMid_Lock; /* protects above & list operations */ |
748 | /* on midQ entries */ | 758 | /* on midQ entries */ |
749 | GLOBAL_EXTERN char Local_System_Name[15]; | ||
750 | |||
751 | /* | 759 | /* |
752 | * Global counters, updated atomically | 760 | * Global counters, updated atomically |
753 | */ | 761 | */ |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index db961dc4fd3d..e6d1481b16c1 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -54,7 +54,8 @@ do { \ | |||
54 | __func__, curr_xid, (int)rc); \ | 54 | __func__, curr_xid, (int)rc); \ |
55 | } while (0) | 55 | } while (0) |
56 | extern char *build_path_from_dentry(struct dentry *); | 56 | extern char *build_path_from_dentry(struct dentry *); |
57 | extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb); | 57 | extern char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb, |
58 | struct cifsTconInfo *tcon); | ||
58 | extern char *build_wildcard_path_from_dentry(struct dentry *direntry); | 59 | extern char *build_wildcard_path_from_dentry(struct dentry *direntry); |
59 | extern char *cifs_compose_mount_options(const char *sb_mountdata, | 60 | extern char *cifs_compose_mount_options(const char *sb_mountdata, |
60 | const char *fullpath, const struct dfs_info3_param *ref, | 61 | const char *fullpath, const struct dfs_info3_param *ref, |
@@ -79,9 +80,7 @@ extern bool is_valid_oplock_break(struct smb_hdr *smb, | |||
79 | struct TCP_Server_Info *); | 80 | struct TCP_Server_Info *); |
80 | extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); | 81 | extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); |
81 | extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool); | 82 | extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool); |
82 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
83 | extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool); | 83 | extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool); |
84 | #endif | ||
85 | extern unsigned int smbCalcSize(struct smb_hdr *ptr); | 84 | extern unsigned int smbCalcSize(struct smb_hdr *ptr); |
86 | extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); | 85 | extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); |
87 | extern int decode_negTokenInit(unsigned char *security_blob, int length, | 86 | extern int decode_negTokenInit(unsigned char *security_blob, int length, |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 2f2632b6df5a..67acfb3acad2 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -2478,95 +2478,6 @@ querySymLinkRetry: | |||
2478 | } | 2478 | } |
2479 | 2479 | ||
2480 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 2480 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
2481 | /* Initialize NT TRANSACT SMB into small smb request buffer. | ||
2482 | This assumes that all NT TRANSACTS that we init here have | ||
2483 | total parm and data under about 400 bytes (to fit in small cifs | ||
2484 | buffer size), which is the case so far, it easily fits. NB: | ||
2485 | Setup words themselves and ByteCount | ||
2486 | MaxSetupCount (size of returned setup area) and | ||
2487 | MaxParameterCount (returned parms size) must be set by caller */ | ||
2488 | static int | ||
2489 | smb_init_nttransact(const __u16 sub_command, const int setup_count, | ||
2490 | const int parm_len, struct cifsTconInfo *tcon, | ||
2491 | void **ret_buf) | ||
2492 | { | ||
2493 | int rc; | ||
2494 | __u32 temp_offset; | ||
2495 | struct smb_com_ntransact_req *pSMB; | ||
2496 | |||
2497 | rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon, | ||
2498 | (void **)&pSMB); | ||
2499 | if (rc) | ||
2500 | return rc; | ||
2501 | *ret_buf = (void *)pSMB; | ||
2502 | pSMB->Reserved = 0; | ||
2503 | pSMB->TotalParameterCount = cpu_to_le32(parm_len); | ||
2504 | pSMB->TotalDataCount = 0; | ||
2505 | pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf - | ||
2506 | MAX_CIFS_HDR_SIZE) & 0xFFFFFF00); | ||
2507 | pSMB->ParameterCount = pSMB->TotalParameterCount; | ||
2508 | pSMB->DataCount = pSMB->TotalDataCount; | ||
2509 | temp_offset = offsetof(struct smb_com_ntransact_req, Parms) + | ||
2510 | (setup_count * 2) - 4 /* for rfc1001 length itself */; | ||
2511 | pSMB->ParameterOffset = cpu_to_le32(temp_offset); | ||
2512 | pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len); | ||
2513 | pSMB->SetupCount = setup_count; /* no need to le convert byte fields */ | ||
2514 | pSMB->SubCommand = cpu_to_le16(sub_command); | ||
2515 | return 0; | ||
2516 | } | ||
2517 | |||
2518 | static int | ||
2519 | validate_ntransact(char *buf, char **ppparm, char **ppdata, | ||
2520 | __u32 *pparmlen, __u32 *pdatalen) | ||
2521 | { | ||
2522 | char *end_of_smb; | ||
2523 | __u32 data_count, data_offset, parm_count, parm_offset; | ||
2524 | struct smb_com_ntransact_rsp *pSMBr; | ||
2525 | |||
2526 | *pdatalen = 0; | ||
2527 | *pparmlen = 0; | ||
2528 | |||
2529 | if (buf == NULL) | ||
2530 | return -EINVAL; | ||
2531 | |||
2532 | pSMBr = (struct smb_com_ntransact_rsp *)buf; | ||
2533 | |||
2534 | /* ByteCount was converted from little endian in SendReceive */ | ||
2535 | end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount + | ||
2536 | (char *)&pSMBr->ByteCount; | ||
2537 | |||
2538 | data_offset = le32_to_cpu(pSMBr->DataOffset); | ||
2539 | data_count = le32_to_cpu(pSMBr->DataCount); | ||
2540 | parm_offset = le32_to_cpu(pSMBr->ParameterOffset); | ||
2541 | parm_count = le32_to_cpu(pSMBr->ParameterCount); | ||
2542 | |||
2543 | *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset; | ||
2544 | *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset; | ||
2545 | |||
2546 | /* should we also check that parm and data areas do not overlap? */ | ||
2547 | if (*ppparm > end_of_smb) { | ||
2548 | cFYI(1, "parms start after end of smb"); | ||
2549 | return -EINVAL; | ||
2550 | } else if (parm_count + *ppparm > end_of_smb) { | ||
2551 | cFYI(1, "parm end after end of smb"); | ||
2552 | return -EINVAL; | ||
2553 | } else if (*ppdata > end_of_smb) { | ||
2554 | cFYI(1, "data starts after end of smb"); | ||
2555 | return -EINVAL; | ||
2556 | } else if (data_count + *ppdata > end_of_smb) { | ||
2557 | cFYI(1, "data %p + count %d (%p) past smb end %p start %p", | ||
2558 | *ppdata, data_count, (data_count + *ppdata), | ||
2559 | end_of_smb, pSMBr); | ||
2560 | return -EINVAL; | ||
2561 | } else if (parm_count + data_count > pSMBr->ByteCount) { | ||
2562 | cFYI(1, "parm count and data count larger than SMB"); | ||
2563 | return -EINVAL; | ||
2564 | } | ||
2565 | *pdatalen = data_count; | ||
2566 | *pparmlen = parm_count; | ||
2567 | return 0; | ||
2568 | } | ||
2569 | |||
2570 | int | 2481 | int |
2571 | CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, | 2482 | CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, |
2572 | const unsigned char *searchName, | 2483 | const unsigned char *searchName, |
@@ -3056,7 +2967,97 @@ GetExtAttrOut: | |||
3056 | 2967 | ||
3057 | #endif /* CONFIG_POSIX */ | 2968 | #endif /* CONFIG_POSIX */ |
3058 | 2969 | ||
3059 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 2970 | #ifdef CONFIG_CIFS_ACL |
2971 | /* | ||
2972 | * Initialize NT TRANSACT SMB into small smb request buffer. This assumes that | ||
2973 | * all NT TRANSACTS that we init here have total parm and data under about 400 | ||
2974 | * bytes (to fit in small cifs buffer size), which is the case so far, it | ||
2975 | * easily fits. NB: Setup words themselves and ByteCount MaxSetupCount (size of | ||
2976 | * returned setup area) and MaxParameterCount (returned parms size) must be set | ||
2977 | * by caller | ||
2978 | */ | ||
2979 | static int | ||
2980 | smb_init_nttransact(const __u16 sub_command, const int setup_count, | ||
2981 | const int parm_len, struct cifsTconInfo *tcon, | ||
2982 | void **ret_buf) | ||
2983 | { | ||
2984 | int rc; | ||
2985 | __u32 temp_offset; | ||
2986 | struct smb_com_ntransact_req *pSMB; | ||
2987 | |||
2988 | rc = small_smb_init(SMB_COM_NT_TRANSACT, 19 + setup_count, tcon, | ||
2989 | (void **)&pSMB); | ||
2990 | if (rc) | ||
2991 | return rc; | ||
2992 | *ret_buf = (void *)pSMB; | ||
2993 | pSMB->Reserved = 0; | ||
2994 | pSMB->TotalParameterCount = cpu_to_le32(parm_len); | ||
2995 | pSMB->TotalDataCount = 0; | ||
2996 | pSMB->MaxDataCount = cpu_to_le32((tcon->ses->server->maxBuf - | ||
2997 | MAX_CIFS_HDR_SIZE) & 0xFFFFFF00); | ||
2998 | pSMB->ParameterCount = pSMB->TotalParameterCount; | ||
2999 | pSMB->DataCount = pSMB->TotalDataCount; | ||
3000 | temp_offset = offsetof(struct smb_com_ntransact_req, Parms) + | ||
3001 | (setup_count * 2) - 4 /* for rfc1001 length itself */; | ||
3002 | pSMB->ParameterOffset = cpu_to_le32(temp_offset); | ||
3003 | pSMB->DataOffset = cpu_to_le32(temp_offset + parm_len); | ||
3004 | pSMB->SetupCount = setup_count; /* no need to le convert byte fields */ | ||
3005 | pSMB->SubCommand = cpu_to_le16(sub_command); | ||
3006 | return 0; | ||
3007 | } | ||
3008 | |||
3009 | static int | ||
3010 | validate_ntransact(char *buf, char **ppparm, char **ppdata, | ||
3011 | __u32 *pparmlen, __u32 *pdatalen) | ||
3012 | { | ||
3013 | char *end_of_smb; | ||
3014 | __u32 data_count, data_offset, parm_count, parm_offset; | ||
3015 | struct smb_com_ntransact_rsp *pSMBr; | ||
3016 | |||
3017 | *pdatalen = 0; | ||
3018 | *pparmlen = 0; | ||
3019 | |||
3020 | if (buf == NULL) | ||
3021 | return -EINVAL; | ||
3022 | |||
3023 | pSMBr = (struct smb_com_ntransact_rsp *)buf; | ||
3024 | |||
3025 | /* ByteCount was converted from little endian in SendReceive */ | ||
3026 | end_of_smb = 2 /* sizeof byte count */ + pSMBr->ByteCount + | ||
3027 | (char *)&pSMBr->ByteCount; | ||
3028 | |||
3029 | data_offset = le32_to_cpu(pSMBr->DataOffset); | ||
3030 | data_count = le32_to_cpu(pSMBr->DataCount); | ||
3031 | parm_offset = le32_to_cpu(pSMBr->ParameterOffset); | ||
3032 | parm_count = le32_to_cpu(pSMBr->ParameterCount); | ||
3033 | |||
3034 | *ppparm = (char *)&pSMBr->hdr.Protocol + parm_offset; | ||
3035 | *ppdata = (char *)&pSMBr->hdr.Protocol + data_offset; | ||
3036 | |||
3037 | /* should we also check that parm and data areas do not overlap? */ | ||
3038 | if (*ppparm > end_of_smb) { | ||
3039 | cFYI(1, "parms start after end of smb"); | ||
3040 | return -EINVAL; | ||
3041 | } else if (parm_count + *ppparm > end_of_smb) { | ||
3042 | cFYI(1, "parm end after end of smb"); | ||
3043 | return -EINVAL; | ||
3044 | } else if (*ppdata > end_of_smb) { | ||
3045 | cFYI(1, "data starts after end of smb"); | ||
3046 | return -EINVAL; | ||
3047 | } else if (data_count + *ppdata > end_of_smb) { | ||
3048 | cFYI(1, "data %p + count %d (%p) past smb end %p start %p", | ||
3049 | *ppdata, data_count, (data_count + *ppdata), | ||
3050 | end_of_smb, pSMBr); | ||
3051 | return -EINVAL; | ||
3052 | } else if (parm_count + data_count > pSMBr->ByteCount) { | ||
3053 | cFYI(1, "parm count and data count larger than SMB"); | ||
3054 | return -EINVAL; | ||
3055 | } | ||
3056 | *pdatalen = data_count; | ||
3057 | *pparmlen = parm_count; | ||
3058 | return 0; | ||
3059 | } | ||
3060 | |||
3060 | /* Get Security Descriptor (by handle) from remote server for a file or dir */ | 3061 | /* Get Security Descriptor (by handle) from remote server for a file or dir */ |
3061 | int | 3062 | int |
3062 | CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | 3063 | CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, |
@@ -3214,7 +3215,7 @@ setCifsAclRetry: | |||
3214 | return (rc); | 3215 | return (rc); |
3215 | } | 3216 | } |
3216 | 3217 | ||
3217 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | 3218 | #endif /* CONFIG_CIFS_ACL */ |
3218 | 3219 | ||
3219 | /* Legacy Query Path Information call for lookup to old servers such | 3220 | /* Legacy Query Path Information call for lookup to old servers such |
3220 | as Win9x/WinME */ | 3221 | as Win9x/WinME */ |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 32fa4d9b5dbc..cc1a8604a790 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -105,6 +105,7 @@ struct smb_vol { | |||
105 | unsigned int wsize; | 105 | unsigned int wsize; |
106 | bool sockopt_tcp_nodelay:1; | 106 | bool sockopt_tcp_nodelay:1; |
107 | unsigned short int port; | 107 | unsigned short int port; |
108 | unsigned long actimeo; /* attribute cache timeout (jiffies) */ | ||
108 | char *prepath; | 109 | char *prepath; |
109 | struct sockaddr_storage srcaddr; /* allow binding to a local IP */ | 110 | struct sockaddr_storage srcaddr; /* allow binding to a local IP */ |
110 | struct nls_table *local_nls; | 111 | struct nls_table *local_nls; |
@@ -806,23 +807,20 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
806 | short int override_gid = -1; | 807 | short int override_gid = -1; |
807 | bool uid_specified = false; | 808 | bool uid_specified = false; |
808 | bool gid_specified = false; | 809 | bool gid_specified = false; |
810 | char *nodename = utsname()->nodename; | ||
809 | 811 | ||
810 | separator[0] = ','; | 812 | separator[0] = ','; |
811 | separator[1] = 0; | 813 | separator[1] = 0; |
812 | 814 | ||
813 | if (Local_System_Name[0] != 0) | 815 | /* |
814 | memcpy(vol->source_rfc1001_name, Local_System_Name, 15); | 816 | * does not have to be perfect mapping since field is |
815 | else { | 817 | * informational, only used for servers that do not support |
816 | char *nodename = utsname()->nodename; | 818 | * port 445 and it can be overridden at mount time |
817 | int n = strnlen(nodename, 15); | 819 | */ |
818 | memset(vol->source_rfc1001_name, 0x20, 15); | 820 | memset(vol->source_rfc1001_name, 0x20, 15); |
819 | for (i = 0; i < n; i++) { | 821 | for (i = 0; i < strnlen(nodename, 15); i++) |
820 | /* does not have to be perfect mapping since field is | 822 | vol->source_rfc1001_name[i] = toupper(nodename[i]); |
821 | informational, only used for servers that do not support | 823 | |
822 | port 445 and it can be overridden at mount time */ | ||
823 | vol->source_rfc1001_name[i] = toupper(nodename[i]); | ||
824 | } | ||
825 | } | ||
826 | vol->source_rfc1001_name[15] = 0; | 824 | vol->source_rfc1001_name[15] = 0; |
827 | /* null target name indicates to use *SMBSERVR default called name | 825 | /* null target name indicates to use *SMBSERVR default called name |
828 | if we end up sending RFC1001 session initialize */ | 826 | if we end up sending RFC1001 session initialize */ |
@@ -840,6 +838,8 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
840 | /* default to using server inode numbers where available */ | 838 | /* default to using server inode numbers where available */ |
841 | vol->server_ino = 1; | 839 | vol->server_ino = 1; |
842 | 840 | ||
841 | vol->actimeo = CIFS_DEF_ACTIMEO; | ||
842 | |||
843 | if (!options) | 843 | if (!options) |
844 | return 1; | 844 | return 1; |
845 | 845 | ||
@@ -1214,6 +1214,16 @@ cifs_parse_mount_options(char *options, const char *devname, | |||
1214 | printk(KERN_WARNING "CIFS: server net" | 1214 | printk(KERN_WARNING "CIFS: server net" |
1215 | "biosname longer than 15 truncated.\n"); | 1215 | "biosname longer than 15 truncated.\n"); |
1216 | } | 1216 | } |
1217 | } else if (strnicmp(data, "actimeo", 7) == 0) { | ||
1218 | if (value && *value) { | ||
1219 | vol->actimeo = HZ * simple_strtoul(value, | ||
1220 | &value, 0); | ||
1221 | if (vol->actimeo > CIFS_MAX_ACTIMEO) { | ||
1222 | cERROR(1, "CIFS: attribute cache" | ||
1223 | "timeout too large"); | ||
1224 | return 1; | ||
1225 | } | ||
1226 | } | ||
1217 | } else if (strnicmp(data, "credentials", 4) == 0) { | 1227 | } else if (strnicmp(data, "credentials", 4) == 0) { |
1218 | /* ignore */ | 1228 | /* ignore */ |
1219 | } else if (strnicmp(data, "version", 3) == 0) { | 1229 | } else if (strnicmp(data, "version", 3) == 0) { |
@@ -2571,6 +2581,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info, | |||
2571 | cFYI(1, "file mode: 0x%x dir mode: 0x%x", | 2581 | cFYI(1, "file mode: 0x%x dir mode: 0x%x", |
2572 | cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode); | 2582 | cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode); |
2573 | 2583 | ||
2584 | cifs_sb->actimeo = pvolume_info->actimeo; | ||
2585 | |||
2574 | if (pvolume_info->noperm) | 2586 | if (pvolume_info->noperm) |
2575 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; | 2587 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM; |
2576 | if (pvolume_info->setuids) | 2588 | if (pvolume_info->setuids) |
@@ -2821,13 +2833,13 @@ remote_path_check: | |||
2821 | /* check if a whole path (including prepath) is not remote */ | 2833 | /* check if a whole path (including prepath) is not remote */ |
2822 | if (!rc && cifs_sb->prepathlen && tcon) { | 2834 | if (!rc && cifs_sb->prepathlen && tcon) { |
2823 | /* build_path_to_root works only when we have a valid tcon */ | 2835 | /* build_path_to_root works only when we have a valid tcon */ |
2824 | full_path = cifs_build_path_to_root(cifs_sb); | 2836 | full_path = cifs_build_path_to_root(cifs_sb, tcon); |
2825 | if (full_path == NULL) { | 2837 | if (full_path == NULL) { |
2826 | rc = -ENOMEM; | 2838 | rc = -ENOMEM; |
2827 | goto mount_fail_check; | 2839 | goto mount_fail_check; |
2828 | } | 2840 | } |
2829 | rc = is_path_accessible(xid, tcon, cifs_sb, full_path); | 2841 | rc = is_path_accessible(xid, tcon, cifs_sb, full_path); |
2830 | if (rc != -EREMOTE) { | 2842 | if (rc != 0 && rc != -EREMOTE) { |
2831 | kfree(full_path); | 2843 | kfree(full_path); |
2832 | goto mount_fail_check; | 2844 | goto mount_fail_check; |
2833 | } | 2845 | } |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index b857ce5db775..5a28660ca2b5 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -1108,7 +1108,6 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file, | |||
1108 | return total_written; | 1108 | return total_written; |
1109 | } | 1109 | } |
1110 | 1110 | ||
1111 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
1112 | struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, | 1111 | struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, |
1113 | bool fsuid_only) | 1112 | bool fsuid_only) |
1114 | { | 1113 | { |
@@ -1142,7 +1141,6 @@ struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, | |||
1142 | spin_unlock(&cifs_file_list_lock); | 1141 | spin_unlock(&cifs_file_list_lock); |
1143 | return NULL; | 1142 | return NULL; |
1144 | } | 1143 | } |
1145 | #endif | ||
1146 | 1144 | ||
1147 | struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, | 1145 | struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode, |
1148 | bool fsuid_only) | 1146 | bool fsuid_only) |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 28cb6e735943..589f3e3f6e00 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -686,7 +686,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
686 | cFYI(1, "cifs_sfu_type failed: %d", tmprc); | 686 | cFYI(1, "cifs_sfu_type failed: %d", tmprc); |
687 | } | 687 | } |
688 | 688 | ||
689 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 689 | #ifdef CONFIG_CIFS_ACL |
690 | /* fill in 0777 bits from ACL */ | 690 | /* fill in 0777 bits from ACL */ |
691 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 691 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
692 | rc = cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path, | 692 | rc = cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path, |
@@ -697,7 +697,7 @@ int cifs_get_inode_info(struct inode **pinode, | |||
697 | goto cgii_exit; | 697 | goto cgii_exit; |
698 | } | 698 | } |
699 | } | 699 | } |
700 | #endif | 700 | #endif /* CONFIG_CIFS_ACL */ |
701 | 701 | ||
702 | /* fill in remaining high mode bits e.g. SUID, VTX */ | 702 | /* fill in remaining high mode bits e.g. SUID, VTX */ |
703 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) | 703 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) |
@@ -728,12 +728,12 @@ static const struct inode_operations cifs_ipc_inode_ops = { | |||
728 | .lookup = cifs_lookup, | 728 | .lookup = cifs_lookup, |
729 | }; | 729 | }; |
730 | 730 | ||
731 | char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb) | 731 | char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb, |
732 | struct cifsTconInfo *tcon) | ||
732 | { | 733 | { |
733 | int pplen = cifs_sb->prepathlen; | 734 | int pplen = cifs_sb->prepathlen; |
734 | int dfsplen; | 735 | int dfsplen; |
735 | char *full_path = NULL; | 736 | char *full_path = NULL; |
736 | struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); | ||
737 | 737 | ||
738 | /* if no prefix path, simply set path to the root of share to "" */ | 738 | /* if no prefix path, simply set path to the root of share to "" */ |
739 | if (pplen == 0) { | 739 | if (pplen == 0) { |
@@ -875,7 +875,7 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino) | |||
875 | char *full_path; | 875 | char *full_path; |
876 | struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); | 876 | struct cifsTconInfo *tcon = cifs_sb_master_tcon(cifs_sb); |
877 | 877 | ||
878 | full_path = cifs_build_path_to_root(cifs_sb); | 878 | full_path = cifs_build_path_to_root(cifs_sb, tcon); |
879 | if (full_path == NULL) | 879 | if (full_path == NULL) |
880 | return ERR_PTR(-ENOMEM); | 880 | return ERR_PTR(-ENOMEM); |
881 | 881 | ||
@@ -1653,6 +1653,7 @@ static bool | |||
1653 | cifs_inode_needs_reval(struct inode *inode) | 1653 | cifs_inode_needs_reval(struct inode *inode) |
1654 | { | 1654 | { |
1655 | struct cifsInodeInfo *cifs_i = CIFS_I(inode); | 1655 | struct cifsInodeInfo *cifs_i = CIFS_I(inode); |
1656 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); | ||
1656 | 1657 | ||
1657 | if (cifs_i->clientCanCacheRead) | 1658 | if (cifs_i->clientCanCacheRead) |
1658 | return false; | 1659 | return false; |
@@ -1663,12 +1664,12 @@ cifs_inode_needs_reval(struct inode *inode) | |||
1663 | if (cifs_i->time == 0) | 1664 | if (cifs_i->time == 0) |
1664 | return true; | 1665 | return true; |
1665 | 1666 | ||
1666 | /* FIXME: the actimeo should be tunable */ | 1667 | if (!time_in_range(jiffies, cifs_i->time, |
1667 | if (time_after_eq(jiffies, cifs_i->time + HZ)) | 1668 | cifs_i->time + cifs_sb->actimeo)) |
1668 | return true; | 1669 | return true; |
1669 | 1670 | ||
1670 | /* hardlinked files w/ noserverino get "special" treatment */ | 1671 | /* hardlinked files w/ noserverino get "special" treatment */ |
1671 | if (!(CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) && | 1672 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) && |
1672 | S_ISREG(inode->i_mode) && inode->i_nlink != 1) | 1673 | S_ISREG(inode->i_mode) && inode->i_nlink != 1) |
1673 | return true; | 1674 | return true; |
1674 | 1675 | ||
@@ -2121,7 +2122,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | |||
2121 | 2122 | ||
2122 | if (attrs->ia_valid & ATTR_MODE) { | 2123 | if (attrs->ia_valid & ATTR_MODE) { |
2123 | rc = 0; | 2124 | rc = 0; |
2124 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 2125 | #ifdef CONFIG_CIFS_ACL |
2125 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 2126 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { |
2126 | rc = mode_to_cifs_acl(inode, full_path, mode); | 2127 | rc = mode_to_cifs_acl(inode, full_path, mode); |
2127 | if (rc) { | 2128 | if (rc) { |
@@ -2130,7 +2131,7 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) | |||
2130 | goto cifs_setattr_exit; | 2131 | goto cifs_setattr_exit; |
2131 | } | 2132 | } |
2132 | } else | 2133 | } else |
2133 | #endif | 2134 | #endif /* CONFIG_CIFS_ACL */ |
2134 | if (((mode & S_IWUGO) == 0) && | 2135 | if (((mode & S_IWUGO) == 0) && |
2135 | (cifsInode->cifsAttrs & ATTR_READONLY) == 0) { | 2136 | (cifsInode->cifsAttrs & ATTR_READONLY) == 0) { |
2136 | 2137 | ||
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 32d300e8f20e..a73eb9f4bdaf 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -759,18 +759,6 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir, | |||
759 | rc = filldir(direntry, qstring.name, qstring.len, file->f_pos, | 759 | rc = filldir(direntry, qstring.name, qstring.len, file->f_pos, |
760 | ino, fattr.cf_dtype); | 760 | ino, fattr.cf_dtype); |
761 | 761 | ||
762 | /* | ||
763 | * we can not return filldir errors to the caller since they are | ||
764 | * "normal" when the stat blocksize is too small - we return remapped | ||
765 | * error instead | ||
766 | * | ||
767 | * FIXME: This looks bogus. filldir returns -EOVERFLOW in the above | ||
768 | * case already. Why should we be clobbering other errors from it? | ||
769 | */ | ||
770 | if (rc) { | ||
771 | cFYI(1, "filldir rc = %d", rc); | ||
772 | rc = -EOVERFLOW; | ||
773 | } | ||
774 | dput(tmp_dentry); | 762 | dput(tmp_dentry); |
775 | return rc; | 763 | return rc; |
776 | } | 764 | } |
@@ -275,6 +275,11 @@ static int __bprm_mm_init(struct linux_binprm *bprm) | |||
275 | vma->vm_flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP; | 275 | vma->vm_flags = VM_STACK_FLAGS | VM_STACK_INCOMPLETE_SETUP; |
276 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); | 276 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
277 | INIT_LIST_HEAD(&vma->anon_vma_chain); | 277 | INIT_LIST_HEAD(&vma->anon_vma_chain); |
278 | |||
279 | err = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1); | ||
280 | if (err) | ||
281 | goto err; | ||
282 | |||
278 | err = insert_vm_struct(mm, vma); | 283 | err = insert_vm_struct(mm, vma); |
279 | if (err) | 284 | if (err) |
280 | goto err; | 285 | goto err; |
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 6a5edea2d70b..94ce3d7a1c4b 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -910,6 +910,7 @@ struct ext4_inode_info { | |||
910 | #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */ | 910 | #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */ |
911 | #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */ | 911 | #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */ |
912 | #define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */ | 912 | #define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */ |
913 | #define EXT4_MOUNT_MBLK_IO_SUBMIT 0x4000000 /* multi-block io submits */ | ||
913 | #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */ | 914 | #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */ |
914 | #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */ | 915 | #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */ |
915 | #define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */ | 916 | #define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */ |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index bdbe69902207..e659597b690b 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -2125,9 +2125,12 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd, | |||
2125 | */ | 2125 | */ |
2126 | if (unlikely(journal_data && PageChecked(page))) | 2126 | if (unlikely(journal_data && PageChecked(page))) |
2127 | err = __ext4_journalled_writepage(page, len); | 2127 | err = __ext4_journalled_writepage(page, len); |
2128 | else | 2128 | else if (test_opt(inode->i_sb, MBLK_IO_SUBMIT)) |
2129 | err = ext4_bio_write_page(&io_submit, page, | 2129 | err = ext4_bio_write_page(&io_submit, page, |
2130 | len, mpd->wbc); | 2130 | len, mpd->wbc); |
2131 | else | ||
2132 | err = block_write_full_page(page, | ||
2133 | noalloc_get_block_write, mpd->wbc); | ||
2131 | 2134 | ||
2132 | if (!err) | 2135 | if (!err) |
2133 | mpd->pages_written++; | 2136 | mpd->pages_written++; |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 92203b8a099f..dc40e75cba88 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -872,7 +872,7 @@ static struct buffer_head * ext4_find_entry (struct inode *dir, | |||
872 | if (namelen > EXT4_NAME_LEN) | 872 | if (namelen > EXT4_NAME_LEN) |
873 | return NULL; | 873 | return NULL; |
874 | if ((namelen <= 2) && (name[0] == '.') && | 874 | if ((namelen <= 2) && (name[0] == '.') && |
875 | (name[1] == '.' || name[1] == '0')) { | 875 | (name[1] == '.' || name[1] == '\0')) { |
876 | /* | 876 | /* |
877 | * "." or ".." will only be in the first block | 877 | * "." or ".." will only be in the first block |
878 | * NFS may look up ".."; "." should be handled by the VFS | 878 | * NFS may look up ".."; "." should be handled by the VFS |
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index dc963929de65..981c8477adab 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
@@ -232,6 +232,8 @@ static int setup_new_group_blocks(struct super_block *sb, | |||
232 | GFP_NOFS); | 232 | GFP_NOFS); |
233 | if (err) | 233 | if (err) |
234 | goto exit_bh; | 234 | goto exit_bh; |
235 | for (i = 0, bit = gdblocks + 1; i < reserved_gdb; i++, bit++) | ||
236 | ext4_set_bit(bit, bh->b_data); | ||
235 | 237 | ||
236 | ext4_debug("mark block bitmap %#04llx (+%llu)\n", input->block_bitmap, | 238 | ext4_debug("mark block bitmap %#04llx (+%llu)\n", input->block_bitmap, |
237 | input->block_bitmap - start); | 239 | input->block_bitmap - start); |
@@ -247,6 +249,9 @@ static int setup_new_group_blocks(struct super_block *sb, | |||
247 | err = sb_issue_zeroout(sb, block, sbi->s_itb_per_group, GFP_NOFS); | 249 | err = sb_issue_zeroout(sb, block, sbi->s_itb_per_group, GFP_NOFS); |
248 | if (err) | 250 | if (err) |
249 | goto exit_bh; | 251 | goto exit_bh; |
252 | for (i = 0, bit = input->inode_table - start; | ||
253 | i < sbi->s_itb_per_group; i++, bit++) | ||
254 | ext4_set_bit(bit, bh->b_data); | ||
250 | 255 | ||
251 | if ((err = extend_or_restart_transaction(handle, 2, bh))) | 256 | if ((err = extend_or_restart_transaction(handle, 2, bh))) |
252 | goto exit_bh; | 257 | goto exit_bh; |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index e32195d6aac3..fb15c9c0be74 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -1026,6 +1026,8 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
1026 | !(def_mount_opts & EXT4_DEFM_NODELALLOC)) | 1026 | !(def_mount_opts & EXT4_DEFM_NODELALLOC)) |
1027 | seq_puts(seq, ",nodelalloc"); | 1027 | seq_puts(seq, ",nodelalloc"); |
1028 | 1028 | ||
1029 | if (test_opt(sb, MBLK_IO_SUBMIT)) | ||
1030 | seq_puts(seq, ",mblk_io_submit"); | ||
1029 | if (sbi->s_stripe) | 1031 | if (sbi->s_stripe) |
1030 | seq_printf(seq, ",stripe=%lu", sbi->s_stripe); | 1032 | seq_printf(seq, ",stripe=%lu", sbi->s_stripe); |
1031 | /* | 1033 | /* |
@@ -1239,8 +1241,8 @@ enum { | |||
1239 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota, | 1241 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota, |
1240 | Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, | 1242 | Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, |
1241 | Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version, | 1243 | Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version, |
1242 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, | 1244 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit, |
1243 | Opt_block_validity, Opt_noblock_validity, | 1245 | Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity, |
1244 | Opt_inode_readahead_blks, Opt_journal_ioprio, | 1246 | Opt_inode_readahead_blks, Opt_journal_ioprio, |
1245 | Opt_dioread_nolock, Opt_dioread_lock, | 1247 | Opt_dioread_nolock, Opt_dioread_lock, |
1246 | Opt_discard, Opt_nodiscard, | 1248 | Opt_discard, Opt_nodiscard, |
@@ -1304,6 +1306,8 @@ static const match_table_t tokens = { | |||
1304 | {Opt_resize, "resize"}, | 1306 | {Opt_resize, "resize"}, |
1305 | {Opt_delalloc, "delalloc"}, | 1307 | {Opt_delalloc, "delalloc"}, |
1306 | {Opt_nodelalloc, "nodelalloc"}, | 1308 | {Opt_nodelalloc, "nodelalloc"}, |
1309 | {Opt_mblk_io_submit, "mblk_io_submit"}, | ||
1310 | {Opt_nomblk_io_submit, "nomblk_io_submit"}, | ||
1307 | {Opt_block_validity, "block_validity"}, | 1311 | {Opt_block_validity, "block_validity"}, |
1308 | {Opt_noblock_validity, "noblock_validity"}, | 1312 | {Opt_noblock_validity, "noblock_validity"}, |
1309 | {Opt_inode_readahead_blks, "inode_readahead_blks=%u"}, | 1313 | {Opt_inode_readahead_blks, "inode_readahead_blks=%u"}, |
@@ -1725,6 +1729,12 @@ set_qf_format: | |||
1725 | case Opt_nodelalloc: | 1729 | case Opt_nodelalloc: |
1726 | clear_opt(sbi->s_mount_opt, DELALLOC); | 1730 | clear_opt(sbi->s_mount_opt, DELALLOC); |
1727 | break; | 1731 | break; |
1732 | case Opt_mblk_io_submit: | ||
1733 | set_opt(sbi->s_mount_opt, MBLK_IO_SUBMIT); | ||
1734 | break; | ||
1735 | case Opt_nomblk_io_submit: | ||
1736 | clear_opt(sbi->s_mount_opt, MBLK_IO_SUBMIT); | ||
1737 | break; | ||
1728 | case Opt_stripe: | 1738 | case Opt_stripe: |
1729 | if (match_int(&args[0], &option)) | 1739 | if (match_int(&args[0], &option)) |
1730 | return 0; | 1740 | return 0; |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 9242d294fe90..8b984a2cebbd 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/sched.h> | 14 | #include <linux/sched.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/compat.h> | ||
16 | 17 | ||
17 | static const struct file_operations fuse_direct_io_file_operations; | 18 | static const struct file_operations fuse_direct_io_file_operations; |
18 | 19 | ||
@@ -1628,6 +1629,58 @@ static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov, | |||
1628 | } | 1629 | } |
1629 | 1630 | ||
1630 | /* | 1631 | /* |
1632 | * CUSE servers compiled on 32bit broke on 64bit kernels because the | ||
1633 | * ABI was defined to be 'struct iovec' which is different on 32bit | ||
1634 | * and 64bit. Fortunately we can determine which structure the server | ||
1635 | * used from the size of the reply. | ||
1636 | */ | ||
1637 | static int fuse_copy_ioctl_iovec(struct iovec *dst, void *src, | ||
1638 | size_t transferred, unsigned count, | ||
1639 | bool is_compat) | ||
1640 | { | ||
1641 | #ifdef CONFIG_COMPAT | ||
1642 | if (count * sizeof(struct compat_iovec) == transferred) { | ||
1643 | struct compat_iovec *ciov = src; | ||
1644 | unsigned i; | ||
1645 | |||
1646 | /* | ||
1647 | * With this interface a 32bit server cannot support | ||
1648 | * non-compat (i.e. ones coming from 64bit apps) ioctl | ||
1649 | * requests | ||
1650 | */ | ||
1651 | if (!is_compat) | ||
1652 | return -EINVAL; | ||
1653 | |||
1654 | for (i = 0; i < count; i++) { | ||
1655 | dst[i].iov_base = compat_ptr(ciov[i].iov_base); | ||
1656 | dst[i].iov_len = ciov[i].iov_len; | ||
1657 | } | ||
1658 | return 0; | ||
1659 | } | ||
1660 | #endif | ||
1661 | |||
1662 | if (count * sizeof(struct iovec) != transferred) | ||
1663 | return -EIO; | ||
1664 | |||
1665 | memcpy(dst, src, transferred); | ||
1666 | return 0; | ||
1667 | } | ||
1668 | |||
1669 | /* Make sure iov_length() won't overflow */ | ||
1670 | static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count) | ||
1671 | { | ||
1672 | size_t n; | ||
1673 | u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT; | ||
1674 | |||
1675 | for (n = 0; n < count; n++) { | ||
1676 | if (iov->iov_len > (size_t) max) | ||
1677 | return -ENOMEM; | ||
1678 | max -= iov->iov_len; | ||
1679 | } | ||
1680 | return 0; | ||
1681 | } | ||
1682 | |||
1683 | /* | ||
1631 | * For ioctls, there is no generic way to determine how much memory | 1684 | * For ioctls, there is no generic way to determine how much memory |
1632 | * needs to be read and/or written. Furthermore, ioctls are allowed | 1685 | * needs to be read and/or written. Furthermore, ioctls are allowed |
1633 | * to dereference the passed pointer, so the parameter requires deep | 1686 | * to dereference the passed pointer, so the parameter requires deep |
@@ -1808,18 +1861,25 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, | |||
1808 | in_iovs + out_iovs > FUSE_IOCTL_MAX_IOV) | 1861 | in_iovs + out_iovs > FUSE_IOCTL_MAX_IOV) |
1809 | goto out; | 1862 | goto out; |
1810 | 1863 | ||
1811 | err = -EIO; | ||
1812 | if ((in_iovs + out_iovs) * sizeof(struct iovec) != transferred) | ||
1813 | goto out; | ||
1814 | |||
1815 | /* okay, copy in iovs and retry */ | ||
1816 | vaddr = kmap_atomic(pages[0], KM_USER0); | 1864 | vaddr = kmap_atomic(pages[0], KM_USER0); |
1817 | memcpy(page_address(iov_page), vaddr, transferred); | 1865 | err = fuse_copy_ioctl_iovec(page_address(iov_page), vaddr, |
1866 | transferred, in_iovs + out_iovs, | ||
1867 | (flags & FUSE_IOCTL_COMPAT) != 0); | ||
1818 | kunmap_atomic(vaddr, KM_USER0); | 1868 | kunmap_atomic(vaddr, KM_USER0); |
1869 | if (err) | ||
1870 | goto out; | ||
1819 | 1871 | ||
1820 | in_iov = page_address(iov_page); | 1872 | in_iov = page_address(iov_page); |
1821 | out_iov = in_iov + in_iovs; | 1873 | out_iov = in_iov + in_iovs; |
1822 | 1874 | ||
1875 | err = fuse_verify_ioctl_iov(in_iov, in_iovs); | ||
1876 | if (err) | ||
1877 | goto out; | ||
1878 | |||
1879 | err = fuse_verify_ioctl_iov(out_iov, out_iovs); | ||
1880 | if (err) | ||
1881 | goto out; | ||
1882 | |||
1823 | goto retry; | 1883 | goto retry; |
1824 | } | 1884 | } |
1825 | 1885 | ||
diff --git a/fs/logfs/journal.c b/fs/logfs/journal.c index f46ee8b0e135..9da29706f91c 100644 --- a/fs/logfs/journal.c +++ b/fs/logfs/journal.c | |||
@@ -828,7 +828,7 @@ void do_logfs_journal_wl_pass(struct super_block *sb) | |||
828 | super->s_journal_seg[i] = segno; | 828 | super->s_journal_seg[i] = segno; |
829 | super->s_journal_ec[i] = ec; | 829 | super->s_journal_ec[i] = ec; |
830 | logfs_set_segment_reserved(sb, segno); | 830 | logfs_set_segment_reserved(sb, segno); |
831 | err = btree_insert32(head, segno, (void *)1, GFP_KERNEL); | 831 | err = btree_insert32(head, segno, (void *)1, GFP_NOFS); |
832 | BUG_ON(err); /* mempool should prevent this */ | 832 | BUG_ON(err); /* mempool should prevent this */ |
833 | err = logfs_erase_segment(sb, segno, 1); | 833 | err = logfs_erase_segment(sb, segno, 1); |
834 | BUG_ON(err); /* FIXME: remount-ro would be nicer */ | 834 | BUG_ON(err); /* FIXME: remount-ro would be nicer */ |
diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c index 6127baf0e188..ee99a9f5dfd3 100644 --- a/fs/logfs/readwrite.c +++ b/fs/logfs/readwrite.c | |||
@@ -1994,6 +1994,9 @@ static int do_write_inode(struct inode *inode) | |||
1994 | 1994 | ||
1995 | /* FIXME: transaction is part of logfs_block now. Is that enough? */ | 1995 | /* FIXME: transaction is part of logfs_block now. Is that enough? */ |
1996 | err = logfs_write_buf(master_inode, page, 0); | 1996 | err = logfs_write_buf(master_inode, page, 0); |
1997 | if (err) | ||
1998 | move_page_to_inode(inode, page); | ||
1999 | |||
1997 | logfs_put_write_page(page); | 2000 | logfs_put_write_page(page); |
1998 | return err; | 2001 | return err; |
1999 | } | 2002 | } |
diff --git a/fs/namei.c b/fs/namei.c index 5362af9b7372..4ff7ca530533 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1748,6 +1748,9 @@ struct file *do_filp_open(int dfd, const char *pathname, | |||
1748 | if (!(open_flag & O_CREAT)) | 1748 | if (!(open_flag & O_CREAT)) |
1749 | mode = 0; | 1749 | mode = 0; |
1750 | 1750 | ||
1751 | /* Must never be set by userspace */ | ||
1752 | open_flag &= ~FMODE_NONOTIFY; | ||
1753 | |||
1751 | /* | 1754 | /* |
1752 | * O_SYNC is implemented as __O_SYNC|O_DSYNC. As many places only | 1755 | * O_SYNC is implemented as __O_SYNC|O_DSYNC. As many places only |
1753 | * check for O_DSYNC if the need any syncing at all we enforce it's | 1756 | * check for O_DSYNC if the need any syncing at all we enforce it's |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index f0a384e2ae63..996dd8989a91 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -57,7 +57,7 @@ static int nfs_rename(struct inode *, struct dentry *, | |||
57 | struct inode *, struct dentry *); | 57 | struct inode *, struct dentry *); |
58 | static int nfs_fsync_dir(struct file *, int); | 58 | static int nfs_fsync_dir(struct file *, int); |
59 | static loff_t nfs_llseek_dir(struct file *, loff_t, int); | 59 | static loff_t nfs_llseek_dir(struct file *, loff_t, int); |
60 | static int nfs_readdir_clear_array(struct page*, gfp_t); | 60 | static void nfs_readdir_clear_array(struct page*); |
61 | 61 | ||
62 | const struct file_operations nfs_dir_operations = { | 62 | const struct file_operations nfs_dir_operations = { |
63 | .llseek = nfs_llseek_dir, | 63 | .llseek = nfs_llseek_dir, |
@@ -83,8 +83,8 @@ const struct inode_operations nfs_dir_inode_operations = { | |||
83 | .setattr = nfs_setattr, | 83 | .setattr = nfs_setattr, |
84 | }; | 84 | }; |
85 | 85 | ||
86 | const struct address_space_operations nfs_dir_addr_space_ops = { | 86 | const struct address_space_operations nfs_dir_aops = { |
87 | .releasepage = nfs_readdir_clear_array, | 87 | .freepage = nfs_readdir_clear_array, |
88 | }; | 88 | }; |
89 | 89 | ||
90 | #ifdef CONFIG_NFS_V3 | 90 | #ifdef CONFIG_NFS_V3 |
@@ -178,6 +178,7 @@ typedef struct { | |||
178 | struct page *page; | 178 | struct page *page; |
179 | unsigned long page_index; | 179 | unsigned long page_index; |
180 | u64 *dir_cookie; | 180 | u64 *dir_cookie; |
181 | u64 last_cookie; | ||
181 | loff_t current_index; | 182 | loff_t current_index; |
182 | decode_dirent_t decode; | 183 | decode_dirent_t decode; |
183 | 184 | ||
@@ -213,17 +214,15 @@ void nfs_readdir_release_array(struct page *page) | |||
213 | * we are freeing strings created by nfs_add_to_readdir_array() | 214 | * we are freeing strings created by nfs_add_to_readdir_array() |
214 | */ | 215 | */ |
215 | static | 216 | static |
216 | int nfs_readdir_clear_array(struct page *page, gfp_t mask) | 217 | void nfs_readdir_clear_array(struct page *page) |
217 | { | 218 | { |
218 | struct nfs_cache_array *array = nfs_readdir_get_array(page); | 219 | struct nfs_cache_array *array; |
219 | int i; | 220 | int i; |
220 | 221 | ||
221 | if (IS_ERR(array)) | 222 | array = kmap_atomic(page, KM_USER0); |
222 | return PTR_ERR(array); | ||
223 | for (i = 0; i < array->size; i++) | 223 | for (i = 0; i < array->size; i++) |
224 | kfree(array->array[i].string.name); | 224 | kfree(array->array[i].string.name); |
225 | nfs_readdir_release_array(page); | 225 | kunmap_atomic(array, KM_USER0); |
226 | return 0; | ||
227 | } | 226 | } |
228 | 227 | ||
229 | /* | 228 | /* |
@@ -272,7 +271,7 @@ int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page) | |||
272 | goto out; | 271 | goto out; |
273 | array->last_cookie = entry->cookie; | 272 | array->last_cookie = entry->cookie; |
274 | array->size++; | 273 | array->size++; |
275 | if (entry->eof == 1) | 274 | if (entry->eof != 0) |
276 | array->eof_index = array->size; | 275 | array->eof_index = array->size; |
277 | out: | 276 | out: |
278 | nfs_readdir_release_array(page); | 277 | nfs_readdir_release_array(page); |
@@ -312,15 +311,14 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des | |||
312 | for (i = 0; i < array->size; i++) { | 311 | for (i = 0; i < array->size; i++) { |
313 | if (array->array[i].cookie == *desc->dir_cookie) { | 312 | if (array->array[i].cookie == *desc->dir_cookie) { |
314 | desc->cache_entry_index = i; | 313 | desc->cache_entry_index = i; |
315 | status = 0; | 314 | return 0; |
316 | goto out; | ||
317 | } | 315 | } |
318 | } | 316 | } |
319 | if (i == array->eof_index) { | 317 | if (array->eof_index >= 0) { |
320 | desc->eof = 1; | ||
321 | status = -EBADCOOKIE; | 318 | status = -EBADCOOKIE; |
319 | if (*desc->dir_cookie == array->last_cookie) | ||
320 | desc->eof = 1; | ||
322 | } | 321 | } |
323 | out: | ||
324 | return status; | 322 | return status; |
325 | } | 323 | } |
326 | 324 | ||
@@ -328,10 +326,7 @@ static | |||
328 | int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc) | 326 | int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc) |
329 | { | 327 | { |
330 | struct nfs_cache_array *array; | 328 | struct nfs_cache_array *array; |
331 | int status = -EBADCOOKIE; | 329 | int status; |
332 | |||
333 | if (desc->dir_cookie == NULL) | ||
334 | goto out; | ||
335 | 330 | ||
336 | array = nfs_readdir_get_array(desc->page); | 331 | array = nfs_readdir_get_array(desc->page); |
337 | if (IS_ERR(array)) { | 332 | if (IS_ERR(array)) { |
@@ -344,6 +339,10 @@ int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc) | |||
344 | else | 339 | else |
345 | status = nfs_readdir_search_for_cookie(array, desc); | 340 | status = nfs_readdir_search_for_cookie(array, desc); |
346 | 341 | ||
342 | if (status == -EAGAIN) { | ||
343 | desc->last_cookie = array->last_cookie; | ||
344 | desc->page_index++; | ||
345 | } | ||
347 | nfs_readdir_release_array(desc->page); | 346 | nfs_readdir_release_array(desc->page); |
348 | out: | 347 | out: |
349 | return status; | 348 | return status; |
@@ -490,7 +489,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en | |||
490 | 489 | ||
491 | count++; | 490 | count++; |
492 | 491 | ||
493 | if (desc->plus == 1) | 492 | if (desc->plus != 0) |
494 | nfs_prime_dcache(desc->file->f_path.dentry, entry); | 493 | nfs_prime_dcache(desc->file->f_path.dentry, entry); |
495 | 494 | ||
496 | status = nfs_readdir_add_to_array(entry, page); | 495 | status = nfs_readdir_add_to_array(entry, page); |
@@ -498,7 +497,7 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en | |||
498 | break; | 497 | break; |
499 | } while (!entry->eof); | 498 | } while (!entry->eof); |
500 | 499 | ||
501 | if (count == 0 || (status == -EBADCOOKIE && entry->eof == 1)) { | 500 | if (count == 0 || (status == -EBADCOOKIE && entry->eof != 0)) { |
502 | array = nfs_readdir_get_array(page); | 501 | array = nfs_readdir_get_array(page); |
503 | if (!IS_ERR(array)) { | 502 | if (!IS_ERR(array)) { |
504 | array->eof_index = array->size; | 503 | array->eof_index = array->size; |
@@ -563,7 +562,7 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page, | |||
563 | unsigned int array_size = ARRAY_SIZE(pages); | 562 | unsigned int array_size = ARRAY_SIZE(pages); |
564 | 563 | ||
565 | entry.prev_cookie = 0; | 564 | entry.prev_cookie = 0; |
566 | entry.cookie = *desc->dir_cookie; | 565 | entry.cookie = desc->last_cookie; |
567 | entry.eof = 0; | 566 | entry.eof = 0; |
568 | entry.fh = nfs_alloc_fhandle(); | 567 | entry.fh = nfs_alloc_fhandle(); |
569 | entry.fattr = nfs_alloc_fattr(); | 568 | entry.fattr = nfs_alloc_fattr(); |
@@ -636,6 +635,8 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page* page) | |||
636 | static | 635 | static |
637 | void cache_page_release(nfs_readdir_descriptor_t *desc) | 636 | void cache_page_release(nfs_readdir_descriptor_t *desc) |
638 | { | 637 | { |
638 | if (!desc->page->mapping) | ||
639 | nfs_readdir_clear_array(desc->page); | ||
639 | page_cache_release(desc->page); | 640 | page_cache_release(desc->page); |
640 | desc->page = NULL; | 641 | desc->page = NULL; |
641 | } | 642 | } |
@@ -660,9 +661,8 @@ int find_cache_page(nfs_readdir_descriptor_t *desc) | |||
660 | return PTR_ERR(desc->page); | 661 | return PTR_ERR(desc->page); |
661 | 662 | ||
662 | res = nfs_readdir_search_array(desc); | 663 | res = nfs_readdir_search_array(desc); |
663 | if (res == 0) | 664 | if (res != 0) |
664 | return 0; | 665 | cache_page_release(desc); |
665 | cache_page_release(desc); | ||
666 | return res; | 666 | return res; |
667 | } | 667 | } |
668 | 668 | ||
@@ -672,22 +672,16 @@ int readdir_search_pagecache(nfs_readdir_descriptor_t *desc) | |||
672 | { | 672 | { |
673 | int res; | 673 | int res; |
674 | 674 | ||
675 | if (desc->page_index == 0) | 675 | if (desc->page_index == 0) { |
676 | desc->current_index = 0; | 676 | desc->current_index = 0; |
677 | while (1) { | 677 | desc->last_cookie = 0; |
678 | res = find_cache_page(desc); | ||
679 | if (res != -EAGAIN) | ||
680 | break; | ||
681 | desc->page_index++; | ||
682 | } | 678 | } |
679 | do { | ||
680 | res = find_cache_page(desc); | ||
681 | } while (res == -EAGAIN); | ||
683 | return res; | 682 | return res; |
684 | } | 683 | } |
685 | 684 | ||
686 | static inline unsigned int dt_type(struct inode *inode) | ||
687 | { | ||
688 | return (inode->i_mode >> 12) & 15; | ||
689 | } | ||
690 | |||
691 | /* | 685 | /* |
692 | * Once we've found the start of the dirent within a page: fill 'er up... | 686 | * Once we've found the start of the dirent within a page: fill 'er up... |
693 | */ | 687 | */ |
@@ -717,13 +711,12 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent, | |||
717 | break; | 711 | break; |
718 | } | 712 | } |
719 | file->f_pos++; | 713 | file->f_pos++; |
720 | desc->cache_entry_index = i; | ||
721 | if (i < (array->size-1)) | 714 | if (i < (array->size-1)) |
722 | *desc->dir_cookie = array->array[i+1].cookie; | 715 | *desc->dir_cookie = array->array[i+1].cookie; |
723 | else | 716 | else |
724 | *desc->dir_cookie = array->last_cookie; | 717 | *desc->dir_cookie = array->last_cookie; |
725 | } | 718 | } |
726 | if (i == array->eof_index) | 719 | if (array->eof_index >= 0) |
727 | desc->eof = 1; | 720 | desc->eof = 1; |
728 | 721 | ||
729 | nfs_readdir_release_array(desc->page); | 722 | nfs_readdir_release_array(desc->page); |
@@ -764,6 +757,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent, | |||
764 | } | 757 | } |
765 | 758 | ||
766 | desc->page_index = 0; | 759 | desc->page_index = 0; |
760 | desc->last_cookie = *desc->dir_cookie; | ||
767 | desc->page = page; | 761 | desc->page = page; |
768 | 762 | ||
769 | status = nfs_readdir_xdr_to_array(desc, page, inode); | 763 | status = nfs_readdir_xdr_to_array(desc, page, inode); |
@@ -791,7 +785,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
791 | struct inode *inode = dentry->d_inode; | 785 | struct inode *inode = dentry->d_inode; |
792 | nfs_readdir_descriptor_t my_desc, | 786 | nfs_readdir_descriptor_t my_desc, |
793 | *desc = &my_desc; | 787 | *desc = &my_desc; |
794 | int res = -ENOMEM; | 788 | int res; |
795 | 789 | ||
796 | dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n", | 790 | dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n", |
797 | dentry->d_parent->d_name.name, dentry->d_name.name, | 791 | dentry->d_parent->d_name.name, dentry->d_name.name, |
@@ -816,7 +810,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
816 | if (res < 0) | 810 | if (res < 0) |
817 | goto out; | 811 | goto out; |
818 | 812 | ||
819 | while (desc->eof != 1) { | 813 | do { |
820 | res = readdir_search_pagecache(desc); | 814 | res = readdir_search_pagecache(desc); |
821 | 815 | ||
822 | if (res == -EBADCOOKIE) { | 816 | if (res == -EBADCOOKIE) { |
@@ -844,7 +838,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
844 | res = nfs_do_filldir(desc, dirent, filldir); | 838 | res = nfs_do_filldir(desc, dirent, filldir); |
845 | if (res < 0) | 839 | if (res < 0) |
846 | break; | 840 | break; |
847 | } | 841 | } while (!desc->eof); |
848 | out: | 842 | out: |
849 | nfs_unblock_sillyrename(dentry); | 843 | nfs_unblock_sillyrename(dentry); |
850 | if (res > 0) | 844 | if (res > 0) |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 60677f9f1311..7bf029ef4084 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -693,6 +693,7 @@ do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local) | |||
693 | { | 693 | { |
694 | struct inode *inode = filp->f_mapping->host; | 694 | struct inode *inode = filp->f_mapping->host; |
695 | int status = 0; | 695 | int status = 0; |
696 | unsigned int saved_type = fl->fl_type; | ||
696 | 697 | ||
697 | /* Try local locking first */ | 698 | /* Try local locking first */ |
698 | posix_test_lock(filp, fl); | 699 | posix_test_lock(filp, fl); |
@@ -700,6 +701,7 @@ do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local) | |||
700 | /* found a conflict */ | 701 | /* found a conflict */ |
701 | goto out; | 702 | goto out; |
702 | } | 703 | } |
704 | fl->fl_type = saved_type; | ||
703 | 705 | ||
704 | if (nfs_have_delegation(inode, FMODE_READ)) | 706 | if (nfs_have_delegation(inode, FMODE_READ)) |
705 | goto out_noconflict; | 707 | goto out_noconflict; |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 314f57164602..e67e31c73416 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -289,6 +289,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) | |||
289 | } else if (S_ISDIR(inode->i_mode)) { | 289 | } else if (S_ISDIR(inode->i_mode)) { |
290 | inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops; | 290 | inode->i_op = NFS_SB(sb)->nfs_client->rpc_ops->dir_inode_ops; |
291 | inode->i_fop = &nfs_dir_operations; | 291 | inode->i_fop = &nfs_dir_operations; |
292 | inode->i_data.a_ops = &nfs_dir_aops; | ||
292 | if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS)) | 293 | if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS)) |
293 | set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags); | 294 | set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags); |
294 | /* Deal with crossing mountpoints */ | 295 | /* Deal with crossing mountpoints */ |
diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c index eceafe74f473..4f981f1f6689 100644 --- a/fs/nfs/mount_clnt.c +++ b/fs/nfs/mount_clnt.c | |||
@@ -505,13 +505,13 @@ static struct rpc_procinfo mnt3_procedures[] = { | |||
505 | 505 | ||
506 | static struct rpc_version mnt_version1 = { | 506 | static struct rpc_version mnt_version1 = { |
507 | .number = 1, | 507 | .number = 1, |
508 | .nrprocs = 2, | 508 | .nrprocs = ARRAY_SIZE(mnt_procedures), |
509 | .procs = mnt_procedures, | 509 | .procs = mnt_procedures, |
510 | }; | 510 | }; |
511 | 511 | ||
512 | static struct rpc_version mnt_version3 = { | 512 | static struct rpc_version mnt_version3 = { |
513 | .number = 3, | 513 | .number = 3, |
514 | .nrprocs = 2, | 514 | .nrprocs = ARRAY_SIZE(mnt3_procedures), |
515 | .procs = mnt3_procedures, | 515 | .procs = mnt3_procedures, |
516 | }; | 516 | }; |
517 | 517 | ||
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 6a653ffd8e4e..4435e5e1f904 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -3361,6 +3361,8 @@ static ssize_t nfs4_proc_get_acl(struct inode *inode, void *buf, size_t buflen) | |||
3361 | ret = nfs_revalidate_inode(server, inode); | 3361 | ret = nfs_revalidate_inode(server, inode); |
3362 | if (ret < 0) | 3362 | if (ret < 0) |
3363 | return ret; | 3363 | return ret; |
3364 | if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL) | ||
3365 | nfs_zap_acl_cache(inode); | ||
3364 | ret = nfs4_read_cached_acl(inode, buf, buflen); | 3366 | ret = nfs4_read_cached_acl(inode, buf, buflen); |
3365 | if (ret != -ENOENT) | 3367 | if (ret != -ENOENT) |
3366 | return ret; | 3368 | return ret; |
@@ -3389,6 +3391,13 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl | |||
3389 | nfs_inode_return_delegation(inode); | 3391 | nfs_inode_return_delegation(inode); |
3390 | buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase); | 3392 | buf_to_pages(buf, buflen, arg.acl_pages, &arg.acl_pgbase); |
3391 | ret = nfs4_call_sync(server, &msg, &arg, &res, 1); | 3393 | ret = nfs4_call_sync(server, &msg, &arg, &res, 1); |
3394 | /* | ||
3395 | * Acl update can result in inode attribute update. | ||
3396 | * so mark the attribute cache invalid. | ||
3397 | */ | ||
3398 | spin_lock(&inode->i_lock); | ||
3399 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR; | ||
3400 | spin_unlock(&inode->i_lock); | ||
3392 | nfs_access_zap_cache(inode); | 3401 | nfs_access_zap_cache(inode); |
3393 | nfs_zap_acl_cache(inode); | 3402 | nfs_zap_acl_cache(inode); |
3394 | return ret; | 3403 | return ret; |
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 137b549e63db..b68536cc9046 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c | |||
@@ -115,7 +115,7 @@ int nfs_set_page_tag_locked(struct nfs_page *req) | |||
115 | { | 115 | { |
116 | if (!nfs_lock_request_dontget(req)) | 116 | if (!nfs_lock_request_dontget(req)) |
117 | return 0; | 117 | return 0; |
118 | if (req->wb_page != NULL) | 118 | if (test_bit(PG_MAPPED, &req->wb_flags)) |
119 | radix_tree_tag_set(&NFS_I(req->wb_context->path.dentry->d_inode)->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED); | 119 | radix_tree_tag_set(&NFS_I(req->wb_context->path.dentry->d_inode)->nfs_page_tree, req->wb_index, NFS_PAGE_TAG_LOCKED); |
120 | return 1; | 120 | return 1; |
121 | } | 121 | } |
@@ -125,7 +125,7 @@ int nfs_set_page_tag_locked(struct nfs_page *req) | |||
125 | */ | 125 | */ |
126 | void nfs_clear_page_tag_locked(struct nfs_page *req) | 126 | void nfs_clear_page_tag_locked(struct nfs_page *req) |
127 | { | 127 | { |
128 | if (req->wb_page != NULL) { | 128 | if (test_bit(PG_MAPPED, &req->wb_flags)) { |
129 | struct inode *inode = req->wb_context->path.dentry->d_inode; | 129 | struct inode *inode = req->wb_context->path.dentry->d_inode; |
130 | struct nfs_inode *nfsi = NFS_I(inode); | 130 | struct nfs_inode *nfsi = NFS_I(inode); |
131 | 131 | ||
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index e4b62c6f5a6e..aedcaa7f291f 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -152,7 +152,6 @@ static void nfs_readpage_release(struct nfs_page *req) | |||
152 | (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode), | 152 | (long long)NFS_FILEID(req->wb_context->path.dentry->d_inode), |
153 | req->wb_bytes, | 153 | req->wb_bytes, |
154 | (long long)req_offset(req)); | 154 | (long long)req_offset(req)); |
155 | nfs_clear_request(req); | ||
156 | nfs_release_request(req); | 155 | nfs_release_request(req); |
157 | } | 156 | } |
158 | 157 | ||
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 3c045044fca2..4100630c9a5b 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -1069,12 +1069,10 @@ static int nfs_parse_mount_options(char *raw, | |||
1069 | mnt->flags |= NFS_MOUNT_VER3; | 1069 | mnt->flags |= NFS_MOUNT_VER3; |
1070 | mnt->version = 3; | 1070 | mnt->version = 3; |
1071 | break; | 1071 | break; |
1072 | #ifdef CONFIG_NFS_V4 | ||
1073 | case Opt_v4: | 1072 | case Opt_v4: |
1074 | mnt->flags &= ~NFS_MOUNT_VER3; | 1073 | mnt->flags &= ~NFS_MOUNT_VER3; |
1075 | mnt->version = 4; | 1074 | mnt->version = 4; |
1076 | break; | 1075 | break; |
1077 | #endif | ||
1078 | case Opt_udp: | 1076 | case Opt_udp: |
1079 | mnt->flags &= ~NFS_MOUNT_TCP; | 1077 | mnt->flags &= ~NFS_MOUNT_TCP; |
1080 | mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; | 1078 | mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP; |
@@ -1286,12 +1284,10 @@ static int nfs_parse_mount_options(char *raw, | |||
1286 | mnt->flags |= NFS_MOUNT_VER3; | 1284 | mnt->flags |= NFS_MOUNT_VER3; |
1287 | mnt->version = 3; | 1285 | mnt->version = 3; |
1288 | break; | 1286 | break; |
1289 | #ifdef CONFIG_NFS_V4 | ||
1290 | case NFS4_VERSION: | 1287 | case NFS4_VERSION: |
1291 | mnt->flags &= ~NFS_MOUNT_VER3; | 1288 | mnt->flags &= ~NFS_MOUNT_VER3; |
1292 | mnt->version = 4; | 1289 | mnt->version = 4; |
1293 | break; | 1290 | break; |
1294 | #endif | ||
1295 | default: | 1291 | default: |
1296 | goto out_invalid_value; | 1292 | goto out_invalid_value; |
1297 | } | 1293 | } |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 4c14c17a5276..10d648ea128b 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -390,6 +390,7 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req) | |||
390 | if (nfs_have_delegation(inode, FMODE_WRITE)) | 390 | if (nfs_have_delegation(inode, FMODE_WRITE)) |
391 | nfsi->change_attr++; | 391 | nfsi->change_attr++; |
392 | } | 392 | } |
393 | set_bit(PG_MAPPED, &req->wb_flags); | ||
393 | SetPagePrivate(req->wb_page); | 394 | SetPagePrivate(req->wb_page); |
394 | set_page_private(req->wb_page, (unsigned long)req); | 395 | set_page_private(req->wb_page, (unsigned long)req); |
395 | nfsi->npages++; | 396 | nfsi->npages++; |
@@ -415,6 +416,7 @@ static void nfs_inode_remove_request(struct nfs_page *req) | |||
415 | spin_lock(&inode->i_lock); | 416 | spin_lock(&inode->i_lock); |
416 | set_page_private(req->wb_page, 0); | 417 | set_page_private(req->wb_page, 0); |
417 | ClearPagePrivate(req->wb_page); | 418 | ClearPagePrivate(req->wb_page); |
419 | clear_bit(PG_MAPPED, &req->wb_flags); | ||
418 | radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index); | 420 | radix_tree_delete(&nfsi->nfs_page_tree, req->wb_index); |
419 | nfsi->npages--; | 421 | nfsi->npages--; |
420 | if (!nfsi->npages) { | 422 | if (!nfsi->npages) { |
@@ -422,7 +424,6 @@ static void nfs_inode_remove_request(struct nfs_page *req) | |||
422 | iput(inode); | 424 | iput(inode); |
423 | } else | 425 | } else |
424 | spin_unlock(&inode->i_lock); | 426 | spin_unlock(&inode->i_lock); |
425 | nfs_clear_request(req); | ||
426 | nfs_release_request(req); | 427 | nfs_release_request(req); |
427 | } | 428 | } |
428 | 429 | ||
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 2a533a0af2a9..7e84a852cdae 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c | |||
@@ -260,9 +260,11 @@ void fill_post_wcc(struct svc_fh *fhp) | |||
260 | err = vfs_getattr(fhp->fh_export->ex_path.mnt, fhp->fh_dentry, | 260 | err = vfs_getattr(fhp->fh_export->ex_path.mnt, fhp->fh_dentry, |
261 | &fhp->fh_post_attr); | 261 | &fhp->fh_post_attr); |
262 | fhp->fh_post_change = fhp->fh_dentry->d_inode->i_version; | 262 | fhp->fh_post_change = fhp->fh_dentry->d_inode->i_version; |
263 | if (err) | 263 | if (err) { |
264 | fhp->fh_post_saved = 0; | 264 | fhp->fh_post_saved = 0; |
265 | else | 265 | /* Grab the ctime anyway - set_change_info might use it */ |
266 | fhp->fh_post_attr.ctime = fhp->fh_dentry->d_inode->i_ctime; | ||
267 | } else | ||
266 | fhp->fh_post_saved = 1; | 268 | fhp->fh_post_saved = 1; |
267 | } | 269 | } |
268 | 270 | ||
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 4d476ff08ae6..60fce3dc5cb5 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h | |||
@@ -484,18 +484,17 @@ static inline bool nfsd4_not_cached(struct nfsd4_compoundres *resp) | |||
484 | static inline void | 484 | static inline void |
485 | set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp) | 485 | set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp) |
486 | { | 486 | { |
487 | BUG_ON(!fhp->fh_pre_saved || !fhp->fh_post_saved); | 487 | BUG_ON(!fhp->fh_pre_saved); |
488 | cinfo->atomic = 1; | 488 | cinfo->atomic = fhp->fh_post_saved; |
489 | cinfo->change_supported = IS_I_VERSION(fhp->fh_dentry->d_inode); | 489 | cinfo->change_supported = IS_I_VERSION(fhp->fh_dentry->d_inode); |
490 | if (cinfo->change_supported) { | 490 | |
491 | cinfo->before_change = fhp->fh_pre_change; | 491 | cinfo->before_change = fhp->fh_pre_change; |
492 | cinfo->after_change = fhp->fh_post_change; | 492 | cinfo->after_change = fhp->fh_post_change; |
493 | } else { | 493 | cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec; |
494 | cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec; | 494 | cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec; |
495 | cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec; | 495 | cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec; |
496 | cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec; | 496 | cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec; |
497 | cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec; | 497 | |
498 | } | ||
499 | } | 498 | } |
500 | 499 | ||
501 | int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *); | 500 | int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *); |
diff --git a/fs/nilfs2/gcinode.c b/fs/nilfs2/gcinode.c index 33ad25ddd5c4..caf9a6a3fb54 100644 --- a/fs/nilfs2/gcinode.c +++ b/fs/nilfs2/gcinode.c | |||
@@ -176,7 +176,6 @@ int nilfs_gccache_wait_and_mark_dirty(struct buffer_head *bh) | |||
176 | int nilfs_init_gcinode(struct inode *inode) | 176 | int nilfs_init_gcinode(struct inode *inode) |
177 | { | 177 | { |
178 | struct nilfs_inode_info *ii = NILFS_I(inode); | 178 | struct nilfs_inode_info *ii = NILFS_I(inode); |
179 | struct the_nilfs *nilfs = NILFS_SB(inode->i_sb)->s_nilfs; | ||
180 | 179 | ||
181 | inode->i_mode = S_IFREG; | 180 | inode->i_mode = S_IFREG; |
182 | mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); | 181 | mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); |
@@ -186,14 +185,6 @@ int nilfs_init_gcinode(struct inode *inode) | |||
186 | ii->i_flags = 0; | 185 | ii->i_flags = 0; |
187 | nilfs_bmap_init_gc(ii->i_bmap); | 186 | nilfs_bmap_init_gc(ii->i_bmap); |
188 | 187 | ||
189 | /* | ||
190 | * Add the inode to GC inode list. Garbage Collection | ||
191 | * is serialized and no two processes manipulate the | ||
192 | * list simultaneously. | ||
193 | */ | ||
194 | igrab(inode); | ||
195 | list_add(&NILFS_I(inode)->i_dirty, &nilfs->ns_gc_inodes); | ||
196 | |||
197 | return 0; | 188 | return 0; |
198 | } | 189 | } |
199 | 190 | ||
diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index e00d9457c256..b185e937a335 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c | |||
@@ -337,6 +337,7 @@ static int nilfs_ioctl_move_blocks(struct super_block *sb, | |||
337 | struct nilfs_argv *argv, void *buf) | 337 | struct nilfs_argv *argv, void *buf) |
338 | { | 338 | { |
339 | size_t nmembs = argv->v_nmembs; | 339 | size_t nmembs = argv->v_nmembs; |
340 | struct the_nilfs *nilfs = NILFS_SB(sb)->s_nilfs; | ||
340 | struct inode *inode; | 341 | struct inode *inode; |
341 | struct nilfs_vdesc *vdesc; | 342 | struct nilfs_vdesc *vdesc; |
342 | struct buffer_head *bh, *n; | 343 | struct buffer_head *bh, *n; |
@@ -353,6 +354,17 @@ static int nilfs_ioctl_move_blocks(struct super_block *sb, | |||
353 | ret = PTR_ERR(inode); | 354 | ret = PTR_ERR(inode); |
354 | goto failed; | 355 | goto failed; |
355 | } | 356 | } |
357 | if (list_empty(&NILFS_I(inode)->i_dirty)) { | ||
358 | /* | ||
359 | * Add the inode to GC inode list. Garbage Collection | ||
360 | * is serialized and no two processes manipulate the | ||
361 | * list simultaneously. | ||
362 | */ | ||
363 | igrab(inode); | ||
364 | list_add(&NILFS_I(inode)->i_dirty, | ||
365 | &nilfs->ns_gc_inodes); | ||
366 | } | ||
367 | |||
356 | do { | 368 | do { |
357 | ret = nilfs_ioctl_move_inode_block(inode, vdesc, | 369 | ret = nilfs_ioctl_move_inode_block(inode, vdesc, |
358 | &buffers); | 370 | &buffers); |
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index b04f88eed09e..f35794b97e8e 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c | |||
@@ -92,7 +92,11 @@ static int fanotify_get_response_from_access(struct fsnotify_group *group, | |||
92 | 92 | ||
93 | pr_debug("%s: group=%p event=%p\n", __func__, group, event); | 93 | pr_debug("%s: group=%p event=%p\n", __func__, group, event); |
94 | 94 | ||
95 | wait_event(group->fanotify_data.access_waitq, event->response); | 95 | wait_event(group->fanotify_data.access_waitq, event->response || |
96 | atomic_read(&group->fanotify_data.bypass_perm)); | ||
97 | |||
98 | if (!event->response) /* bypass_perm set */ | ||
99 | return 0; | ||
96 | 100 | ||
97 | /* userspace responded, convert to something usable */ | 101 | /* userspace responded, convert to something usable */ |
98 | spin_lock(&event->lock); | 102 | spin_lock(&event->lock); |
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 063224812b7e..8b61220cffc5 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
@@ -106,20 +106,29 @@ static int create_fd(struct fsnotify_group *group, struct fsnotify_event *event) | |||
106 | return client_fd; | 106 | return client_fd; |
107 | } | 107 | } |
108 | 108 | ||
109 | static ssize_t fill_event_metadata(struct fsnotify_group *group, | 109 | static int fill_event_metadata(struct fsnotify_group *group, |
110 | struct fanotify_event_metadata *metadata, | 110 | struct fanotify_event_metadata *metadata, |
111 | struct fsnotify_event *event) | 111 | struct fsnotify_event *event) |
112 | { | 112 | { |
113 | int ret = 0; | ||
114 | |||
113 | pr_debug("%s: group=%p metadata=%p event=%p\n", __func__, | 115 | pr_debug("%s: group=%p metadata=%p event=%p\n", __func__, |
114 | group, metadata, event); | 116 | group, metadata, event); |
115 | 117 | ||
116 | metadata->event_len = FAN_EVENT_METADATA_LEN; | 118 | metadata->event_len = FAN_EVENT_METADATA_LEN; |
119 | metadata->metadata_len = FAN_EVENT_METADATA_LEN; | ||
117 | metadata->vers = FANOTIFY_METADATA_VERSION; | 120 | metadata->vers = FANOTIFY_METADATA_VERSION; |
118 | metadata->mask = event->mask & FAN_ALL_OUTGOING_EVENTS; | 121 | metadata->mask = event->mask & FAN_ALL_OUTGOING_EVENTS; |
119 | metadata->pid = pid_vnr(event->tgid); | 122 | metadata->pid = pid_vnr(event->tgid); |
120 | metadata->fd = create_fd(group, event); | 123 | if (unlikely(event->mask & FAN_Q_OVERFLOW)) |
124 | metadata->fd = FAN_NOFD; | ||
125 | else { | ||
126 | metadata->fd = create_fd(group, event); | ||
127 | if (metadata->fd < 0) | ||
128 | ret = metadata->fd; | ||
129 | } | ||
121 | 130 | ||
122 | return metadata->fd; | 131 | return ret; |
123 | } | 132 | } |
124 | 133 | ||
125 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS | 134 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS |
@@ -200,7 +209,7 @@ static int prepare_for_access_response(struct fsnotify_group *group, | |||
200 | 209 | ||
201 | mutex_lock(&group->fanotify_data.access_mutex); | 210 | mutex_lock(&group->fanotify_data.access_mutex); |
202 | 211 | ||
203 | if (group->fanotify_data.bypass_perm) { | 212 | if (atomic_read(&group->fanotify_data.bypass_perm)) { |
204 | mutex_unlock(&group->fanotify_data.access_mutex); | 213 | mutex_unlock(&group->fanotify_data.access_mutex); |
205 | kmem_cache_free(fanotify_response_event_cache, re); | 214 | kmem_cache_free(fanotify_response_event_cache, re); |
206 | event->response = FAN_ALLOW; | 215 | event->response = FAN_ALLOW; |
@@ -257,24 +266,34 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group, | |||
257 | 266 | ||
258 | pr_debug("%s: group=%p event=%p\n", __func__, group, event); | 267 | pr_debug("%s: group=%p event=%p\n", __func__, group, event); |
259 | 268 | ||
260 | fd = fill_event_metadata(group, &fanotify_event_metadata, event); | 269 | ret = fill_event_metadata(group, &fanotify_event_metadata, event); |
261 | if (fd < 0) | 270 | if (ret < 0) |
262 | return fd; | 271 | goto out; |
263 | 272 | ||
273 | fd = fanotify_event_metadata.fd; | ||
264 | ret = prepare_for_access_response(group, event, fd); | 274 | ret = prepare_for_access_response(group, event, fd); |
265 | if (ret) | 275 | if (ret) |
266 | goto out_close_fd; | 276 | goto out_close_fd; |
267 | 277 | ||
268 | ret = -EFAULT; | 278 | ret = -EFAULT; |
269 | if (copy_to_user(buf, &fanotify_event_metadata, FAN_EVENT_METADATA_LEN)) | 279 | if (copy_to_user(buf, &fanotify_event_metadata, |
280 | fanotify_event_metadata.event_len)) | ||
270 | goto out_kill_access_response; | 281 | goto out_kill_access_response; |
271 | 282 | ||
272 | return FAN_EVENT_METADATA_LEN; | 283 | return fanotify_event_metadata.event_len; |
273 | 284 | ||
274 | out_kill_access_response: | 285 | out_kill_access_response: |
275 | remove_access_response(group, event, fd); | 286 | remove_access_response(group, event, fd); |
276 | out_close_fd: | 287 | out_close_fd: |
277 | sys_close(fd); | 288 | if (fd != FAN_NOFD) |
289 | sys_close(fd); | ||
290 | out: | ||
291 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS | ||
292 | if (event->mask & FAN_ALL_PERM_EVENTS) { | ||
293 | event->response = FAN_DENY; | ||
294 | wake_up(&group->fanotify_data.access_waitq); | ||
295 | } | ||
296 | #endif | ||
278 | return ret; | 297 | return ret; |
279 | } | 298 | } |
280 | 299 | ||
@@ -382,7 +401,7 @@ static int fanotify_release(struct inode *ignored, struct file *file) | |||
382 | 401 | ||
383 | mutex_lock(&group->fanotify_data.access_mutex); | 402 | mutex_lock(&group->fanotify_data.access_mutex); |
384 | 403 | ||
385 | group->fanotify_data.bypass_perm = true; | 404 | atomic_inc(&group->fanotify_data.bypass_perm); |
386 | 405 | ||
387 | list_for_each_entry_safe(re, lre, &group->fanotify_data.access_list, list) { | 406 | list_for_each_entry_safe(re, lre, &group->fanotify_data.access_list, list) { |
388 | pr_debug("%s: found group=%p re=%p event=%p\n", __func__, group, | 407 | pr_debug("%s: found group=%p re=%p event=%p\n", __func__, group, |
@@ -586,11 +605,10 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group, | |||
586 | { | 605 | { |
587 | struct fsnotify_mark *fsn_mark; | 606 | struct fsnotify_mark *fsn_mark; |
588 | __u32 added; | 607 | __u32 added; |
608 | int ret = 0; | ||
589 | 609 | ||
590 | fsn_mark = fsnotify_find_vfsmount_mark(group, mnt); | 610 | fsn_mark = fsnotify_find_vfsmount_mark(group, mnt); |
591 | if (!fsn_mark) { | 611 | if (!fsn_mark) { |
592 | int ret; | ||
593 | |||
594 | if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks) | 612 | if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks) |
595 | return -ENOSPC; | 613 | return -ENOSPC; |
596 | 614 | ||
@@ -600,17 +618,16 @@ static int fanotify_add_vfsmount_mark(struct fsnotify_group *group, | |||
600 | 618 | ||
601 | fsnotify_init_mark(fsn_mark, fanotify_free_mark); | 619 | fsnotify_init_mark(fsn_mark, fanotify_free_mark); |
602 | ret = fsnotify_add_mark(fsn_mark, group, NULL, mnt, 0); | 620 | ret = fsnotify_add_mark(fsn_mark, group, NULL, mnt, 0); |
603 | if (ret) { | 621 | if (ret) |
604 | fanotify_free_mark(fsn_mark); | 622 | goto err; |
605 | return ret; | ||
606 | } | ||
607 | } | 623 | } |
608 | added = fanotify_mark_add_to_mask(fsn_mark, mask, flags); | 624 | added = fanotify_mark_add_to_mask(fsn_mark, mask, flags); |
609 | fsnotify_put_mark(fsn_mark); | 625 | |
610 | if (added & ~mnt->mnt_fsnotify_mask) | 626 | if (added & ~mnt->mnt_fsnotify_mask) |
611 | fsnotify_recalc_vfsmount_mask(mnt); | 627 | fsnotify_recalc_vfsmount_mask(mnt); |
612 | 628 | err: | |
613 | return 0; | 629 | fsnotify_put_mark(fsn_mark); |
630 | return ret; | ||
614 | } | 631 | } |
615 | 632 | ||
616 | static int fanotify_add_inode_mark(struct fsnotify_group *group, | 633 | static int fanotify_add_inode_mark(struct fsnotify_group *group, |
@@ -619,6 +636,7 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group, | |||
619 | { | 636 | { |
620 | struct fsnotify_mark *fsn_mark; | 637 | struct fsnotify_mark *fsn_mark; |
621 | __u32 added; | 638 | __u32 added; |
639 | int ret = 0; | ||
622 | 640 | ||
623 | pr_debug("%s: group=%p inode=%p\n", __func__, group, inode); | 641 | pr_debug("%s: group=%p inode=%p\n", __func__, group, inode); |
624 | 642 | ||
@@ -634,8 +652,6 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group, | |||
634 | 652 | ||
635 | fsn_mark = fsnotify_find_inode_mark(group, inode); | 653 | fsn_mark = fsnotify_find_inode_mark(group, inode); |
636 | if (!fsn_mark) { | 654 | if (!fsn_mark) { |
637 | int ret; | ||
638 | |||
639 | if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks) | 655 | if (atomic_read(&group->num_marks) > group->fanotify_data.max_marks) |
640 | return -ENOSPC; | 656 | return -ENOSPC; |
641 | 657 | ||
@@ -645,16 +661,16 @@ static int fanotify_add_inode_mark(struct fsnotify_group *group, | |||
645 | 661 | ||
646 | fsnotify_init_mark(fsn_mark, fanotify_free_mark); | 662 | fsnotify_init_mark(fsn_mark, fanotify_free_mark); |
647 | ret = fsnotify_add_mark(fsn_mark, group, inode, NULL, 0); | 663 | ret = fsnotify_add_mark(fsn_mark, group, inode, NULL, 0); |
648 | if (ret) { | 664 | if (ret) |
649 | fanotify_free_mark(fsn_mark); | 665 | goto err; |
650 | return ret; | ||
651 | } | ||
652 | } | 666 | } |
653 | added = fanotify_mark_add_to_mask(fsn_mark, mask, flags); | 667 | added = fanotify_mark_add_to_mask(fsn_mark, mask, flags); |
654 | fsnotify_put_mark(fsn_mark); | 668 | |
655 | if (added & ~inode->i_fsnotify_mask) | 669 | if (added & ~inode->i_fsnotify_mask) |
656 | fsnotify_recalc_inode_mask(inode); | 670 | fsnotify_recalc_inode_mask(inode); |
657 | return 0; | 671 | err: |
672 | fsnotify_put_mark(fsn_mark); | ||
673 | return ret; | ||
658 | } | 674 | } |
659 | 675 | ||
660 | /* fanotify syscalls */ | 676 | /* fanotify syscalls */ |
@@ -687,8 +703,10 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) | |||
687 | 703 | ||
688 | /* fsnotify_alloc_group takes a ref. Dropped in fanotify_release */ | 704 | /* fsnotify_alloc_group takes a ref. Dropped in fanotify_release */ |
689 | group = fsnotify_alloc_group(&fanotify_fsnotify_ops); | 705 | group = fsnotify_alloc_group(&fanotify_fsnotify_ops); |
690 | if (IS_ERR(group)) | 706 | if (IS_ERR(group)) { |
707 | free_uid(user); | ||
691 | return PTR_ERR(group); | 708 | return PTR_ERR(group); |
709 | } | ||
692 | 710 | ||
693 | group->fanotify_data.user = user; | 711 | group->fanotify_data.user = user; |
694 | atomic_inc(&user->fanotify_listeners); | 712 | atomic_inc(&user->fanotify_listeners); |
@@ -698,6 +716,7 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) | |||
698 | mutex_init(&group->fanotify_data.access_mutex); | 716 | mutex_init(&group->fanotify_data.access_mutex); |
699 | init_waitqueue_head(&group->fanotify_data.access_waitq); | 717 | init_waitqueue_head(&group->fanotify_data.access_waitq); |
700 | INIT_LIST_HEAD(&group->fanotify_data.access_list); | 718 | INIT_LIST_HEAD(&group->fanotify_data.access_list); |
719 | atomic_set(&group->fanotify_data.bypass_perm, 0); | ||
701 | #endif | 720 | #endif |
702 | switch (flags & FAN_ALL_CLASS_BITS) { | 721 | switch (flags & FAN_ALL_CLASS_BITS) { |
703 | case FAN_CLASS_NOTIF: | 722 | case FAN_CLASS_NOTIF: |
@@ -764,8 +783,10 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags, | |||
764 | if (flags & ~FAN_ALL_MARK_FLAGS) | 783 | if (flags & ~FAN_ALL_MARK_FLAGS) |
765 | return -EINVAL; | 784 | return -EINVAL; |
766 | switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) { | 785 | switch (flags & (FAN_MARK_ADD | FAN_MARK_REMOVE | FAN_MARK_FLUSH)) { |
767 | case FAN_MARK_ADD: | 786 | case FAN_MARK_ADD: /* fallthrough */ |
768 | case FAN_MARK_REMOVE: | 787 | case FAN_MARK_REMOVE: |
788 | if (!mask) | ||
789 | return -EINVAL; | ||
769 | case FAN_MARK_FLUSH: | 790 | case FAN_MARK_FLUSH: |
770 | break; | 791 | break; |
771 | default: | 792 | default: |
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index 444c305a468c..4cd5d5d78f9f 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c | |||
@@ -752,6 +752,7 @@ SYSCALL_DEFINE1(inotify_init1, int, flags) | |||
752 | if (ret >= 0) | 752 | if (ret >= 0) |
753 | return ret; | 753 | return ret; |
754 | 754 | ||
755 | fsnotify_put_group(group); | ||
755 | atomic_dec(&user->inotify_devs); | 756 | atomic_dec(&user->inotify_devs); |
756 | out_free_uid: | 757 | out_free_uid: |
757 | free_uid(user); | 758 | free_uid(user); |
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index f1e962cb3b73..0d7c5540ad66 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
@@ -573,11 +573,14 @@ static void ocfs2_dio_end_io(struct kiocb *iocb, | |||
573 | /* this io's submitter should not have unlocked this before we could */ | 573 | /* this io's submitter should not have unlocked this before we could */ |
574 | BUG_ON(!ocfs2_iocb_is_rw_locked(iocb)); | 574 | BUG_ON(!ocfs2_iocb_is_rw_locked(iocb)); |
575 | 575 | ||
576 | if (ocfs2_iocb_is_sem_locked(iocb)) { | ||
577 | up_read(&inode->i_alloc_sem); | ||
578 | ocfs2_iocb_clear_sem_locked(iocb); | ||
579 | } | ||
580 | |||
576 | ocfs2_iocb_clear_rw_locked(iocb); | 581 | ocfs2_iocb_clear_rw_locked(iocb); |
577 | 582 | ||
578 | level = ocfs2_iocb_rw_locked_level(iocb); | 583 | level = ocfs2_iocb_rw_locked_level(iocb); |
579 | if (!level) | ||
580 | up_read(&inode->i_alloc_sem); | ||
581 | ocfs2_rw_unlock(inode, level); | 584 | ocfs2_rw_unlock(inode, level); |
582 | 585 | ||
583 | if (is_async) | 586 | if (is_async) |
diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h index 76bfdfda691a..eceb456037c1 100644 --- a/fs/ocfs2/aops.h +++ b/fs/ocfs2/aops.h | |||
@@ -68,8 +68,27 @@ static inline void ocfs2_iocb_set_rw_locked(struct kiocb *iocb, int level) | |||
68 | else | 68 | else |
69 | clear_bit(1, (unsigned long *)&iocb->private); | 69 | clear_bit(1, (unsigned long *)&iocb->private); |
70 | } | 70 | } |
71 | |||
72 | /* | ||
73 | * Using a named enum representing lock types in terms of #N bit stored in | ||
74 | * iocb->private, which is going to be used for communication bewteen | ||
75 | * ocfs2_dio_end_io() and ocfs2_file_aio_write/read(). | ||
76 | */ | ||
77 | enum ocfs2_iocb_lock_bits { | ||
78 | OCFS2_IOCB_RW_LOCK = 0, | ||
79 | OCFS2_IOCB_RW_LOCK_LEVEL, | ||
80 | OCFS2_IOCB_SEM, | ||
81 | OCFS2_IOCB_NUM_LOCKS | ||
82 | }; | ||
83 | |||
71 | #define ocfs2_iocb_clear_rw_locked(iocb) \ | 84 | #define ocfs2_iocb_clear_rw_locked(iocb) \ |
72 | clear_bit(0, (unsigned long *)&iocb->private) | 85 | clear_bit(OCFS2_IOCB_RW_LOCK, (unsigned long *)&iocb->private) |
73 | #define ocfs2_iocb_rw_locked_level(iocb) \ | 86 | #define ocfs2_iocb_rw_locked_level(iocb) \ |
74 | test_bit(1, (unsigned long *)&iocb->private) | 87 | test_bit(OCFS2_IOCB_RW_LOCK_LEVEL, (unsigned long *)&iocb->private) |
88 | #define ocfs2_iocb_set_sem_locked(iocb) \ | ||
89 | set_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private) | ||
90 | #define ocfs2_iocb_clear_sem_locked(iocb) \ | ||
91 | clear_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private) | ||
92 | #define ocfs2_iocb_is_sem_locked(iocb) \ | ||
93 | test_bit(OCFS2_IOCB_SEM, (unsigned long *)&iocb->private) | ||
75 | #endif /* OCFS2_FILE_H */ | 94 | #endif /* OCFS2_FILE_H */ |
diff --git a/fs/ocfs2/cluster/masklog.c b/fs/ocfs2/cluster/masklog.c index c7fba396392d..6c61771469af 100644 --- a/fs/ocfs2/cluster/masklog.c +++ b/fs/ocfs2/cluster/masklog.c | |||
@@ -113,10 +113,11 @@ static struct mlog_attribute mlog_attrs[MLOG_MAX_BITS] = { | |||
113 | define_mask(QUOTA), | 113 | define_mask(QUOTA), |
114 | define_mask(REFCOUNT), | 114 | define_mask(REFCOUNT), |
115 | define_mask(BASTS), | 115 | define_mask(BASTS), |
116 | define_mask(RESERVATIONS), | ||
117 | define_mask(CLUSTER), | ||
116 | define_mask(ERROR), | 118 | define_mask(ERROR), |
117 | define_mask(NOTICE), | 119 | define_mask(NOTICE), |
118 | define_mask(KTHREAD), | 120 | define_mask(KTHREAD), |
119 | define_mask(RESERVATIONS), | ||
120 | }; | 121 | }; |
121 | 122 | ||
122 | static struct attribute *mlog_attr_ptrs[MLOG_MAX_BITS] = {NULL, }; | 123 | static struct attribute *mlog_attr_ptrs[MLOG_MAX_BITS] = {NULL, }; |
diff --git a/fs/ocfs2/cluster/masklog.h b/fs/ocfs2/cluster/masklog.h index ea2ed9f56c94..34d6544357d9 100644 --- a/fs/ocfs2/cluster/masklog.h +++ b/fs/ocfs2/cluster/masklog.h | |||
@@ -81,7 +81,7 @@ | |||
81 | #include <linux/sched.h> | 81 | #include <linux/sched.h> |
82 | 82 | ||
83 | /* bits that are frequently given and infrequently matched in the low word */ | 83 | /* bits that are frequently given and infrequently matched in the low word */ |
84 | /* NOTE: If you add a flag, you need to also update mlog.c! */ | 84 | /* NOTE: If you add a flag, you need to also update masklog.c! */ |
85 | #define ML_ENTRY 0x0000000000000001ULL /* func call entry */ | 85 | #define ML_ENTRY 0x0000000000000001ULL /* func call entry */ |
86 | #define ML_EXIT 0x0000000000000002ULL /* func call exit */ | 86 | #define ML_EXIT 0x0000000000000002ULL /* func call exit */ |
87 | #define ML_TCP 0x0000000000000004ULL /* net cluster/tcp.c */ | 87 | #define ML_TCP 0x0000000000000004ULL /* net cluster/tcp.c */ |
@@ -114,13 +114,14 @@ | |||
114 | #define ML_XATTR 0x0000000020000000ULL /* ocfs2 extended attributes */ | 114 | #define ML_XATTR 0x0000000020000000ULL /* ocfs2 extended attributes */ |
115 | #define ML_QUOTA 0x0000000040000000ULL /* ocfs2 quota operations */ | 115 | #define ML_QUOTA 0x0000000040000000ULL /* ocfs2 quota operations */ |
116 | #define ML_REFCOUNT 0x0000000080000000ULL /* refcount tree operations */ | 116 | #define ML_REFCOUNT 0x0000000080000000ULL /* refcount tree operations */ |
117 | #define ML_BASTS 0x0000001000000000ULL /* dlmglue asts and basts */ | 117 | #define ML_BASTS 0x0000000100000000ULL /* dlmglue asts and basts */ |
118 | #define ML_RESERVATIONS 0x0000000200000000ULL /* ocfs2 alloc reservations */ | ||
119 | #define ML_CLUSTER 0x0000000400000000ULL /* cluster stack */ | ||
120 | |||
118 | /* bits that are infrequently given and frequently matched in the high word */ | 121 | /* bits that are infrequently given and frequently matched in the high word */ |
119 | #define ML_ERROR 0x0000000100000000ULL /* sent to KERN_ERR */ | 122 | #define ML_ERROR 0x1000000000000000ULL /* sent to KERN_ERR */ |
120 | #define ML_NOTICE 0x0000000200000000ULL /* setn to KERN_NOTICE */ | 123 | #define ML_NOTICE 0x2000000000000000ULL /* setn to KERN_NOTICE */ |
121 | #define ML_KTHREAD 0x0000000400000000ULL /* kernel thread activity */ | 124 | #define ML_KTHREAD 0x4000000000000000ULL /* kernel thread activity */ |
122 | #define ML_RESERVATIONS 0x0000000800000000ULL /* ocfs2 alloc reservations */ | ||
123 | #define ML_CLUSTER 0x0000001000000000ULL /* cluster stack */ | ||
124 | 125 | ||
125 | #define MLOG_INITIAL_AND_MASK (ML_ERROR|ML_NOTICE) | 126 | #define MLOG_INITIAL_AND_MASK (ML_ERROR|ML_NOTICE) |
126 | #define MLOG_INITIAL_NOT_MASK (ML_ENTRY|ML_EXIT) | 127 | #define MLOG_INITIAL_NOT_MASK (ML_ENTRY|ML_EXIT) |
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c index c49f6de0e7ab..d417b3f9b0c7 100644 --- a/fs/ocfs2/dir.c +++ b/fs/ocfs2/dir.c | |||
@@ -2461,8 +2461,10 @@ static int ocfs2_dx_dir_attach_index(struct ocfs2_super *osb, | |||
2461 | 2461 | ||
2462 | di->i_dx_root = cpu_to_le64(dr_blkno); | 2462 | di->i_dx_root = cpu_to_le64(dr_blkno); |
2463 | 2463 | ||
2464 | spin_lock(&OCFS2_I(dir)->ip_lock); | ||
2464 | OCFS2_I(dir)->ip_dyn_features |= OCFS2_INDEXED_DIR_FL; | 2465 | OCFS2_I(dir)->ip_dyn_features |= OCFS2_INDEXED_DIR_FL; |
2465 | di->i_dyn_features = cpu_to_le16(OCFS2_I(dir)->ip_dyn_features); | 2466 | di->i_dyn_features = cpu_to_le16(OCFS2_I(dir)->ip_dyn_features); |
2467 | spin_unlock(&OCFS2_I(dir)->ip_lock); | ||
2466 | 2468 | ||
2467 | ocfs2_journal_dirty(handle, di_bh); | 2469 | ocfs2_journal_dirty(handle, di_bh); |
2468 | 2470 | ||
@@ -4466,8 +4468,10 @@ static int ocfs2_dx_dir_remove_index(struct inode *dir, | |||
4466 | goto out_commit; | 4468 | goto out_commit; |
4467 | } | 4469 | } |
4468 | 4470 | ||
4471 | spin_lock(&OCFS2_I(dir)->ip_lock); | ||
4469 | OCFS2_I(dir)->ip_dyn_features &= ~OCFS2_INDEXED_DIR_FL; | 4472 | OCFS2_I(dir)->ip_dyn_features &= ~OCFS2_INDEXED_DIR_FL; |
4470 | di->i_dyn_features = cpu_to_le16(OCFS2_I(dir)->ip_dyn_features); | 4473 | di->i_dyn_features = cpu_to_le16(OCFS2_I(dir)->ip_dyn_features); |
4474 | spin_unlock(&OCFS2_I(dir)->ip_lock); | ||
4471 | di->i_dx_root = cpu_to_le64(0ULL); | 4475 | di->i_dx_root = cpu_to_le64(0ULL); |
4472 | 4476 | ||
4473 | ocfs2_journal_dirty(handle, di_bh); | 4477 | ocfs2_journal_dirty(handle, di_bh); |
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index f564b0e5f80d..59f0f6bdfc62 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
@@ -2346,7 +2346,8 @@ static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data) | |||
2346 | */ | 2346 | */ |
2347 | static int dlm_is_lockres_migrateable(struct dlm_ctxt *dlm, | 2347 | static int dlm_is_lockres_migrateable(struct dlm_ctxt *dlm, |
2348 | struct dlm_lock_resource *res, | 2348 | struct dlm_lock_resource *res, |
2349 | int *numlocks) | 2349 | int *numlocks, |
2350 | int *hasrefs) | ||
2350 | { | 2351 | { |
2351 | int ret; | 2352 | int ret; |
2352 | int i; | 2353 | int i; |
@@ -2356,6 +2357,9 @@ static int dlm_is_lockres_migrateable(struct dlm_ctxt *dlm, | |||
2356 | 2357 | ||
2357 | assert_spin_locked(&res->spinlock); | 2358 | assert_spin_locked(&res->spinlock); |
2358 | 2359 | ||
2360 | *numlocks = 0; | ||
2361 | *hasrefs = 0; | ||
2362 | |||
2359 | ret = -EINVAL; | 2363 | ret = -EINVAL; |
2360 | if (res->owner == DLM_LOCK_RES_OWNER_UNKNOWN) { | 2364 | if (res->owner == DLM_LOCK_RES_OWNER_UNKNOWN) { |
2361 | mlog(0, "cannot migrate lockres with unknown owner!\n"); | 2365 | mlog(0, "cannot migrate lockres with unknown owner!\n"); |
@@ -2386,7 +2390,13 @@ static int dlm_is_lockres_migrateable(struct dlm_ctxt *dlm, | |||
2386 | } | 2390 | } |
2387 | 2391 | ||
2388 | *numlocks = count; | 2392 | *numlocks = count; |
2389 | mlog(0, "migrateable lockres having %d locks\n", *numlocks); | 2393 | |
2394 | count = find_next_bit(res->refmap, O2NM_MAX_NODES, 0); | ||
2395 | if (count < O2NM_MAX_NODES) | ||
2396 | *hasrefs = 1; | ||
2397 | |||
2398 | mlog(0, "%s: res %.*s, Migrateable, locks %d, refs %d\n", dlm->name, | ||
2399 | res->lockname.len, res->lockname.name, *numlocks, *hasrefs); | ||
2390 | 2400 | ||
2391 | leave: | 2401 | leave: |
2392 | return ret; | 2402 | return ret; |
@@ -2408,7 +2418,7 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm, | |||
2408 | const char *name; | 2418 | const char *name; |
2409 | unsigned int namelen; | 2419 | unsigned int namelen; |
2410 | int mle_added = 0; | 2420 | int mle_added = 0; |
2411 | int numlocks; | 2421 | int numlocks, hasrefs; |
2412 | int wake = 0; | 2422 | int wake = 0; |
2413 | 2423 | ||
2414 | if (!dlm_grab(dlm)) | 2424 | if (!dlm_grab(dlm)) |
@@ -2417,13 +2427,13 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm, | |||
2417 | name = res->lockname.name; | 2427 | name = res->lockname.name; |
2418 | namelen = res->lockname.len; | 2428 | namelen = res->lockname.len; |
2419 | 2429 | ||
2420 | mlog(0, "migrating %.*s to %u\n", namelen, name, target); | 2430 | mlog(0, "%s: Migrating %.*s to %u\n", dlm->name, namelen, name, target); |
2421 | 2431 | ||
2422 | /* | 2432 | /* |
2423 | * ensure this lockres is a proper candidate for migration | 2433 | * ensure this lockres is a proper candidate for migration |
2424 | */ | 2434 | */ |
2425 | spin_lock(&res->spinlock); | 2435 | spin_lock(&res->spinlock); |
2426 | ret = dlm_is_lockres_migrateable(dlm, res, &numlocks); | 2436 | ret = dlm_is_lockres_migrateable(dlm, res, &numlocks, &hasrefs); |
2427 | if (ret < 0) { | 2437 | if (ret < 0) { |
2428 | spin_unlock(&res->spinlock); | 2438 | spin_unlock(&res->spinlock); |
2429 | goto leave; | 2439 | goto leave; |
@@ -2431,10 +2441,8 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm, | |||
2431 | spin_unlock(&res->spinlock); | 2441 | spin_unlock(&res->spinlock); |
2432 | 2442 | ||
2433 | /* no work to do */ | 2443 | /* no work to do */ |
2434 | if (numlocks == 0) { | 2444 | if (numlocks == 0 && !hasrefs) |
2435 | mlog(0, "no locks were found on this lockres! done!\n"); | ||
2436 | goto leave; | 2445 | goto leave; |
2437 | } | ||
2438 | 2446 | ||
2439 | /* | 2447 | /* |
2440 | * preallocate up front | 2448 | * preallocate up front |
@@ -2459,14 +2467,14 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm, | |||
2459 | * find a node to migrate the lockres to | 2467 | * find a node to migrate the lockres to |
2460 | */ | 2468 | */ |
2461 | 2469 | ||
2462 | mlog(0, "picking a migration node\n"); | ||
2463 | spin_lock(&dlm->spinlock); | 2470 | spin_lock(&dlm->spinlock); |
2464 | /* pick a new node */ | 2471 | /* pick a new node */ |
2465 | if (!test_bit(target, dlm->domain_map) || | 2472 | if (!test_bit(target, dlm->domain_map) || |
2466 | target >= O2NM_MAX_NODES) { | 2473 | target >= O2NM_MAX_NODES) { |
2467 | target = dlm_pick_migration_target(dlm, res); | 2474 | target = dlm_pick_migration_target(dlm, res); |
2468 | } | 2475 | } |
2469 | mlog(0, "node %u chosen for migration\n", target); | 2476 | mlog(0, "%s: res %.*s, Node %u chosen for migration\n", dlm->name, |
2477 | namelen, name, target); | ||
2470 | 2478 | ||
2471 | if (target >= O2NM_MAX_NODES || | 2479 | if (target >= O2NM_MAX_NODES || |
2472 | !test_bit(target, dlm->domain_map)) { | 2480 | !test_bit(target, dlm->domain_map)) { |
@@ -2667,7 +2675,7 @@ int dlm_empty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) | |||
2667 | { | 2675 | { |
2668 | int ret; | 2676 | int ret; |
2669 | int lock_dropped = 0; | 2677 | int lock_dropped = 0; |
2670 | int numlocks; | 2678 | int numlocks, hasrefs; |
2671 | 2679 | ||
2672 | spin_lock(&res->spinlock); | 2680 | spin_lock(&res->spinlock); |
2673 | if (res->owner != dlm->node_num) { | 2681 | if (res->owner != dlm->node_num) { |
@@ -2681,8 +2689,8 @@ int dlm_empty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) | |||
2681 | } | 2689 | } |
2682 | 2690 | ||
2683 | /* No need to migrate a lockres having no locks */ | 2691 | /* No need to migrate a lockres having no locks */ |
2684 | ret = dlm_is_lockres_migrateable(dlm, res, &numlocks); | 2692 | ret = dlm_is_lockres_migrateable(dlm, res, &numlocks, &hasrefs); |
2685 | if (ret >= 0 && numlocks == 0) { | 2693 | if (ret >= 0 && numlocks == 0 && !hasrefs) { |
2686 | spin_unlock(&res->spinlock); | 2694 | spin_unlock(&res->spinlock); |
2687 | goto leave; | 2695 | goto leave; |
2688 | } | 2696 | } |
@@ -2915,6 +2923,12 @@ static u8 dlm_pick_migration_target(struct dlm_ctxt *dlm, | |||
2915 | } | 2923 | } |
2916 | queue++; | 2924 | queue++; |
2917 | } | 2925 | } |
2926 | |||
2927 | nodenum = find_next_bit(res->refmap, O2NM_MAX_NODES, 0); | ||
2928 | if (nodenum < O2NM_MAX_NODES) { | ||
2929 | spin_unlock(&res->spinlock); | ||
2930 | return nodenum; | ||
2931 | } | ||
2918 | spin_unlock(&res->spinlock); | 2932 | spin_unlock(&res->spinlock); |
2919 | mlog(0, "have not found a suitable target yet! checking domain map\n"); | 2933 | mlog(0, "have not found a suitable target yet! checking domain map\n"); |
2920 | 2934 | ||
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 77b4c04a2809..f6cba566429d 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -2241,11 +2241,15 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, | |||
2241 | 2241 | ||
2242 | mutex_lock(&inode->i_mutex); | 2242 | mutex_lock(&inode->i_mutex); |
2243 | 2243 | ||
2244 | ocfs2_iocb_clear_sem_locked(iocb); | ||
2245 | |||
2244 | relock: | 2246 | relock: |
2245 | /* to match setattr's i_mutex -> i_alloc_sem -> rw_lock ordering */ | 2247 | /* to match setattr's i_mutex -> i_alloc_sem -> rw_lock ordering */ |
2246 | if (direct_io) { | 2248 | if (direct_io) { |
2247 | down_read(&inode->i_alloc_sem); | 2249 | down_read(&inode->i_alloc_sem); |
2248 | have_alloc_sem = 1; | 2250 | have_alloc_sem = 1; |
2251 | /* communicate with ocfs2_dio_end_io */ | ||
2252 | ocfs2_iocb_set_sem_locked(iocb); | ||
2249 | } | 2253 | } |
2250 | 2254 | ||
2251 | /* | 2255 | /* |
@@ -2382,8 +2386,10 @@ out: | |||
2382 | ocfs2_rw_unlock(inode, rw_level); | 2386 | ocfs2_rw_unlock(inode, rw_level); |
2383 | 2387 | ||
2384 | out_sems: | 2388 | out_sems: |
2385 | if (have_alloc_sem) | 2389 | if (have_alloc_sem) { |
2386 | up_read(&inode->i_alloc_sem); | 2390 | up_read(&inode->i_alloc_sem); |
2391 | ocfs2_iocb_clear_sem_locked(iocb); | ||
2392 | } | ||
2387 | 2393 | ||
2388 | mutex_unlock(&inode->i_mutex); | 2394 | mutex_unlock(&inode->i_mutex); |
2389 | 2395 | ||
@@ -2527,6 +2533,8 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, | |||
2527 | goto bail; | 2533 | goto bail; |
2528 | } | 2534 | } |
2529 | 2535 | ||
2536 | ocfs2_iocb_clear_sem_locked(iocb); | ||
2537 | |||
2530 | /* | 2538 | /* |
2531 | * buffered reads protect themselves in ->readpage(). O_DIRECT reads | 2539 | * buffered reads protect themselves in ->readpage(). O_DIRECT reads |
2532 | * need locks to protect pending reads from racing with truncate. | 2540 | * need locks to protect pending reads from racing with truncate. |
@@ -2534,6 +2542,7 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, | |||
2534 | if (filp->f_flags & O_DIRECT) { | 2542 | if (filp->f_flags & O_DIRECT) { |
2535 | down_read(&inode->i_alloc_sem); | 2543 | down_read(&inode->i_alloc_sem); |
2536 | have_alloc_sem = 1; | 2544 | have_alloc_sem = 1; |
2545 | ocfs2_iocb_set_sem_locked(iocb); | ||
2537 | 2546 | ||
2538 | ret = ocfs2_rw_lock(inode, 0); | 2547 | ret = ocfs2_rw_lock(inode, 0); |
2539 | if (ret < 0) { | 2548 | if (ret < 0) { |
@@ -2575,8 +2584,10 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, | |||
2575 | } | 2584 | } |
2576 | 2585 | ||
2577 | bail: | 2586 | bail: |
2578 | if (have_alloc_sem) | 2587 | if (have_alloc_sem) { |
2579 | up_read(&inode->i_alloc_sem); | 2588 | up_read(&inode->i_alloc_sem); |
2589 | ocfs2_iocb_clear_sem_locked(iocb); | ||
2590 | } | ||
2580 | if (rw_level != -1) | 2591 | if (rw_level != -1) |
2581 | ocfs2_rw_unlock(inode, rw_level); | 2592 | ocfs2_rw_unlock(inode, rw_level); |
2582 | mlog_exit(ret); | 2593 | mlog_exit(ret); |
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h index c2e4f8222e2f..bf2e7764920e 100644 --- a/fs/ocfs2/ocfs2_fs.h +++ b/fs/ocfs2/ocfs2_fs.h | |||
@@ -350,7 +350,7 @@ enum { | |||
350 | #define OCFS2_LAST_LOCAL_SYSTEM_INODE LOCAL_GROUP_QUOTA_SYSTEM_INODE | 350 | #define OCFS2_LAST_LOCAL_SYSTEM_INODE LOCAL_GROUP_QUOTA_SYSTEM_INODE |
351 | NUM_SYSTEM_INODES | 351 | NUM_SYSTEM_INODES |
352 | }; | 352 | }; |
353 | #define NUM_GLOBAL_SYSTEM_INODES OCFS2_LAST_GLOBAL_SYSTEM_INODE | 353 | #define NUM_GLOBAL_SYSTEM_INODES OCFS2_FIRST_LOCAL_SYSTEM_INODE |
354 | #define NUM_LOCAL_SYSTEM_INODES \ | 354 | #define NUM_LOCAL_SYSTEM_INODES \ |
355 | (NUM_SYSTEM_INODES - OCFS2_FIRST_LOCAL_SYSTEM_INODE) | 355 | (NUM_SYSTEM_INODES - OCFS2_FIRST_LOCAL_SYSTEM_INODE) |
356 | 356 | ||
diff --git a/fs/xfs/xfs_rename.c b/fs/xfs/xfs_rename.c index d2af0a8381a6..77a59891734e 100644 --- a/fs/xfs/xfs_rename.c +++ b/fs/xfs/xfs_rename.c | |||
@@ -297,6 +297,7 @@ xfs_rename( | |||
297 | * it and some incremental backup programs won't work without it. | 297 | * it and some incremental backup programs won't work without it. |
298 | */ | 298 | */ |
299 | xfs_trans_ichgtime(tp, src_ip, XFS_ICHGTIME_CHG); | 299 | xfs_trans_ichgtime(tp, src_ip, XFS_ICHGTIME_CHG); |
300 | xfs_trans_log_inode(tp, src_ip, XFS_ILOG_CORE); | ||
300 | 301 | ||
301 | /* | 302 | /* |
302 | * Adjust the link count on src_dp. This is necessary when | 303 | * Adjust the link count on src_dp. This is necessary when |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 359ef11725a6..20b05cd68663 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -149,8 +149,7 @@ struct acpi_device_flags { | |||
149 | u32 power_manageable:1; | 149 | u32 power_manageable:1; |
150 | u32 performance_manageable:1; | 150 | u32 performance_manageable:1; |
151 | u32 wake_capable:1; /* Wakeup(_PRW) supported? */ | 151 | u32 wake_capable:1; /* Wakeup(_PRW) supported? */ |
152 | u32 force_power_state:1; | 152 | u32 reserved:23; |
153 | u32 reserved:22; | ||
154 | }; | 153 | }; |
155 | 154 | ||
156 | /* File System */ | 155 | /* File System */ |
@@ -242,20 +241,14 @@ struct acpi_device_perf { | |||
242 | struct acpi_device_wakeup_flags { | 241 | struct acpi_device_wakeup_flags { |
243 | u8 valid:1; /* Can successfully enable wakeup? */ | 242 | u8 valid:1; /* Can successfully enable wakeup? */ |
244 | u8 run_wake:1; /* Run-Wake GPE devices */ | 243 | u8 run_wake:1; /* Run-Wake GPE devices */ |
245 | u8 always_enabled:1; /* Run-wake devices that are always enabled */ | ||
246 | u8 notifier_present:1; /* Wake-up notify handler has been installed */ | 244 | u8 notifier_present:1; /* Wake-up notify handler has been installed */ |
247 | }; | 245 | }; |
248 | 246 | ||
249 | struct acpi_device_wakeup_state { | ||
250 | u8 enabled:1; | ||
251 | }; | ||
252 | |||
253 | struct acpi_device_wakeup { | 247 | struct acpi_device_wakeup { |
254 | acpi_handle gpe_device; | 248 | acpi_handle gpe_device; |
255 | u64 gpe_number; | 249 | u64 gpe_number; |
256 | u64 sleep_state; | 250 | u64 sleep_state; |
257 | struct acpi_handle_list resources; | 251 | struct acpi_handle_list resources; |
258 | struct acpi_device_wakeup_state state; | ||
259 | struct acpi_device_wakeup_flags flags; | 252 | struct acpi_device_wakeup_flags flags; |
260 | int prepare_count; | 253 | int prepare_count; |
261 | int run_wake_count; | 254 | int run_wake_count; |
@@ -328,8 +321,8 @@ void acpi_bus_data_handler(acpi_handle handle, void *context); | |||
328 | acpi_status acpi_bus_get_status_handle(acpi_handle handle, | 321 | acpi_status acpi_bus_get_status_handle(acpi_handle handle, |
329 | unsigned long long *sta); | 322 | unsigned long long *sta); |
330 | int acpi_bus_get_status(struct acpi_device *device); | 323 | int acpi_bus_get_status(struct acpi_device *device); |
331 | int acpi_bus_get_power(acpi_handle handle, int *state); | ||
332 | int acpi_bus_set_power(acpi_handle handle, int state); | 324 | int acpi_bus_set_power(acpi_handle handle, int state); |
325 | int acpi_bus_update_power(acpi_handle handle, int *state_p); | ||
333 | bool acpi_bus_power_manageable(acpi_handle handle); | 326 | bool acpi_bus_power_manageable(acpi_handle handle); |
334 | bool acpi_bus_can_wakeup(acpi_handle handle); | 327 | bool acpi_bus_can_wakeup(acpi_handle handle); |
335 | #ifdef CONFIG_ACPI_PROC_EVENT | 328 | #ifdef CONFIG_ACPI_PROC_EVENT |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 53b7cfd924a3..241b8a04c83c 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
@@ -47,7 +47,7 @@ | |||
47 | 47 | ||
48 | /* Current ACPICA subsystem version in YYYYMMDD format */ | 48 | /* Current ACPICA subsystem version in YYYYMMDD format */ |
49 | 49 | ||
50 | #define ACPI_CA_VERSION 0x20101013 | 50 | #define ACPI_CA_VERSION 0x20101209 |
51 | 51 | ||
52 | #include "actypes.h" | 52 | #include "actypes.h" |
53 | #include "actbl.h" | 53 | #include "actbl.h" |
@@ -229,6 +229,10 @@ acpi_status | |||
229 | acpi_install_initialization_handler(acpi_init_handler handler, u32 function); | 229 | acpi_install_initialization_handler(acpi_init_handler handler, u32 function); |
230 | 230 | ||
231 | acpi_status | 231 | acpi_status |
232 | acpi_install_global_event_handler(ACPI_GBL_EVENT_HANDLER handler, | ||
233 | void *context); | ||
234 | |||
235 | acpi_status | ||
232 | acpi_install_fixed_event_handler(u32 acpi_event, | 236 | acpi_install_fixed_event_handler(u32 acpi_event, |
233 | acpi_event_handler handler, void *context); | 237 | acpi_event_handler handler, void *context); |
234 | 238 | ||
@@ -258,11 +262,11 @@ acpi_remove_address_space_handler(acpi_handle device, | |||
258 | acpi_status | 262 | acpi_status |
259 | acpi_install_gpe_handler(acpi_handle gpe_device, | 263 | acpi_install_gpe_handler(acpi_handle gpe_device, |
260 | u32 gpe_number, | 264 | u32 gpe_number, |
261 | u32 type, acpi_event_handler address, void *context); | 265 | u32 type, acpi_gpe_handler address, void *context); |
262 | 266 | ||
263 | acpi_status | 267 | acpi_status |
264 | acpi_remove_gpe_handler(acpi_handle gpe_device, | 268 | acpi_remove_gpe_handler(acpi_handle gpe_device, |
265 | u32 gpe_number, acpi_event_handler address); | 269 | u32 gpe_number, acpi_gpe_handler address); |
266 | 270 | ||
267 | #ifdef ACPI_FUTURE_USAGE | 271 | #ifdef ACPI_FUTURE_USAGE |
268 | acpi_status acpi_install_exception_handler(acpi_exception_handler handler); | 272 | acpi_status acpi_install_exception_handler(acpi_exception_handler handler); |
@@ -292,11 +296,13 @@ acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number); | |||
292 | 296 | ||
293 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number); | 297 | acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number); |
294 | 298 | ||
295 | acpi_status acpi_gpe_can_wake(acpi_handle gpe_device, u32 gpe_number); | ||
296 | |||
297 | acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number); | 299 | acpi_status acpi_clear_gpe(acpi_handle gpe_device, u32 gpe_number); |
298 | 300 | ||
299 | acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action); | 301 | acpi_status |
302 | acpi_setup_gpe_for_wake(acpi_handle parent_device, | ||
303 | acpi_handle gpe_device, u32 gpe_number); | ||
304 | |||
305 | acpi_status acpi_set_gpe_wake_mask(acpi_handle gpe_device, u32 gpe_number, u8 action); | ||
300 | 306 | ||
301 | acpi_status | 307 | acpi_status |
302 | acpi_get_gpe_status(acpi_handle gpe_device, | 308 | acpi_get_gpe_status(acpi_handle gpe_device, |
@@ -315,7 +321,7 @@ acpi_install_gpe_block(acpi_handle gpe_device, | |||
315 | 321 | ||
316 | acpi_status acpi_remove_gpe_block(acpi_handle gpe_device); | 322 | acpi_status acpi_remove_gpe_block(acpi_handle gpe_device); |
317 | 323 | ||
318 | acpi_status acpi_update_gpes(void); | 324 | acpi_status acpi_update_all_gpes(void); |
319 | 325 | ||
320 | /* | 326 | /* |
321 | * Resource interfaces | 327 | * Resource interfaces |
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 2b134b691e34..939a431a6ab6 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h | |||
@@ -656,33 +656,34 @@ typedef u32 acpi_event_status; | |||
656 | #define ACPI_GPE_MAX 0xFF | 656 | #define ACPI_GPE_MAX 0xFF |
657 | #define ACPI_NUM_GPE 256 | 657 | #define ACPI_NUM_GPE 256 |
658 | 658 | ||
659 | /* Actions for acpi_gpe_wakeup, acpi_hw_low_set_gpe */ | 659 | /* Actions for acpi_set_gpe_wake_mask, acpi_hw_low_set_gpe */ |
660 | 660 | ||
661 | #define ACPI_GPE_ENABLE 0 | 661 | #define ACPI_GPE_ENABLE 0 |
662 | #define ACPI_GPE_DISABLE 1 | 662 | #define ACPI_GPE_DISABLE 1 |
663 | #define ACPI_GPE_COND_ENABLE 2 | 663 | #define ACPI_GPE_CONDITIONAL_ENABLE 2 |
664 | 664 | ||
665 | /* | 665 | /* |
666 | * GPE info flags - Per GPE | 666 | * GPE info flags - Per GPE |
667 | * +-------+---+-+-+ | 667 | * +-------+-+-+---+ |
668 | * | 7:4 |3:2|1|0| | 668 | * | 7:4 |3|2|1:0| |
669 | * +-------+---+-+-+ | 669 | * +-------+-+-+---+ |
670 | * | | | | | 670 | * | | | | |
671 | * | | | +--- Interrupt type: edge or level triggered | 671 | * | | | +-- Type of dispatch:to method, handler, notify, or none |
672 | * | | +----- GPE can wake the system | 672 | * | | +----- Interrupt type: edge or level triggered |
673 | * | +-------- Type of dispatch:to method, handler, or none | 673 | * | +------- Is a Wake GPE |
674 | * +-------------- <Reserved> | 674 | * +------------ <Reserved> |
675 | */ | 675 | */ |
676 | #define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x01 | 676 | #define ACPI_GPE_DISPATCH_NONE (u8) 0x00 |
677 | #define ACPI_GPE_LEVEL_TRIGGERED (u8) 0x01 | 677 | #define ACPI_GPE_DISPATCH_METHOD (u8) 0x01 |
678 | #define ACPI_GPE_EDGE_TRIGGERED (u8) 0x00 | 678 | #define ACPI_GPE_DISPATCH_HANDLER (u8) 0x02 |
679 | #define ACPI_GPE_DISPATCH_NOTIFY (u8) 0x03 | ||
680 | #define ACPI_GPE_DISPATCH_MASK (u8) 0x03 | ||
679 | 681 | ||
680 | #define ACPI_GPE_CAN_WAKE (u8) 0x02 | 682 | #define ACPI_GPE_LEVEL_TRIGGERED (u8) 0x04 |
683 | #define ACPI_GPE_EDGE_TRIGGERED (u8) 0x00 | ||
684 | #define ACPI_GPE_XRUPT_TYPE_MASK (u8) 0x04 | ||
681 | 685 | ||
682 | #define ACPI_GPE_DISPATCH_MASK (u8) 0x0C | 686 | #define ACPI_GPE_CAN_WAKE (u8) 0x08 |
683 | #define ACPI_GPE_DISPATCH_HANDLER (u8) 0x04 | ||
684 | #define ACPI_GPE_DISPATCH_METHOD (u8) 0x08 | ||
685 | #define ACPI_GPE_DISPATCH_NOT_USED (u8) 0x00 | ||
686 | 687 | ||
687 | /* | 688 | /* |
688 | * Flags for GPE and Lock interfaces | 689 | * Flags for GPE and Lock interfaces |
@@ -894,9 +895,20 @@ typedef void | |||
894 | /* | 895 | /* |
895 | * Various handlers and callback procedures | 896 | * Various handlers and callback procedures |
896 | */ | 897 | */ |
898 | typedef | ||
899 | void (*ACPI_GBL_EVENT_HANDLER) (u32 event_type, | ||
900 | acpi_handle device, | ||
901 | u32 event_number, void *context); | ||
902 | |||
903 | #define ACPI_EVENT_TYPE_GPE 0 | ||
904 | #define ACPI_EVENT_TYPE_FIXED 1 | ||
905 | |||
897 | typedef u32(*acpi_event_handler) (void *context); | 906 | typedef u32(*acpi_event_handler) (void *context); |
898 | 907 | ||
899 | typedef | 908 | typedef |
909 | u32 (*acpi_gpe_handler) (acpi_handle gpe_device, u32 gpe_number, void *context); | ||
910 | |||
911 | typedef | ||
900 | void (*acpi_notify_handler) (acpi_handle device, u32 value, void *context); | 912 | void (*acpi_notify_handler) (acpi_handle device, u32 value, void *context); |
901 | 913 | ||
902 | typedef | 914 | typedef |
@@ -951,6 +963,10 @@ u32 (*acpi_interface_handler) (acpi_string interface_name, u32 supported); | |||
951 | #define ACPI_INTERRUPT_NOT_HANDLED 0x00 | 963 | #define ACPI_INTERRUPT_NOT_HANDLED 0x00 |
952 | #define ACPI_INTERRUPT_HANDLED 0x01 | 964 | #define ACPI_INTERRUPT_HANDLED 0x01 |
953 | 965 | ||
966 | /* GPE handler return values */ | ||
967 | |||
968 | #define ACPI_REENABLE_GPE 0x80 | ||
969 | |||
954 | /* Length of 32-bit EISAID values when converted back to a string */ | 970 | /* Length of 32-bit EISAID values when converted back to a string */ |
955 | 971 | ||
956 | #define ACPI_EISAID_STRING_SIZE 8 /* Includes null terminator */ | 972 | #define ACPI_EISAID_STRING_SIZE 8 /* Includes null terminator */ |
diff --git a/include/acpi/video.h b/include/acpi/video.h index 551793c9b6e8..0e98e679d3a7 100644 --- a/include/acpi/video.h +++ b/include/acpi/video.h | |||
@@ -1,6 +1,10 @@ | |||
1 | #ifndef __ACPI_VIDEO_H | 1 | #ifndef __ACPI_VIDEO_H |
2 | #define __ACPI_VIDEO_H | 2 | #define __ACPI_VIDEO_H |
3 | 3 | ||
4 | #include <linux/errno.h> /* for ENODEV */ | ||
5 | |||
6 | struct acpi_device; | ||
7 | |||
4 | #define ACPI_VIDEO_DISPLAY_CRT 1 | 8 | #define ACPI_VIDEO_DISPLAY_CRT 1 |
5 | #define ACPI_VIDEO_DISPLAY_TV 2 | 9 | #define ACPI_VIDEO_DISPLAY_TV 2 |
6 | #define ACPI_VIDEO_DISPLAY_DVI 3 | 10 | #define ACPI_VIDEO_DISPLAY_DVI 3 |
@@ -26,4 +30,3 @@ static inline int acpi_video_get_edid(struct acpi_device *device, int type, | |||
26 | #endif | 30 | #endif |
27 | 31 | ||
28 | #endif | 32 | #endif |
29 | |||
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index 8c641bed9bbd..a2776e2807a4 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h | |||
@@ -287,6 +287,8 @@ typedef struct drm_i915_irq_wait { | |||
287 | #define I915_PARAM_HAS_EXECBUF2 9 | 287 | #define I915_PARAM_HAS_EXECBUF2 9 |
288 | #define I915_PARAM_HAS_BSD 10 | 288 | #define I915_PARAM_HAS_BSD 10 |
289 | #define I915_PARAM_HAS_BLT 11 | 289 | #define I915_PARAM_HAS_BLT 11 |
290 | #define I915_PARAM_HAS_RELAXED_FENCING 12 | ||
291 | #define I915_PARAM_HAS_COHERENT_RINGS 13 | ||
290 | 292 | ||
291 | typedef struct drm_i915_getparam { | 293 | typedef struct drm_i915_getparam { |
292 | int param; | 294 | int param; |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 050a7bccb836..fa7ed6a983d0 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -219,7 +219,7 @@ static inline int acpi_video_display_switch_support(void) | |||
219 | 219 | ||
220 | extern int acpi_blacklisted(void); | 220 | extern int acpi_blacklisted(void); |
221 | extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d); | 221 | extern void acpi_dmi_osi_linux(int enable, const struct dmi_system_id *d); |
222 | extern int acpi_osi_setup(char *str); | 222 | extern void acpi_osi_setup(char *str); |
223 | 223 | ||
224 | #ifdef CONFIG_ACPI_NUMA | 224 | #ifdef CONFIG_ACPI_NUMA |
225 | int acpi_get_pxm(acpi_handle handle); | 225 | int acpi_get_pxm(acpi_handle handle); |
@@ -254,6 +254,15 @@ void __init acpi_old_suspend_ordering(void); | |||
254 | void __init acpi_nvs_nosave(void); | 254 | void __init acpi_nvs_nosave(void); |
255 | #endif /* CONFIG_PM_SLEEP */ | 255 | #endif /* CONFIG_PM_SLEEP */ |
256 | 256 | ||
257 | #ifdef CONFIG_ACPI_SLEEP | ||
258 | int suspend_nvs_register(unsigned long start, unsigned long size); | ||
259 | #else | ||
260 | static inline int suspend_nvs_register(unsigned long a, unsigned long b) | ||
261 | { | ||
262 | return 0; | ||
263 | } | ||
264 | #endif | ||
265 | |||
257 | struct acpi_osc_context { | 266 | struct acpi_osc_context { |
258 | char *uuid_str; /* uuid string */ | 267 | char *uuid_str; /* uuid string */ |
259 | int rev; | 268 | int rev; |
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h index a8e4e832cdbb..475f8c42c0e9 100644 --- a/include/linux/atmdev.h +++ b/include/linux/atmdev.h | |||
@@ -427,8 +427,10 @@ extern rwlock_t vcc_sklist_lock; | |||
427 | 427 | ||
428 | #define ATM_SKB(skb) (((struct atm_skb_data *) (skb)->cb)) | 428 | #define ATM_SKB(skb) (((struct atm_skb_data *) (skb)->cb)) |
429 | 429 | ||
430 | struct atm_dev *atm_dev_register(const char *type,const struct atmdev_ops *ops, | 430 | struct atm_dev *atm_dev_register(const char *type, struct device *parent, |
431 | int number,unsigned long *flags); /* number == -1: pick first available */ | 431 | const struct atmdev_ops *ops, |
432 | int number, /* -1 == pick first available */ | ||
433 | unsigned long *flags); | ||
432 | struct atm_dev *atm_dev_lookup(int number); | 434 | struct atm_dev *atm_dev_lookup(int number); |
433 | void atm_dev_deregister(struct atm_dev *dev); | 435 | void atm_dev_deregister(struct atm_dev *dev); |
434 | 436 | ||
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index aae86fd10c4f..36ab42c9bb99 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h | |||
@@ -250,7 +250,7 @@ struct queue_limits { | |||
250 | 250 | ||
251 | unsigned char misaligned; | 251 | unsigned char misaligned; |
252 | unsigned char discard_misaligned; | 252 | unsigned char discard_misaligned; |
253 | unsigned char no_cluster; | 253 | unsigned char cluster; |
254 | signed char discard_zeroes_data; | 254 | signed char discard_zeroes_data; |
255 | }; | 255 | }; |
256 | 256 | ||
@@ -380,7 +380,6 @@ struct request_queue | |||
380 | #endif | 380 | #endif |
381 | }; | 381 | }; |
382 | 382 | ||
383 | #define QUEUE_FLAG_CLUSTER 0 /* cluster several segments into 1 */ | ||
384 | #define QUEUE_FLAG_QUEUED 1 /* uses generic tag queueing */ | 383 | #define QUEUE_FLAG_QUEUED 1 /* uses generic tag queueing */ |
385 | #define QUEUE_FLAG_STOPPED 2 /* queue is stopped */ | 384 | #define QUEUE_FLAG_STOPPED 2 /* queue is stopped */ |
386 | #define QUEUE_FLAG_SYNCFULL 3 /* read queue has been filled */ | 385 | #define QUEUE_FLAG_SYNCFULL 3 /* read queue has been filled */ |
@@ -403,7 +402,6 @@ struct request_queue | |||
403 | #define QUEUE_FLAG_SECDISCARD 19 /* supports SECDISCARD */ | 402 | #define QUEUE_FLAG_SECDISCARD 19 /* supports SECDISCARD */ |
404 | 403 | ||
405 | #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ | 404 | #define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \ |
406 | (1 << QUEUE_FLAG_CLUSTER) | \ | ||
407 | (1 << QUEUE_FLAG_STACKABLE) | \ | 405 | (1 << QUEUE_FLAG_STACKABLE) | \ |
408 | (1 << QUEUE_FLAG_SAME_COMP) | \ | 406 | (1 << QUEUE_FLAG_SAME_COMP) | \ |
409 | (1 << QUEUE_FLAG_ADD_RANDOM)) | 407 | (1 << QUEUE_FLAG_ADD_RANDOM)) |
@@ -510,6 +508,11 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q) | |||
510 | 508 | ||
511 | #define rq_data_dir(rq) ((rq)->cmd_flags & 1) | 509 | #define rq_data_dir(rq) ((rq)->cmd_flags & 1) |
512 | 510 | ||
511 | static inline unsigned int blk_queue_cluster(struct request_queue *q) | ||
512 | { | ||
513 | return q->limits.cluster; | ||
514 | } | ||
515 | |||
513 | /* | 516 | /* |
514 | * We regard a request as sync, if either a read or a sync write | 517 | * We regard a request as sync, if either a read or a sync write |
515 | */ | 518 | */ |
@@ -805,6 +808,7 @@ extern struct request_queue *blk_init_allocated_queue(struct request_queue *, | |||
805 | extern void blk_cleanup_queue(struct request_queue *); | 808 | extern void blk_cleanup_queue(struct request_queue *); |
806 | extern void blk_queue_make_request(struct request_queue *, make_request_fn *); | 809 | extern void blk_queue_make_request(struct request_queue *, make_request_fn *); |
807 | extern void blk_queue_bounce_limit(struct request_queue *, u64); | 810 | extern void blk_queue_bounce_limit(struct request_queue *, u64); |
811 | extern void blk_limits_max_hw_sectors(struct queue_limits *, unsigned int); | ||
808 | extern void blk_queue_max_hw_sectors(struct request_queue *, unsigned int); | 812 | extern void blk_queue_max_hw_sectors(struct request_queue *, unsigned int); |
809 | extern void blk_queue_max_segments(struct request_queue *, unsigned short); | 813 | extern void blk_queue_max_segments(struct request_queue *, unsigned short); |
810 | extern void blk_queue_max_segment_size(struct request_queue *, unsigned int); | 814 | extern void blk_queue_max_segment_size(struct request_queue *, unsigned int); |
diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h index 266ab9291232..499dfe982a0e 100644 --- a/include/linux/bootmem.h +++ b/include/linux/bootmem.h | |||
@@ -105,6 +105,8 @@ extern void *__alloc_bootmem_low_node(pg_data_t *pgdat, | |||
105 | 105 | ||
106 | #define alloc_bootmem(x) \ | 106 | #define alloc_bootmem(x) \ |
107 | __alloc_bootmem(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) | 107 | __alloc_bootmem(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) |
108 | #define alloc_bootmem_align(x, align) \ | ||
109 | __alloc_bootmem(x, align, __pa(MAX_DMA_ADDRESS)) | ||
108 | #define alloc_bootmem_nopanic(x) \ | 110 | #define alloc_bootmem_nopanic(x) \ |
109 | __alloc_bootmem_nopanic(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) | 111 | __alloc_bootmem_nopanic(x, SMP_CACHE_BYTES, __pa(MAX_DMA_ADDRESS)) |
110 | #define alloc_bootmem_pages(x) \ | 112 | #define alloc_bootmem_pages(x) \ |
diff --git a/include/linux/ceph/libceph.h b/include/linux/ceph/libceph.h index 9e76d35670d2..72c72bfccb88 100644 --- a/include/linux/ceph/libceph.h +++ b/include/linux/ceph/libceph.h | |||
@@ -227,8 +227,10 @@ extern int ceph_open_session(struct ceph_client *client); | |||
227 | extern void ceph_release_page_vector(struct page **pages, int num_pages); | 227 | extern void ceph_release_page_vector(struct page **pages, int num_pages); |
228 | 228 | ||
229 | extern struct page **ceph_get_direct_page_vector(const char __user *data, | 229 | extern struct page **ceph_get_direct_page_vector(const char __user *data, |
230 | int num_pages); | 230 | int num_pages, |
231 | extern void ceph_put_page_vector(struct page **pages, int num_pages); | 231 | bool write_page); |
232 | extern void ceph_put_page_vector(struct page **pages, int num_pages, | ||
233 | bool dirty); | ||
232 | extern void ceph_release_page_vector(struct page **pages, int num_pages); | 234 | extern void ceph_release_page_vector(struct page **pages, int num_pages); |
233 | extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags); | 235 | extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags); |
234 | extern int ceph_copy_user_to_page_vector(struct page **pages, | 236 | extern int ceph_copy_user_to_page_vector(struct page **pages, |
diff --git a/include/linux/cnt32_to_63.h b/include/linux/cnt32_to_63.h index 7605fdd1eb65..e3d8bf26e5eb 100644 --- a/include/linux/cnt32_to_63.h +++ b/include/linux/cnt32_to_63.h | |||
@@ -61,13 +61,31 @@ union cnt32_to_63 { | |||
61 | * | 61 | * |
62 | * 2) this code must not be preempted for a duration longer than the | 62 | * 2) this code must not be preempted for a duration longer than the |
63 | * 32-bit counter half period minus the longest period between two | 63 | * 32-bit counter half period minus the longest period between two |
64 | * calls to this code. | 64 | * calls to this code; |
65 | * | 65 | * |
66 | * Those requirements ensure proper update to the state bit in memory. | 66 | * Those requirements ensure proper update to the state bit in memory. |
67 | * This is usually not a problem in practice, but if it is then a kernel | 67 | * This is usually not a problem in practice, but if it is then a kernel |
68 | * timer should be scheduled to manage for this code to be executed often | 68 | * timer should be scheduled to manage for this code to be executed often |
69 | * enough. | 69 | * enough. |
70 | * | 70 | * |
71 | * And finally: | ||
72 | * | ||
73 | * 3) the cnt_lo argument must be seen as a globally incrementing value, | ||
74 | * meaning that it should be a direct reference to the counter data which | ||
75 | * can be evaluated according to a specific ordering within the macro, | ||
76 | * and not the result of a previous evaluation stored in a variable. | ||
77 | * | ||
78 | * For example, this is wrong: | ||
79 | * | ||
80 | * u32 partial = get_hw_count(); | ||
81 | * u64 full = cnt32_to_63(partial); | ||
82 | * return full; | ||
83 | * | ||
84 | * This is fine: | ||
85 | * | ||
86 | * u64 full = cnt32_to_63(get_hw_count()); | ||
87 | * return full; | ||
88 | * | ||
71 | * Note that the top bit (bit 63) in the returned value should be considered | 89 | * Note that the top bit (bit 63) in the returned value should be considered |
72 | * as garbage. It is not cleared here because callers are likely to use a | 90 | * as garbage. It is not cleared here because callers are likely to use a |
73 | * multiplier on the returned value which can get rid of the top bit | 91 | * multiplier on the returned value which can get rid of the top bit |
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 9d8688b92d8b..8cd00ad98d37 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h | |||
@@ -824,6 +824,8 @@ enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie); | |||
824 | #ifdef CONFIG_DMA_ENGINE | 824 | #ifdef CONFIG_DMA_ENGINE |
825 | enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx); | 825 | enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx); |
826 | void dma_issue_pending_all(void); | 826 | void dma_issue_pending_all(void); |
827 | struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, void *fn_param); | ||
828 | void dma_release_channel(struct dma_chan *chan); | ||
827 | #else | 829 | #else |
828 | static inline enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx) | 830 | static inline enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descriptor *tx) |
829 | { | 831 | { |
@@ -831,7 +833,14 @@ static inline enum dma_status dma_wait_for_async_tx(struct dma_async_tx_descript | |||
831 | } | 833 | } |
832 | static inline void dma_issue_pending_all(void) | 834 | static inline void dma_issue_pending_all(void) |
833 | { | 835 | { |
834 | do { } while (0); | 836 | } |
837 | static inline struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, | ||
838 | dma_filter_fn fn, void *fn_param) | ||
839 | { | ||
840 | return NULL; | ||
841 | } | ||
842 | static inline void dma_release_channel(struct dma_chan *chan) | ||
843 | { | ||
835 | } | 844 | } |
836 | #endif | 845 | #endif |
837 | 846 | ||
@@ -842,8 +851,6 @@ void dma_async_device_unregister(struct dma_device *device); | |||
842 | void dma_run_dependencies(struct dma_async_tx_descriptor *tx); | 851 | void dma_run_dependencies(struct dma_async_tx_descriptor *tx); |
843 | struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type); | 852 | struct dma_chan *dma_find_channel(enum dma_transaction_type tx_type); |
844 | #define dma_request_channel(mask, x, y) __dma_request_channel(&(mask), x, y) | 853 | #define dma_request_channel(mask, x, y) __dma_request_channel(&(mask), x, y) |
845 | struct dma_chan *__dma_request_channel(dma_cap_mask_t *mask, dma_filter_fn fn, void *fn_param); | ||
846 | void dma_release_channel(struct dma_chan *chan); | ||
847 | 854 | ||
848 | /* --- Helper iov-locking functions --- */ | 855 | /* --- Helper iov-locking functions --- */ |
849 | 856 | ||
diff --git a/include/linux/fanotify.h b/include/linux/fanotify.h index 0f0121467fc4..6c6133f76e16 100644 --- a/include/linux/fanotify.h +++ b/include/linux/fanotify.h | |||
@@ -83,11 +83,13 @@ | |||
83 | FAN_ALL_PERM_EVENTS |\ | 83 | FAN_ALL_PERM_EVENTS |\ |
84 | FAN_Q_OVERFLOW) | 84 | FAN_Q_OVERFLOW) |
85 | 85 | ||
86 | #define FANOTIFY_METADATA_VERSION 2 | 86 | #define FANOTIFY_METADATA_VERSION 3 |
87 | 87 | ||
88 | struct fanotify_event_metadata { | 88 | struct fanotify_event_metadata { |
89 | __u32 event_len; | 89 | __u32 event_len; |
90 | __u32 vers; | 90 | __u8 vers; |
91 | __u8 reserved; | ||
92 | __u16 metadata_len; | ||
91 | __aligned_u64 mask; | 93 | __aligned_u64 mask; |
92 | __s32 fd; | 94 | __s32 fd; |
93 | __s32 pid; | 95 | __s32 pid; |
@@ -96,11 +98,13 @@ struct fanotify_event_metadata { | |||
96 | struct fanotify_response { | 98 | struct fanotify_response { |
97 | __s32 fd; | 99 | __s32 fd; |
98 | __u32 response; | 100 | __u32 response; |
99 | } __attribute__ ((packed)); | 101 | }; |
100 | 102 | ||
101 | /* Legit userspace responses to a _PERM event */ | 103 | /* Legit userspace responses to a _PERM event */ |
102 | #define FAN_ALLOW 0x01 | 104 | #define FAN_ALLOW 0x01 |
103 | #define FAN_DENY 0x02 | 105 | #define FAN_DENY 0x02 |
106 | /* No fd set in event */ | ||
107 | #define FAN_NOFD -1 | ||
104 | 108 | ||
105 | /* Helper functions to deal with fanotify_event_metadata buffers */ | 109 | /* Helper functions to deal with fanotify_event_metadata buffers */ |
106 | #define FAN_EVENT_METADATA_LEN (sizeof(struct fanotify_event_metadata)) | 110 | #define FAN_EVENT_METADATA_LEN (sizeof(struct fanotify_event_metadata)) |
diff --git a/include/linux/fs.h b/include/linux/fs.h index c9e06cc70dad..090f0eacde29 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -602,6 +602,7 @@ struct address_space_operations { | |||
602 | sector_t (*bmap)(struct address_space *, sector_t); | 602 | sector_t (*bmap)(struct address_space *, sector_t); |
603 | void (*invalidatepage) (struct page *, unsigned long); | 603 | void (*invalidatepage) (struct page *, unsigned long); |
604 | int (*releasepage) (struct page *, gfp_t); | 604 | int (*releasepage) (struct page *, gfp_t); |
605 | void (*freepage)(struct page *); | ||
605 | ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov, | 606 | ssize_t (*direct_IO)(int, struct kiocb *, const struct iovec *iov, |
606 | loff_t offset, unsigned long nr_segs); | 607 | loff_t offset, unsigned long nr_segs); |
607 | int (*get_xip_mem)(struct address_space *, pgoff_t, int, | 608 | int (*get_xip_mem)(struct address_space *, pgoff_t, int, |
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 5c185fa27089..b10bcdeaef76 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h | |||
@@ -235,9 +235,6 @@ static inline void fsnotify_open(struct file *file) | |||
235 | if (S_ISDIR(inode->i_mode)) | 235 | if (S_ISDIR(inode->i_mode)) |
236 | mask |= FS_ISDIR; | 236 | mask |= FS_ISDIR; |
237 | 237 | ||
238 | /* FMODE_NONOTIFY must never be set from user */ | ||
239 | file->f_mode &= ~FMODE_NONOTIFY; | ||
240 | |||
241 | fsnotify_parent(path, NULL, mask); | 238 | fsnotify_parent(path, NULL, mask); |
242 | fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); | 239 | fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0); |
243 | } | 240 | } |
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 0a68f924f06f..7380763595d3 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h | |||
@@ -166,7 +166,7 @@ struct fsnotify_group { | |||
166 | struct mutex access_mutex; | 166 | struct mutex access_mutex; |
167 | struct list_head access_list; | 167 | struct list_head access_list; |
168 | wait_queue_head_t access_waitq; | 168 | wait_queue_head_t access_waitq; |
169 | bool bypass_perm; /* protected by access_mutex */ | 169 | atomic_t bypass_perm; |
170 | #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */ | 170 | #endif /* CONFIG_FANOTIFY_ACCESS_PERMISSIONS */ |
171 | int f_flags; | 171 | int f_flags; |
172 | unsigned int max_marks; | 172 | unsigned int max_marks; |
diff --git a/include/linux/gpio_keys.h b/include/linux/gpio_keys.h index ce73a30113b4..dd1a56fbe924 100644 --- a/include/linux/gpio_keys.h +++ b/include/linux/gpio_keys.h | |||
@@ -16,6 +16,8 @@ struct gpio_keys_button { | |||
16 | struct gpio_keys_platform_data { | 16 | struct gpio_keys_platform_data { |
17 | struct gpio_keys_button *buttons; | 17 | struct gpio_keys_button *buttons; |
18 | int nbuttons; | 18 | int nbuttons; |
19 | unsigned int poll_interval; /* polling interval in msecs - | ||
20 | for polling driver only */ | ||
19 | unsigned int rep:1; /* enable input subsystem auto repeat */ | 21 | unsigned int rep:1; /* enable input subsystem auto repeat */ |
20 | int (*enable)(struct device *dev); | 22 | int (*enable)(struct device *dev); |
21 | void (*disable)(struct device *dev); | 23 | void (*disable)(struct device *dev); |
diff --git a/include/linux/input.h b/include/linux/input.h index 6ef44465db8d..9777668883be 100644 --- a/include/linux/input.h +++ b/include/linux/input.h | |||
@@ -47,6 +47,25 @@ struct input_id { | |||
47 | __u16 version; | 47 | __u16 version; |
48 | }; | 48 | }; |
49 | 49 | ||
50 | /** | ||
51 | * struct input_absinfo - used by EVIOCGABS/EVIOCSABS ioctls | ||
52 | * @value: latest reported value for the axis. | ||
53 | * @minimum: specifies minimum value for the axis. | ||
54 | * @maximum: specifies maximum value for the axis. | ||
55 | * @fuzz: specifies fuzz value that is used to filter noise from | ||
56 | * the event stream. | ||
57 | * @flat: values that are within this value will be discarded by | ||
58 | * joydev interface and reported as 0 instead. | ||
59 | * @resolution: specifies resolution for the values reported for | ||
60 | * the axis. | ||
61 | * | ||
62 | * Note that input core does not clamp reported values to the | ||
63 | * [minimum, maximum] limits, such task is left to userspace. | ||
64 | * | ||
65 | * Resolution for main axes (ABS_X, ABS_Y, ABS_Z) is reported in | ||
66 | * units per millimeter (units/mm), resolution for rotational axes | ||
67 | * (ABS_RX, ABS_RY, ABS_RZ) is reported in units per radian. | ||
68 | */ | ||
50 | struct input_absinfo { | 69 | struct input_absinfo { |
51 | __s32 value; | 70 | __s32 value; |
52 | __s32 minimum; | 71 | __s32 minimum; |
@@ -85,8 +104,10 @@ struct input_keymap_entry { | |||
85 | #define EVIOCGREP _IOR('E', 0x03, unsigned int[2]) /* get repeat settings */ | 104 | #define EVIOCGREP _IOR('E', 0x03, unsigned int[2]) /* get repeat settings */ |
86 | #define EVIOCSREP _IOW('E', 0x03, unsigned int[2]) /* set repeat settings */ | 105 | #define EVIOCSREP _IOW('E', 0x03, unsigned int[2]) /* set repeat settings */ |
87 | 106 | ||
88 | #define EVIOCGKEYCODE _IOR('E', 0x04, struct input_keymap_entry) /* get keycode */ | 107 | #define EVIOCGKEYCODE _IOR('E', 0x04, unsigned int[2]) /* get keycode */ |
89 | #define EVIOCSKEYCODE _IOW('E', 0x04, struct input_keymap_entry) /* set keycode */ | 108 | #define EVIOCGKEYCODE_V2 _IOR('E', 0x04, struct input_keymap_entry) |
109 | #define EVIOCSKEYCODE _IOW('E', 0x04, unsigned int[2]) /* set keycode */ | ||
110 | #define EVIOCSKEYCODE_V2 _IOW('E', 0x04, struct input_keymap_entry) | ||
90 | 111 | ||
91 | #define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */ | 112 | #define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */ |
92 | #define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */ | 113 | #define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */ |
@@ -624,6 +645,10 @@ struct input_keymap_entry { | |||
624 | #define KEY_CAMERA_FOCUS 0x210 | 645 | #define KEY_CAMERA_FOCUS 0x210 |
625 | #define KEY_WPS_BUTTON 0x211 /* WiFi Protected Setup key */ | 646 | #define KEY_WPS_BUTTON 0x211 /* WiFi Protected Setup key */ |
626 | 647 | ||
648 | #define KEY_TOUCHPAD_TOGGLE 0x212 /* Request switch touchpad on or off */ | ||
649 | #define KEY_TOUCHPAD_ON 0x213 | ||
650 | #define KEY_TOUCHPAD_OFF 0x214 | ||
651 | |||
627 | #define BTN_TRIGGER_HAPPY 0x2c0 | 652 | #define BTN_TRIGGER_HAPPY 0x2c0 |
628 | #define BTN_TRIGGER_HAPPY1 0x2c0 | 653 | #define BTN_TRIGGER_HAPPY1 0x2c0 |
629 | #define BTN_TRIGGER_HAPPY2 0x2c1 | 654 | #define BTN_TRIGGER_HAPPY2 0x2c1 |
@@ -1130,7 +1155,7 @@ struct input_mt_slot { | |||
1130 | * of tracked contacts | 1155 | * of tracked contacts |
1131 | * @mtsize: number of MT slots the device uses | 1156 | * @mtsize: number of MT slots the device uses |
1132 | * @slot: MT slot currently being transmitted | 1157 | * @slot: MT slot currently being transmitted |
1133 | * @absinfo: array of &struct absinfo elements holding information | 1158 | * @absinfo: array of &struct input_absinfo elements holding information |
1134 | * about absolute axes (current value, min, max, flat, fuzz, | 1159 | * about absolute axes (current value, min, max, flat, fuzz, |
1135 | * resolution) | 1160 | * resolution) |
1136 | * @key: reflects current state of device's keys/buttons | 1161 | * @key: reflects current state of device's keys/buttons |
diff --git a/include/linux/ioport.h b/include/linux/ioport.h index d377ea815d45..e9bb22cba764 100644 --- a/include/linux/ioport.h +++ b/include/linux/ioport.h | |||
@@ -112,7 +112,6 @@ struct resource_list { | |||
112 | /* PC/ISA/whatever - the normal PC address spaces: IO and memory */ | 112 | /* PC/ISA/whatever - the normal PC address spaces: IO and memory */ |
113 | extern struct resource ioport_resource; | 113 | extern struct resource ioport_resource; |
114 | extern struct resource iomem_resource; | 114 | extern struct resource iomem_resource; |
115 | extern int resource_alloc_from_bottom; | ||
116 | 115 | ||
117 | extern struct resource *request_resource_conflict(struct resource *root, struct resource *new); | 116 | extern struct resource *request_resource_conflict(struct resource *root, struct resource *new); |
118 | extern int request_resource(struct resource *root, struct resource *new); | 117 | extern int request_resource(struct resource *root, struct resource *new); |
@@ -124,6 +123,7 @@ extern void reserve_region_with_split(struct resource *root, | |||
124 | extern struct resource *insert_resource_conflict(struct resource *parent, struct resource *new); | 123 | extern struct resource *insert_resource_conflict(struct resource *parent, struct resource *new); |
125 | extern int insert_resource(struct resource *parent, struct resource *new); | 124 | extern int insert_resource(struct resource *parent, struct resource *new); |
126 | extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new); | 125 | extern void insert_resource_expand_to_fit(struct resource *root, struct resource *new); |
126 | extern void arch_remove_reservations(struct resource *avail); | ||
127 | extern int allocate_resource(struct resource *root, struct resource *new, | 127 | extern int allocate_resource(struct resource *root, struct resource *new, |
128 | resource_size_t size, resource_size_t min, | 128 | resource_size_t size, resource_size_t min, |
129 | resource_size_t max, resource_size_t align, | 129 | resource_size_t max, resource_size_t align, |
diff --git a/include/linux/kthread.h b/include/linux/kthread.h index 685ea65eb803..ce0775aa64c3 100644 --- a/include/linux/kthread.h +++ b/include/linux/kthread.h | |||
@@ -81,16 +81,41 @@ struct kthread_work { | |||
81 | #define DEFINE_KTHREAD_WORK(work, fn) \ | 81 | #define DEFINE_KTHREAD_WORK(work, fn) \ |
82 | struct kthread_work work = KTHREAD_WORK_INIT(work, fn) | 82 | struct kthread_work work = KTHREAD_WORK_INIT(work, fn) |
83 | 83 | ||
84 | static inline void init_kthread_worker(struct kthread_worker *worker) | 84 | /* |
85 | { | 85 | * kthread_worker.lock and kthread_work.done need their own lockdep class |
86 | *worker = (struct kthread_worker)KTHREAD_WORKER_INIT(*worker); | 86 | * keys if they are defined on stack with lockdep enabled. Use the |
87 | } | 87 | * following macros when defining them on stack. |
88 | 88 | */ | |
89 | static inline void init_kthread_work(struct kthread_work *work, | 89 | #ifdef CONFIG_LOCKDEP |
90 | kthread_work_func_t fn) | 90 | # define KTHREAD_WORKER_INIT_ONSTACK(worker) \ |
91 | { | 91 | ({ init_kthread_worker(&worker); worker; }) |
92 | *work = (struct kthread_work)KTHREAD_WORK_INIT(*work, fn); | 92 | # define DEFINE_KTHREAD_WORKER_ONSTACK(worker) \ |
93 | } | 93 | struct kthread_worker worker = KTHREAD_WORKER_INIT_ONSTACK(worker) |
94 | # define KTHREAD_WORK_INIT_ONSTACK(work, fn) \ | ||
95 | ({ init_kthread_work((&work), fn); work; }) | ||
96 | # define DEFINE_KTHREAD_WORK_ONSTACK(work, fn) \ | ||
97 | struct kthread_work work = KTHREAD_WORK_INIT_ONSTACK(work, fn) | ||
98 | #else | ||
99 | # define DEFINE_KTHREAD_WORKER_ONSTACK(worker) DEFINE_KTHREAD_WORKER(worker) | ||
100 | # define DEFINE_KTHREAD_WORK_ONSTACK(work, fn) DEFINE_KTHREAD_WORK(work, fn) | ||
101 | #endif | ||
102 | |||
103 | extern void __init_kthread_worker(struct kthread_worker *worker, | ||
104 | const char *name, struct lock_class_key *key); | ||
105 | |||
106 | #define init_kthread_worker(worker) \ | ||
107 | do { \ | ||
108 | static struct lock_class_key __key; \ | ||
109 | __init_kthread_worker((worker), "("#worker")->lock", &__key); \ | ||
110 | } while (0) | ||
111 | |||
112 | #define init_kthread_work(work, fn) \ | ||
113 | do { \ | ||
114 | memset((work), 0, sizeof(struct kthread_work)); \ | ||
115 | INIT_LIST_HEAD(&(work)->node); \ | ||
116 | (work)->func = (fn); \ | ||
117 | init_waitqueue_head(&(work)->done); \ | ||
118 | } while (0) | ||
94 | 119 | ||
95 | int kthread_worker_fn(void *worker_ptr); | 120 | int kthread_worker_fn(void *worker_ptr); |
96 | 121 | ||
diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h index 5c51f367c061..add8a1b8bcf0 100644 --- a/include/linux/mfd/wm8994/pdata.h +++ b/include/linux/mfd/wm8994/pdata.h | |||
@@ -29,7 +29,7 @@ struct wm8994_ldo_pdata { | |||
29 | #define WM8994_CONFIGURE_GPIO 0x8000 | 29 | #define WM8994_CONFIGURE_GPIO 0x8000 |
30 | 30 | ||
31 | #define WM8994_DRC_REGS 5 | 31 | #define WM8994_DRC_REGS 5 |
32 | #define WM8994_EQ_REGS 19 | 32 | #define WM8994_EQ_REGS 20 |
33 | 33 | ||
34 | /** | 34 | /** |
35 | * DRC configurations are specified with a label and a set of register | 35 | * DRC configurations are specified with a label and a set of register |
diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 123566912d73..e2b9e63afa68 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h | |||
@@ -70,7 +70,7 @@ struct nlmsghdr { | |||
70 | Check NLM_F_EXCL | 70 | Check NLM_F_EXCL |
71 | */ | 71 | */ |
72 | 72 | ||
73 | #define NLMSG_ALIGNTO 4 | 73 | #define NLMSG_ALIGNTO 4U |
74 | #define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) ) | 74 | #define NLMSG_ALIGN(len) ( ((len)+NLMSG_ALIGNTO-1) & ~(NLMSG_ALIGNTO-1) ) |
75 | #define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr))) | 75 | #define NLMSG_HDRLEN ((int) NLMSG_ALIGN(sizeof(struct nlmsghdr))) |
76 | #define NLMSG_LENGTH(len) ((len)+NLMSG_ALIGN(NLMSG_HDRLEN)) | 76 | #define NLMSG_LENGTH(len) ((len)+NLMSG_ALIGN(NLMSG_HDRLEN)) |
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index c66fdb7d6998..29d504d5d1c3 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h | |||
@@ -401,6 +401,7 @@ extern const struct inode_operations nfs3_file_inode_operations; | |||
401 | #endif /* CONFIG_NFS_V3 */ | 401 | #endif /* CONFIG_NFS_V3 */ |
402 | extern const struct file_operations nfs_file_operations; | 402 | extern const struct file_operations nfs_file_operations; |
403 | extern const struct address_space_operations nfs_file_aops; | 403 | extern const struct address_space_operations nfs_file_aops; |
404 | extern const struct address_space_operations nfs_dir_aops; | ||
404 | 405 | ||
405 | static inline struct nfs_open_context *nfs_file_open_context(struct file *filp) | 406 | static inline struct nfs_open_context *nfs_file_open_context(struct file *filp) |
406 | { | 407 | { |
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h index f8b60e7f4c44..d55cee73f634 100644 --- a/include/linux/nfs_page.h +++ b/include/linux/nfs_page.h | |||
@@ -29,6 +29,7 @@ | |||
29 | */ | 29 | */ |
30 | enum { | 30 | enum { |
31 | PG_BUSY = 0, | 31 | PG_BUSY = 0, |
32 | PG_MAPPED, | ||
32 | PG_CLEAN, | 33 | PG_CLEAN, |
33 | PG_NEED_COMMIT, | 34 | PG_NEED_COMMIT, |
34 | PG_NEED_RESCHED, | 35 | PG_NEED_RESCHED, |
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index de2c41758e29..4f1279e105ee 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
@@ -887,6 +887,7 @@ struct perf_cpu_context { | |||
887 | int exclusive; | 887 | int exclusive; |
888 | struct list_head rotation_list; | 888 | struct list_head rotation_list; |
889 | int jiffies_interval; | 889 | int jiffies_interval; |
890 | struct pmu *active_pmu; | ||
890 | }; | 891 | }; |
891 | 892 | ||
892 | struct perf_output_handle { | 893 | struct perf_output_handle { |
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index 3ec2358f8692..d19f1cca7f74 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h | |||
@@ -77,7 +77,8 @@ static inline void device_set_run_wake(struct device *dev, bool enable) | |||
77 | 77 | ||
78 | static inline bool pm_runtime_suspended(struct device *dev) | 78 | static inline bool pm_runtime_suspended(struct device *dev) |
79 | { | 79 | { |
80 | return dev->power.runtime_status == RPM_SUSPENDED; | 80 | return dev->power.runtime_status == RPM_SUSPENDED |
81 | && !dev->power.disable_depth; | ||
81 | } | 82 | } |
82 | 83 | ||
83 | static inline void pm_runtime_mark_last_busy(struct device *dev) | 84 | static inline void pm_runtime_mark_last_busy(struct device *dev) |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 2c79e921a68b..223874538b33 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -143,7 +143,7 @@ extern unsigned long nr_iowait_cpu(int cpu); | |||
143 | extern unsigned long this_cpu_load(void); | 143 | extern unsigned long this_cpu_load(void); |
144 | 144 | ||
145 | 145 | ||
146 | extern void calc_global_load(void); | 146 | extern void calc_global_load(unsigned long ticks); |
147 | 147 | ||
148 | extern unsigned long get_parent_ip(unsigned long addr); | 148 | extern unsigned long get_parent_ip(unsigned long addr); |
149 | 149 | ||
diff --git a/include/linux/snmp.h b/include/linux/snmp.h index ebb0c80ffd6e..12b2b18e50c1 100644 --- a/include/linux/snmp.h +++ b/include/linux/snmp.h | |||
@@ -230,6 +230,7 @@ enum | |||
230 | LINUX_MIB_TCPMINTTLDROP, /* RFC 5082 */ | 230 | LINUX_MIB_TCPMINTTLDROP, /* RFC 5082 */ |
231 | LINUX_MIB_TCPDEFERACCEPTDROP, | 231 | LINUX_MIB_TCPDEFERACCEPTDROP, |
232 | LINUX_MIB_IPRPFILTER, /* IP Reverse Path Filter (rp_filter) */ | 232 | LINUX_MIB_IPRPFILTER, /* IP Reverse Path Filter (rp_filter) */ |
233 | LINUX_MIB_TCPTIMEWAITOVERFLOW, /* TCPTimeWaitOverflow */ | ||
233 | __LINUX_MIB_MAX | 234 | __LINUX_MIB_MAX |
234 | }; | 235 | }; |
235 | 236 | ||
diff --git a/include/linux/ssb/ssb_driver_gige.h b/include/linux/ssb/ssb_driver_gige.h index 942e38736901..eba52a100533 100644 --- a/include/linux/ssb/ssb_driver_gige.h +++ b/include/linux/ssb/ssb_driver_gige.h | |||
@@ -96,16 +96,21 @@ static inline bool ssb_gige_must_flush_posted_writes(struct pci_dev *pdev) | |||
96 | return 0; | 96 | return 0; |
97 | } | 97 | } |
98 | 98 | ||
99 | extern char * nvram_get(const char *name); | 99 | #ifdef CONFIG_BCM47XX |
100 | #include <asm/mach-bcm47xx/nvram.h> | ||
100 | /* Get the device MAC address */ | 101 | /* Get the device MAC address */ |
101 | static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr) | 102 | static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr) |
102 | { | 103 | { |
103 | #ifdef CONFIG_BCM47XX | 104 | char buf[20]; |
104 | char *res = nvram_get("et0macaddr"); | 105 | if (nvram_getenv("et0macaddr", buf, sizeof(buf)) < 0) |
105 | if (res) | 106 | return; |
106 | memcpy(macaddr, res, 6); | 107 | nvram_parse_macaddr(buf, macaddr); |
107 | #endif | ||
108 | } | 108 | } |
109 | #else | ||
110 | static inline void ssb_gige_get_macaddr(struct pci_dev *pdev, u8 *macaddr) | ||
111 | { | ||
112 | } | ||
113 | #endif | ||
109 | 114 | ||
110 | extern int ssb_gige_pcibios_plat_dev_init(struct ssb_device *sdev, | 115 | extern int ssb_gige_pcibios_plat_dev_init(struct ssb_device *sdev, |
111 | struct pci_dev *pdev); | 116 | struct pci_dev *pdev); |
diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 26697514c5ec..0e288e3c37be 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h | |||
@@ -258,23 +258,6 @@ static inline int hibernate(void) { return -ENOSYS; } | |||
258 | static inline bool system_entering_hibernation(void) { return false; } | 258 | static inline bool system_entering_hibernation(void) { return false; } |
259 | #endif /* CONFIG_HIBERNATION */ | 259 | #endif /* CONFIG_HIBERNATION */ |
260 | 260 | ||
261 | #ifdef CONFIG_SUSPEND_NVS | ||
262 | extern int suspend_nvs_register(unsigned long start, unsigned long size); | ||
263 | extern int suspend_nvs_alloc(void); | ||
264 | extern void suspend_nvs_free(void); | ||
265 | extern void suspend_nvs_save(void); | ||
266 | extern void suspend_nvs_restore(void); | ||
267 | #else /* CONFIG_SUSPEND_NVS */ | ||
268 | static inline int suspend_nvs_register(unsigned long a, unsigned long b) | ||
269 | { | ||
270 | return 0; | ||
271 | } | ||
272 | static inline int suspend_nvs_alloc(void) { return 0; } | ||
273 | static inline void suspend_nvs_free(void) {} | ||
274 | static inline void suspend_nvs_save(void) {} | ||
275 | static inline void suspend_nvs_restore(void) {} | ||
276 | #endif /* CONFIG_SUSPEND_NVS */ | ||
277 | |||
278 | #ifdef CONFIG_PM_SLEEP | 261 | #ifdef CONFIG_PM_SLEEP |
279 | void save_processor_state(void); | 262 | void save_processor_state(void); |
280 | void restore_processor_state(void); | 263 | void restore_processor_state(void); |
diff --git a/include/linux/taskstats.h b/include/linux/taskstats.h index 341dddb55090..2466e550a41d 100644 --- a/include/linux/taskstats.h +++ b/include/linux/taskstats.h | |||
@@ -33,7 +33,7 @@ | |||
33 | */ | 33 | */ |
34 | 34 | ||
35 | 35 | ||
36 | #define TASKSTATS_VERSION 7 | 36 | #define TASKSTATS_VERSION 8 |
37 | #define TS_COMM_LEN 32 /* should be >= TASK_COMM_LEN | 37 | #define TS_COMM_LEN 32 /* should be >= TASK_COMM_LEN |
38 | * in linux/sched.h */ | 38 | * in linux/sched.h */ |
39 | 39 | ||
@@ -188,6 +188,7 @@ enum { | |||
188 | TASKSTATS_TYPE_STATS, /* taskstats structure */ | 188 | TASKSTATS_TYPE_STATS, /* taskstats structure */ |
189 | TASKSTATS_TYPE_AGGR_PID, /* contains pid + stats */ | 189 | TASKSTATS_TYPE_AGGR_PID, /* contains pid + stats */ |
190 | TASKSTATS_TYPE_AGGR_TGID, /* contains tgid + stats */ | 190 | TASKSTATS_TYPE_AGGR_TGID, /* contains tgid + stats */ |
191 | TASKSTATS_TYPE_NULL, /* contains nothing */ | ||
191 | __TASKSTATS_TYPE_MAX, | 192 | __TASKSTATS_TYPE_MAX, |
192 | }; | 193 | }; |
193 | 194 | ||
diff --git a/include/linux/unaligned/packed_struct.h b/include/linux/unaligned/packed_struct.h index 2498bb9fe002..c9a6abd972a1 100644 --- a/include/linux/unaligned/packed_struct.h +++ b/include/linux/unaligned/packed_struct.h | |||
@@ -3,9 +3,9 @@ | |||
3 | 3 | ||
4 | #include <linux/kernel.h> | 4 | #include <linux/kernel.h> |
5 | 5 | ||
6 | struct __una_u16 { u16 x __attribute__((packed)); }; | 6 | struct __una_u16 { u16 x; } __attribute__((packed)); |
7 | struct __una_u32 { u32 x __attribute__((packed)); }; | 7 | struct __una_u32 { u32 x; } __attribute__((packed)); |
8 | struct __una_u64 { u64 x __attribute__((packed)); }; | 8 | struct __una_u64 { u64 x; } __attribute__((packed)); |
9 | 9 | ||
10 | static inline u16 __get_unaligned_cpu16(const void *p) | 10 | static inline u16 __get_unaligned_cpu16(const void *p) |
11 | { | 11 | { |
diff --git a/include/linux/video_output.h b/include/linux/video_output.h index 2fb46bc9340d..ed5cdeb3604d 100644 --- a/include/linux/video_output.h +++ b/include/linux/video_output.h | |||
@@ -23,6 +23,7 @@ | |||
23 | #ifndef _LINUX_VIDEO_OUTPUT_H | 23 | #ifndef _LINUX_VIDEO_OUTPUT_H |
24 | #define _LINUX_VIDEO_OUTPUT_H | 24 | #define _LINUX_VIDEO_OUTPUT_H |
25 | #include <linux/device.h> | 25 | #include <linux/device.h> |
26 | #include <linux/err.h> | ||
26 | struct output_device; | 27 | struct output_device; |
27 | struct output_properties { | 28 | struct output_properties { |
28 | int (*set_state)(struct output_device *); | 29 | int (*set_state)(struct output_device *); |
@@ -34,9 +35,23 @@ struct output_device { | |||
34 | struct device dev; | 35 | struct device dev; |
35 | }; | 36 | }; |
36 | #define to_output_device(obj) container_of(obj, struct output_device, dev) | 37 | #define to_output_device(obj) container_of(obj, struct output_device, dev) |
38 | #if defined(CONFIG_VIDEO_OUTPUT_CONTROL) || defined(CONFIG_VIDEO_OUTPUT_CONTROL_MODULE) | ||
37 | struct output_device *video_output_register(const char *name, | 39 | struct output_device *video_output_register(const char *name, |
38 | struct device *dev, | 40 | struct device *dev, |
39 | void *devdata, | 41 | void *devdata, |
40 | struct output_properties *op); | 42 | struct output_properties *op); |
41 | void video_output_unregister(struct output_device *dev); | 43 | void video_output_unregister(struct output_device *dev); |
44 | #else | ||
45 | static struct output_device *video_output_register(const char *name, | ||
46 | struct device *dev, | ||
47 | void *devdata, | ||
48 | struct output_properties *op) | ||
49 | { | ||
50 | return ERR_PTR(-ENODEV); | ||
51 | } | ||
52 | static void video_output_unregister(struct output_device *dev) | ||
53 | { | ||
54 | return; | ||
55 | } | ||
56 | #endif | ||
42 | #endif | 57 | #endif |
diff --git a/include/media/saa7146.h b/include/media/saa7146.h index 7a9f76ecbbbd..ac7ce00f39cf 100644 --- a/include/media/saa7146.h +++ b/include/media/saa7146.h | |||
@@ -161,7 +161,7 @@ extern struct list_head saa7146_devices; | |||
161 | extern struct mutex saa7146_devices_lock; | 161 | extern struct mutex saa7146_devices_lock; |
162 | int saa7146_register_extension(struct saa7146_extension*); | 162 | int saa7146_register_extension(struct saa7146_extension*); |
163 | int saa7146_unregister_extension(struct saa7146_extension*); | 163 | int saa7146_unregister_extension(struct saa7146_extension*); |
164 | struct saa7146_format* format_by_fourcc(struct saa7146_dev *dev, int fourcc); | 164 | struct saa7146_format* saa7146_format_by_fourcc(struct saa7146_dev *dev, int fourcc); |
165 | int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt); | 165 | int saa7146_pgtable_alloc(struct pci_dev *pci, struct saa7146_pgtable *pt); |
166 | void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt); | 166 | void saa7146_pgtable_free(struct pci_dev *pci, struct saa7146_pgtable *pt); |
167 | int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt, struct scatterlist *list, int length ); | 167 | int saa7146_pgtable_build_single(struct pci_dev *pci, struct saa7146_pgtable *pt, struct scatterlist *list, int length ); |
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h index 6648036b728d..b16f307d471a 100644 --- a/include/media/v4l2-device.h +++ b/include/media/v4l2-device.h | |||
@@ -51,6 +51,8 @@ struct v4l2_device { | |||
51 | unsigned int notification, void *arg); | 51 | unsigned int notification, void *arg); |
52 | /* The control handler. May be NULL. */ | 52 | /* The control handler. May be NULL. */ |
53 | struct v4l2_ctrl_handler *ctrl_handler; | 53 | struct v4l2_ctrl_handler *ctrl_handler; |
54 | /* BKL replacement mutex. Temporary solution only. */ | ||
55 | struct mutex ioctl_lock; | ||
54 | }; | 56 | }; |
55 | 57 | ||
56 | /* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev. | 58 | /* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev. |
diff --git a/include/media/wm8775.h b/include/media/wm8775.h index a1c4d417dfa2..60739c5a23ae 100644 --- a/include/media/wm8775.h +++ b/include/media/wm8775.h | |||
@@ -32,7 +32,4 @@ | |||
32 | #define WM8775_AIN3 4 | 32 | #define WM8775_AIN3 4 |
33 | #define WM8775_AIN4 8 | 33 | #define WM8775_AIN4 8 |
34 | 34 | ||
35 | /* subdev group ID */ | ||
36 | #define WM8775_GID (1 << 0) | ||
37 | |||
38 | #endif | 35 | #endif |
diff --git a/include/net/flow.h b/include/net/flow.h index 0ac3fb5e0973..bb08692a20b0 100644 --- a/include/net/flow.h +++ b/include/net/flow.h | |||
@@ -49,7 +49,6 @@ struct flowi { | |||
49 | __u8 proto; | 49 | __u8 proto; |
50 | __u8 flags; | 50 | __u8 flags; |
51 | #define FLOWI_FLAG_ANYSRC 0x01 | 51 | #define FLOWI_FLAG_ANYSRC 0x01 |
52 | #define FLOWI_FLAG_MATCH_ANY_IIF 0x02 | ||
53 | union { | 52 | union { |
54 | struct { | 53 | struct { |
55 | __be16 sport; | 54 | __be16 sport; |
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h index 278312c95f96..2ab926860cd8 100644 --- a/include/net/ip6_route.h +++ b/include/net/ip6_route.h | |||
@@ -164,5 +164,15 @@ static inline int ipv6_unicast_destination(struct sk_buff *skb) | |||
164 | return rt->rt6i_flags & RTF_LOCAL; | 164 | return rt->rt6i_flags & RTF_LOCAL; |
165 | } | 165 | } |
166 | 166 | ||
167 | int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)); | ||
168 | |||
169 | static inline int ip6_skb_dst_mtu(struct sk_buff *skb) | ||
170 | { | ||
171 | struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL; | ||
172 | |||
173 | return (np && np->pmtudisc == IPV6_PMTUDISC_PROBE) ? | ||
174 | skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb)); | ||
175 | } | ||
176 | |||
167 | #endif | 177 | #endif |
168 | #endif | 178 | #endif |
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index 9fdf982d1286..365359b24177 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h | |||
@@ -2024,8 +2024,8 @@ static inline void ieee80211_rx_ni(struct ieee80211_hw *hw, | |||
2024 | * | 2024 | * |
2025 | * This function may not be called in IRQ context. Calls to this function | 2025 | * This function may not be called in IRQ context. Calls to this function |
2026 | * for a single hardware must be synchronized against each other. Calls | 2026 | * for a single hardware must be synchronized against each other. Calls |
2027 | * to this function and ieee80211_tx_status_irqsafe() may not be mixed | 2027 | * to this function, ieee80211_tx_status_ni() and ieee80211_tx_status_irqsafe() |
2028 | * for a single hardware. | 2028 | * may not be mixed for a single hardware. |
2029 | * | 2029 | * |
2030 | * @hw: the hardware the frame was transmitted by | 2030 | * @hw: the hardware the frame was transmitted by |
2031 | * @skb: the frame that was transmitted, owned by mac80211 after this call | 2031 | * @skb: the frame that was transmitted, owned by mac80211 after this call |
@@ -2034,13 +2034,33 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, | |||
2034 | struct sk_buff *skb); | 2034 | struct sk_buff *skb); |
2035 | 2035 | ||
2036 | /** | 2036 | /** |
2037 | * ieee80211_tx_status_ni - transmit status callback (in process context) | ||
2038 | * | ||
2039 | * Like ieee80211_tx_status() but can be called in process context. | ||
2040 | * | ||
2041 | * Calls to this function, ieee80211_tx_status() and | ||
2042 | * ieee80211_tx_status_irqsafe() may not be mixed | ||
2043 | * for a single hardware. | ||
2044 | * | ||
2045 | * @hw: the hardware the frame was transmitted by | ||
2046 | * @skb: the frame that was transmitted, owned by mac80211 after this call | ||
2047 | */ | ||
2048 | static inline void ieee80211_tx_status_ni(struct ieee80211_hw *hw, | ||
2049 | struct sk_buff *skb) | ||
2050 | { | ||
2051 | local_bh_disable(); | ||
2052 | ieee80211_tx_status(hw, skb); | ||
2053 | local_bh_enable(); | ||
2054 | } | ||
2055 | |||
2056 | /** | ||
2037 | * ieee80211_tx_status_irqsafe - IRQ-safe transmit status callback | 2057 | * ieee80211_tx_status_irqsafe - IRQ-safe transmit status callback |
2038 | * | 2058 | * |
2039 | * Like ieee80211_tx_status() but can be called in IRQ context | 2059 | * Like ieee80211_tx_status() but can be called in IRQ context |
2040 | * (internally defers to a tasklet.) | 2060 | * (internally defers to a tasklet.) |
2041 | * | 2061 | * |
2042 | * Calls to this function and ieee80211_tx_status() may not be mixed for a | 2062 | * Calls to this function, ieee80211_tx_status() and |
2043 | * single hardware. | 2063 | * ieee80211_tx_status_ni() may not be mixed for a single hardware. |
2044 | * | 2064 | * |
2045 | * @hw: the hardware the frame was transmitted by | 2065 | * @hw: the hardware the frame was transmitted by |
2046 | * @skb: the frame that was transmitted, owned by mac80211 after this call | 2066 | * @skb: the frame that was transmitted, owned by mac80211 after this call |
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h index dd3031aed9d5..9fcc680ab6b9 100644 --- a/include/net/pkt_cls.h +++ b/include/net/pkt_cls.h | |||
@@ -323,7 +323,9 @@ static inline unsigned char * tcf_get_base_ptr(struct sk_buff *skb, int layer) | |||
323 | static inline int tcf_valid_offset(const struct sk_buff *skb, | 323 | static inline int tcf_valid_offset(const struct sk_buff *skb, |
324 | const unsigned char *ptr, const int len) | 324 | const unsigned char *ptr, const int len) |
325 | { | 325 | { |
326 | return unlikely((ptr + len) < skb_tail_pointer(skb) && ptr > skb->head); | 326 | return likely((ptr + len) <= skb_tail_pointer(skb) && |
327 | ptr >= skb->head && | ||
328 | (ptr <= (ptr + len))); | ||
327 | } | 329 | } |
328 | 330 | ||
329 | #ifdef CONFIG_NET_CLS_IND | 331 | #ifdef CONFIG_NET_CLS_IND |
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h index ea1f8a83160d..79f34e2b752f 100644 --- a/include/net/sch_generic.h +++ b/include/net/sch_generic.h | |||
@@ -610,11 +610,7 @@ static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask, | |||
610 | { | 610 | { |
611 | struct sk_buff *n; | 611 | struct sk_buff *n; |
612 | 612 | ||
613 | if ((action == TC_ACT_STOLEN || action == TC_ACT_QUEUED) && | 613 | n = skb_clone(skb, gfp_mask); |
614 | !skb_shared(skb)) | ||
615 | n = skb_get(skb); | ||
616 | else | ||
617 | n = skb_clone(skb, gfp_mask); | ||
618 | 614 | ||
619 | if (n) { | 615 | if (n) { |
620 | n->tc_verd = SET_TC_VERD(n->tc_verd, 0); | 616 | n->tc_verd = SET_TC_VERD(n->tc_verd, 0); |
diff --git a/include/net/sock.h b/include/net/sock.h index a6338d039857..7d3f7ce239b5 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -754,6 +754,7 @@ struct proto { | |||
754 | void (*unhash)(struct sock *sk); | 754 | void (*unhash)(struct sock *sk); |
755 | void (*rehash)(struct sock *sk); | 755 | void (*rehash)(struct sock *sk); |
756 | int (*get_port)(struct sock *sk, unsigned short snum); | 756 | int (*get_port)(struct sock *sk, unsigned short snum); |
757 | void (*clear_sk)(struct sock *sk, int size); | ||
757 | 758 | ||
758 | /* Keeping track of sockets in use */ | 759 | /* Keeping track of sockets in use */ |
759 | #ifdef CONFIG_PROC_FS | 760 | #ifdef CONFIG_PROC_FS |
@@ -852,6 +853,8 @@ static inline void __sk_prot_rehash(struct sock *sk) | |||
852 | sk->sk_prot->hash(sk); | 853 | sk->sk_prot->hash(sk); |
853 | } | 854 | } |
854 | 855 | ||
856 | void sk_prot_clear_portaddr_nulls(struct sock *sk, int size); | ||
857 | |||
855 | /* About 10 seconds */ | 858 | /* About 10 seconds */ |
856 | #define SOCK_DESTROY_TIME (10*HZ) | 859 | #define SOCK_DESTROY_TIME (10*HZ) |
857 | 860 | ||
@@ -1155,6 +1158,8 @@ extern void sk_common_release(struct sock *sk); | |||
1155 | /* Initialise core socket variables */ | 1158 | /* Initialise core socket variables */ |
1156 | extern void sock_init_data(struct socket *sock, struct sock *sk); | 1159 | extern void sock_init_data(struct socket *sock, struct sock *sk); |
1157 | 1160 | ||
1161 | extern void sk_filter_release_rcu(struct rcu_head *rcu); | ||
1162 | |||
1158 | /** | 1163 | /** |
1159 | * sk_filter_release - release a socket filter | 1164 | * sk_filter_release - release a socket filter |
1160 | * @fp: filter to remove | 1165 | * @fp: filter to remove |
@@ -1165,7 +1170,7 @@ extern void sock_init_data(struct socket *sock, struct sock *sk); | |||
1165 | static inline void sk_filter_release(struct sk_filter *fp) | 1170 | static inline void sk_filter_release(struct sk_filter *fp) |
1166 | { | 1171 | { |
1167 | if (atomic_dec_and_test(&fp->refcnt)) | 1172 | if (atomic_dec_and_test(&fp->refcnt)) |
1168 | kfree(fp); | 1173 | call_rcu_bh(&fp->rcu, sk_filter_release_rcu); |
1169 | } | 1174 | } |
1170 | 1175 | ||
1171 | static inline void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp) | 1176 | static inline void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp) |
diff --git a/include/xen/interface/io/ring.h b/include/xen/interface/io/ring.h index e8cbf431c8cc..75271b9a8f61 100644 --- a/include/xen/interface/io/ring.h +++ b/include/xen/interface/io/ring.h | |||
@@ -24,8 +24,15 @@ typedef unsigned int RING_IDX; | |||
24 | * A ring contains as many entries as will fit, rounded down to the nearest | 24 | * A ring contains as many entries as will fit, rounded down to the nearest |
25 | * power of two (so we can mask with (size-1) to loop around). | 25 | * power of two (so we can mask with (size-1) to loop around). |
26 | */ | 26 | */ |
27 | #define __RING_SIZE(_s, _sz) \ | 27 | #define __CONST_RING_SIZE(_s, _sz) \ |
28 | (__RD32(((_sz) - (long)&(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0]))) | 28 | (__RD32(((_sz) - offsetof(struct _s##_sring, ring)) / \ |
29 | sizeof(((struct _s##_sring *)0)->ring[0]))) | ||
30 | |||
31 | /* | ||
32 | * The same for passing in an actual pointer instead of a name tag. | ||
33 | */ | ||
34 | #define __RING_SIZE(_s, _sz) \ | ||
35 | (__RD32(((_sz) - (long)&(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0]))) | ||
29 | 36 | ||
30 | /* | 37 | /* |
31 | * Macros to make the correct C datatypes for a new kind of ring. | 38 | * Macros to make the correct C datatypes for a new kind of ring. |
diff --git a/init/do_mounts.c b/init/do_mounts.c index 830aaec9c7d5..2b54bef33b55 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c | |||
@@ -93,7 +93,7 @@ no_match: | |||
93 | * | 93 | * |
94 | * Returns the matching dev_t on success or 0 on failure. | 94 | * Returns the matching dev_t on success or 0 on failure. |
95 | */ | 95 | */ |
96 | static dev_t __init devt_from_partuuid(char *uuid_str) | 96 | static dev_t devt_from_partuuid(char *uuid_str) |
97 | { | 97 | { |
98 | dev_t res = 0; | 98 | dev_t res = 0; |
99 | struct device *dev = NULL; | 99 | struct device *dev = NULL; |
diff --git a/kernel/fork.c b/kernel/fork.c index 3b159c5991b7..5447dc7defa9 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -273,6 +273,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) | |||
273 | 273 | ||
274 | setup_thread_stack(tsk, orig); | 274 | setup_thread_stack(tsk, orig); |
275 | clear_user_return_notifier(tsk); | 275 | clear_user_return_notifier(tsk); |
276 | clear_tsk_need_resched(tsk); | ||
276 | stackend = end_of_stack(tsk); | 277 | stackend = end_of_stack(tsk); |
277 | *stackend = STACK_END_MAGIC; /* for overflow detection */ | 278 | *stackend = STACK_END_MAGIC; /* for overflow detection */ |
278 | 279 | ||
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index 01b1d3a88983..6c8a2a9f8a7b 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c | |||
@@ -214,7 +214,7 @@ static int irq_spurious_proc_show(struct seq_file *m, void *v) | |||
214 | 214 | ||
215 | static int irq_spurious_proc_open(struct inode *inode, struct file *file) | 215 | static int irq_spurious_proc_open(struct inode *inode, struct file *file) |
216 | { | 216 | { |
217 | return single_open(file, irq_spurious_proc_show, NULL); | 217 | return single_open(file, irq_spurious_proc_show, PDE(inode)->data); |
218 | } | 218 | } |
219 | 219 | ||
220 | static const struct file_operations irq_spurious_proc_fops = { | 220 | static const struct file_operations irq_spurious_proc_fops = { |
diff --git a/kernel/kthread.c b/kernel/kthread.c index 2dc3786349d1..ca61bbdd44b2 100644 --- a/kernel/kthread.c +++ b/kernel/kthread.c | |||
@@ -265,6 +265,17 @@ int kthreadd(void *unused) | |||
265 | return 0; | 265 | return 0; |
266 | } | 266 | } |
267 | 267 | ||
268 | void __init_kthread_worker(struct kthread_worker *worker, | ||
269 | const char *name, | ||
270 | struct lock_class_key *key) | ||
271 | { | ||
272 | spin_lock_init(&worker->lock); | ||
273 | lockdep_set_class_and_name(&worker->lock, key, name); | ||
274 | INIT_LIST_HEAD(&worker->work_list); | ||
275 | worker->task = NULL; | ||
276 | } | ||
277 | EXPORT_SYMBOL_GPL(__init_kthread_worker); | ||
278 | |||
268 | /** | 279 | /** |
269 | * kthread_worker_fn - kthread function to process kthread_worker | 280 | * kthread_worker_fn - kthread function to process kthread_worker |
270 | * @worker_ptr: pointer to initialized kthread_worker | 281 | * @worker_ptr: pointer to initialized kthread_worker |
diff --git a/kernel/perf_event.c b/kernel/perf_event.c index eac7e3364335..2870feee81dd 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c | |||
@@ -3824,6 +3824,8 @@ static void perf_event_task_event(struct perf_task_event *task_event) | |||
3824 | rcu_read_lock(); | 3824 | rcu_read_lock(); |
3825 | list_for_each_entry_rcu(pmu, &pmus, entry) { | 3825 | list_for_each_entry_rcu(pmu, &pmus, entry) { |
3826 | cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); | 3826 | cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); |
3827 | if (cpuctx->active_pmu != pmu) | ||
3828 | goto next; | ||
3827 | perf_event_task_ctx(&cpuctx->ctx, task_event); | 3829 | perf_event_task_ctx(&cpuctx->ctx, task_event); |
3828 | 3830 | ||
3829 | ctx = task_event->task_ctx; | 3831 | ctx = task_event->task_ctx; |
@@ -3959,6 +3961,8 @@ static void perf_event_comm_event(struct perf_comm_event *comm_event) | |||
3959 | rcu_read_lock(); | 3961 | rcu_read_lock(); |
3960 | list_for_each_entry_rcu(pmu, &pmus, entry) { | 3962 | list_for_each_entry_rcu(pmu, &pmus, entry) { |
3961 | cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); | 3963 | cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); |
3964 | if (cpuctx->active_pmu != pmu) | ||
3965 | goto next; | ||
3962 | perf_event_comm_ctx(&cpuctx->ctx, comm_event); | 3966 | perf_event_comm_ctx(&cpuctx->ctx, comm_event); |
3963 | 3967 | ||
3964 | ctxn = pmu->task_ctx_nr; | 3968 | ctxn = pmu->task_ctx_nr; |
@@ -4144,6 +4148,8 @@ got_name: | |||
4144 | rcu_read_lock(); | 4148 | rcu_read_lock(); |
4145 | list_for_each_entry_rcu(pmu, &pmus, entry) { | 4149 | list_for_each_entry_rcu(pmu, &pmus, entry) { |
4146 | cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); | 4150 | cpuctx = get_cpu_ptr(pmu->pmu_cpu_context); |
4151 | if (cpuctx->active_pmu != pmu) | ||
4152 | goto next; | ||
4147 | perf_event_mmap_ctx(&cpuctx->ctx, mmap_event, | 4153 | perf_event_mmap_ctx(&cpuctx->ctx, mmap_event, |
4148 | vma->vm_flags & VM_EXEC); | 4154 | vma->vm_flags & VM_EXEC); |
4149 | 4155 | ||
@@ -4713,7 +4719,7 @@ static int perf_swevent_init(struct perf_event *event) | |||
4713 | break; | 4719 | break; |
4714 | } | 4720 | } |
4715 | 4721 | ||
4716 | if (event_id > PERF_COUNT_SW_MAX) | 4722 | if (event_id >= PERF_COUNT_SW_MAX) |
4717 | return -ENOENT; | 4723 | return -ENOENT; |
4718 | 4724 | ||
4719 | if (!event->parent) { | 4725 | if (!event->parent) { |
@@ -5145,20 +5151,36 @@ static void *find_pmu_context(int ctxn) | |||
5145 | return NULL; | 5151 | return NULL; |
5146 | } | 5152 | } |
5147 | 5153 | ||
5148 | static void free_pmu_context(void * __percpu cpu_context) | 5154 | static void update_pmu_context(struct pmu *pmu, struct pmu *old_pmu) |
5149 | { | 5155 | { |
5150 | struct pmu *pmu; | 5156 | int cpu; |
5157 | |||
5158 | for_each_possible_cpu(cpu) { | ||
5159 | struct perf_cpu_context *cpuctx; | ||
5160 | |||
5161 | cpuctx = per_cpu_ptr(pmu->pmu_cpu_context, cpu); | ||
5162 | |||
5163 | if (cpuctx->active_pmu == old_pmu) | ||
5164 | cpuctx->active_pmu = pmu; | ||
5165 | } | ||
5166 | } | ||
5167 | |||
5168 | static void free_pmu_context(struct pmu *pmu) | ||
5169 | { | ||
5170 | struct pmu *i; | ||
5151 | 5171 | ||
5152 | mutex_lock(&pmus_lock); | 5172 | mutex_lock(&pmus_lock); |
5153 | /* | 5173 | /* |
5154 | * Like a real lame refcount. | 5174 | * Like a real lame refcount. |
5155 | */ | 5175 | */ |
5156 | list_for_each_entry(pmu, &pmus, entry) { | 5176 | list_for_each_entry(i, &pmus, entry) { |
5157 | if (pmu->pmu_cpu_context == cpu_context) | 5177 | if (i->pmu_cpu_context == pmu->pmu_cpu_context) { |
5178 | update_pmu_context(i, pmu); | ||
5158 | goto out; | 5179 | goto out; |
5180 | } | ||
5159 | } | 5181 | } |
5160 | 5182 | ||
5161 | free_percpu(cpu_context); | 5183 | free_percpu(pmu->pmu_cpu_context); |
5162 | out: | 5184 | out: |
5163 | mutex_unlock(&pmus_lock); | 5185 | mutex_unlock(&pmus_lock); |
5164 | } | 5186 | } |
@@ -5190,6 +5212,7 @@ int perf_pmu_register(struct pmu *pmu) | |||
5190 | cpuctx->ctx.pmu = pmu; | 5212 | cpuctx->ctx.pmu = pmu; |
5191 | cpuctx->jiffies_interval = 1; | 5213 | cpuctx->jiffies_interval = 1; |
5192 | INIT_LIST_HEAD(&cpuctx->rotation_list); | 5214 | INIT_LIST_HEAD(&cpuctx->rotation_list); |
5215 | cpuctx->active_pmu = pmu; | ||
5193 | } | 5216 | } |
5194 | 5217 | ||
5195 | got_cpu_context: | 5218 | got_cpu_context: |
@@ -5241,7 +5264,7 @@ void perf_pmu_unregister(struct pmu *pmu) | |||
5241 | synchronize_rcu(); | 5264 | synchronize_rcu(); |
5242 | 5265 | ||
5243 | free_percpu(pmu->pmu_disable_count); | 5266 | free_percpu(pmu->pmu_disable_count); |
5244 | free_pmu_context(pmu->pmu_cpu_context); | 5267 | free_pmu_context(pmu); |
5245 | } | 5268 | } |
5246 | 5269 | ||
5247 | struct pmu *perf_init_event(struct perf_event *event) | 5270 | struct pmu *perf_init_event(struct perf_event *event) |
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index a5aff3ebad38..265729966ece 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig | |||
@@ -100,13 +100,9 @@ config PM_SLEEP_ADVANCED_DEBUG | |||
100 | depends on PM_ADVANCED_DEBUG | 100 | depends on PM_ADVANCED_DEBUG |
101 | default n | 101 | default n |
102 | 102 | ||
103 | config SUSPEND_NVS | ||
104 | bool | ||
105 | |||
106 | config SUSPEND | 103 | config SUSPEND |
107 | bool "Suspend to RAM and standby" | 104 | bool "Suspend to RAM and standby" |
108 | depends on PM && ARCH_SUSPEND_POSSIBLE | 105 | depends on PM && ARCH_SUSPEND_POSSIBLE |
109 | select SUSPEND_NVS if HAS_IOMEM | ||
110 | default y | 106 | default y |
111 | ---help--- | 107 | ---help--- |
112 | Allow the system to enter sleep states in which main memory is | 108 | Allow the system to enter sleep states in which main memory is |
@@ -140,7 +136,6 @@ config HIBERNATION | |||
140 | depends on PM && SWAP && ARCH_HIBERNATION_POSSIBLE | 136 | depends on PM && SWAP && ARCH_HIBERNATION_POSSIBLE |
141 | select LZO_COMPRESS | 137 | select LZO_COMPRESS |
142 | select LZO_DECOMPRESS | 138 | select LZO_DECOMPRESS |
143 | select SUSPEND_NVS if HAS_IOMEM | ||
144 | ---help--- | 139 | ---help--- |
145 | Enable the suspend to disk (STD) functionality, which is usually | 140 | Enable the suspend to disk (STD) functionality, which is usually |
146 | called "hibernation" in user interfaces. STD checkpoints the | 141 | called "hibernation" in user interfaces. STD checkpoints the |
diff --git a/kernel/power/Makefile b/kernel/power/Makefile index f9063c6b185d..120a15823325 100644 --- a/kernel/power/Makefile +++ b/kernel/power/Makefile | |||
@@ -10,6 +10,5 @@ obj-$(CONFIG_SUSPEND) += suspend.o | |||
10 | obj-$(CONFIG_PM_TEST_SUSPEND) += suspend_test.o | 10 | obj-$(CONFIG_PM_TEST_SUSPEND) += suspend_test.o |
11 | obj-$(CONFIG_HIBERNATION) += hibernate.o snapshot.o swap.o user.o \ | 11 | obj-$(CONFIG_HIBERNATION) += hibernate.o snapshot.o swap.o user.o \ |
12 | block_io.o | 12 | block_io.o |
13 | obj-$(CONFIG_SUSPEND_NVS) += nvs.o | ||
14 | 13 | ||
15 | obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o | 14 | obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o |
diff --git a/kernel/power/swap.c b/kernel/power/swap.c index baf667bb2794..8c7e4832b9be 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c | |||
@@ -30,7 +30,7 @@ | |||
30 | 30 | ||
31 | #include "power.h" | 31 | #include "power.h" |
32 | 32 | ||
33 | #define HIBERNATE_SIG "LINHIB0001" | 33 | #define HIBERNATE_SIG "S1SUSPEND" |
34 | 34 | ||
35 | /* | 35 | /* |
36 | * The swap map is a data structure used for keeping track of each page | 36 | * The swap map is a data structure used for keeping track of each page |
diff --git a/kernel/power/user.c b/kernel/power/user.c index 1b2ea31e6bd8..c36c3b9e8a84 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c | |||
@@ -137,7 +137,7 @@ static int snapshot_release(struct inode *inode, struct file *filp) | |||
137 | free_all_swap_pages(data->swap); | 137 | free_all_swap_pages(data->swap); |
138 | if (data->frozen) | 138 | if (data->frozen) |
139 | thaw_processes(); | 139 | thaw_processes(); |
140 | pm_notifier_call_chain(data->mode == O_WRONLY ? | 140 | pm_notifier_call_chain(data->mode == O_RDONLY ? |
141 | PM_POST_HIBERNATION : PM_POST_RESTORE); | 141 | PM_POST_HIBERNATION : PM_POST_RESTORE); |
142 | atomic_inc(&snapshot_device_available); | 142 | atomic_inc(&snapshot_device_available); |
143 | 143 | ||
diff --git a/kernel/printk.c b/kernel/printk.c index 9a2264fc42ca..a23315dc4498 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -1082,13 +1082,15 @@ void printk_tick(void) | |||
1082 | 1082 | ||
1083 | int printk_needs_cpu(int cpu) | 1083 | int printk_needs_cpu(int cpu) |
1084 | { | 1084 | { |
1085 | if (unlikely(cpu_is_offline(cpu))) | ||
1086 | printk_tick(); | ||
1085 | return per_cpu(printk_pending, cpu); | 1087 | return per_cpu(printk_pending, cpu); |
1086 | } | 1088 | } |
1087 | 1089 | ||
1088 | void wake_up_klogd(void) | 1090 | void wake_up_klogd(void) |
1089 | { | 1091 | { |
1090 | if (waitqueue_active(&log_wait)) | 1092 | if (waitqueue_active(&log_wait)) |
1091 | __raw_get_cpu_var(printk_pending) = 1; | 1093 | this_cpu_write(printk_pending, 1); |
1092 | } | 1094 | } |
1093 | 1095 | ||
1094 | /** | 1096 | /** |
diff --git a/kernel/resource.c b/kernel/resource.c index 9fad33efd0db..798e2fae2a06 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
@@ -40,23 +40,6 @@ EXPORT_SYMBOL(iomem_resource); | |||
40 | 40 | ||
41 | static DEFINE_RWLOCK(resource_lock); | 41 | static DEFINE_RWLOCK(resource_lock); |
42 | 42 | ||
43 | /* | ||
44 | * By default, we allocate free space bottom-up. The architecture can request | ||
45 | * top-down by clearing this flag. The user can override the architecture's | ||
46 | * choice with the "resource_alloc_from_bottom" kernel boot option, but that | ||
47 | * should only be a debugging tool. | ||
48 | */ | ||
49 | int resource_alloc_from_bottom = 1; | ||
50 | |||
51 | static __init int setup_alloc_from_bottom(char *s) | ||
52 | { | ||
53 | printk(KERN_INFO | ||
54 | "resource: allocating from bottom-up; please report a bug\n"); | ||
55 | resource_alloc_from_bottom = 1; | ||
56 | return 0; | ||
57 | } | ||
58 | early_param("resource_alloc_from_bottom", setup_alloc_from_bottom); | ||
59 | |||
60 | static void *r_next(struct seq_file *m, void *v, loff_t *pos) | 43 | static void *r_next(struct seq_file *m, void *v, loff_t *pos) |
61 | { | 44 | { |
62 | struct resource *p = v; | 45 | struct resource *p = v; |
@@ -374,6 +357,10 @@ int __weak page_is_ram(unsigned long pfn) | |||
374 | return walk_system_ram_range(pfn, 1, NULL, __is_ram) == 1; | 357 | return walk_system_ram_range(pfn, 1, NULL, __is_ram) == 1; |
375 | } | 358 | } |
376 | 359 | ||
360 | void __weak arch_remove_reservations(struct resource *avail) | ||
361 | { | ||
362 | } | ||
363 | |||
377 | static resource_size_t simple_align_resource(void *data, | 364 | static resource_size_t simple_align_resource(void *data, |
378 | const struct resource *avail, | 365 | const struct resource *avail, |
379 | resource_size_t size, | 366 | resource_size_t size, |
@@ -397,74 +384,7 @@ static bool resource_contains(struct resource *res1, struct resource *res2) | |||
397 | } | 384 | } |
398 | 385 | ||
399 | /* | 386 | /* |
400 | * Find the resource before "child" in the sibling list of "root" children. | ||
401 | */ | ||
402 | static struct resource *find_sibling_prev(struct resource *root, struct resource *child) | ||
403 | { | ||
404 | struct resource *this; | ||
405 | |||
406 | for (this = root->child; this; this = this->sibling) | ||
407 | if (this->sibling == child) | ||
408 | return this; | ||
409 | |||
410 | return NULL; | ||
411 | } | ||
412 | |||
413 | /* | ||
414 | * Find empty slot in the resource tree given range and alignment. | 387 | * Find empty slot in the resource tree given range and alignment. |
415 | * This version allocates from the end of the root resource first. | ||
416 | */ | ||
417 | static int find_resource_from_top(struct resource *root, struct resource *new, | ||
418 | resource_size_t size, resource_size_t min, | ||
419 | resource_size_t max, resource_size_t align, | ||
420 | resource_size_t (*alignf)(void *, | ||
421 | const struct resource *, | ||
422 | resource_size_t, | ||
423 | resource_size_t), | ||
424 | void *alignf_data) | ||
425 | { | ||
426 | struct resource *this; | ||
427 | struct resource tmp, avail, alloc; | ||
428 | |||
429 | tmp.start = root->end; | ||
430 | tmp.end = root->end; | ||
431 | |||
432 | this = find_sibling_prev(root, NULL); | ||
433 | for (;;) { | ||
434 | if (this) { | ||
435 | if (this->end < root->end) | ||
436 | tmp.start = this->end + 1; | ||
437 | } else | ||
438 | tmp.start = root->start; | ||
439 | |||
440 | resource_clip(&tmp, min, max); | ||
441 | |||
442 | /* Check for overflow after ALIGN() */ | ||
443 | avail = *new; | ||
444 | avail.start = ALIGN(tmp.start, align); | ||
445 | avail.end = tmp.end; | ||
446 | if (avail.start >= tmp.start) { | ||
447 | alloc.start = alignf(alignf_data, &avail, size, align); | ||
448 | alloc.end = alloc.start + size - 1; | ||
449 | if (resource_contains(&avail, &alloc)) { | ||
450 | new->start = alloc.start; | ||
451 | new->end = alloc.end; | ||
452 | return 0; | ||
453 | } | ||
454 | } | ||
455 | |||
456 | if (!this || this->start == root->start) | ||
457 | break; | ||
458 | |||
459 | tmp.end = this->start - 1; | ||
460 | this = find_sibling_prev(root, this); | ||
461 | } | ||
462 | return -EBUSY; | ||
463 | } | ||
464 | |||
465 | /* | ||
466 | * Find empty slot in the resource tree given range and alignment. | ||
467 | * This version allocates from the beginning of the root resource first. | ||
468 | */ | 388 | */ |
469 | static int find_resource(struct resource *root, struct resource *new, | 389 | static int find_resource(struct resource *root, struct resource *new, |
470 | resource_size_t size, resource_size_t min, | 390 | resource_size_t size, resource_size_t min, |
@@ -478,23 +398,24 @@ static int find_resource(struct resource *root, struct resource *new, | |||
478 | struct resource *this = root->child; | 398 | struct resource *this = root->child; |
479 | struct resource tmp = *new, avail, alloc; | 399 | struct resource tmp = *new, avail, alloc; |
480 | 400 | ||
401 | tmp.flags = new->flags; | ||
481 | tmp.start = root->start; | 402 | tmp.start = root->start; |
482 | /* | 403 | /* |
483 | * Skip past an allocated resource that starts at 0, since the | 404 | * Skip past an allocated resource that starts at 0, since the assignment |
484 | * assignment of this->start - 1 to tmp->end below would cause an | 405 | * of this->start - 1 to tmp->end below would cause an underflow. |
485 | * underflow. | ||
486 | */ | 406 | */ |
487 | if (this && this->start == 0) { | 407 | if (this && this->start == 0) { |
488 | tmp.start = this->end + 1; | 408 | tmp.start = this->end + 1; |
489 | this = this->sibling; | 409 | this = this->sibling; |
490 | } | 410 | } |
491 | for (;;) { | 411 | for(;;) { |
492 | if (this) | 412 | if (this) |
493 | tmp.end = this->start - 1; | 413 | tmp.end = this->start - 1; |
494 | else | 414 | else |
495 | tmp.end = root->end; | 415 | tmp.end = root->end; |
496 | 416 | ||
497 | resource_clip(&tmp, min, max); | 417 | resource_clip(&tmp, min, max); |
418 | arch_remove_reservations(&tmp); | ||
498 | 419 | ||
499 | /* Check for overflow after ALIGN() */ | 420 | /* Check for overflow after ALIGN() */ |
500 | avail = *new; | 421 | avail = *new; |
@@ -509,10 +430,8 @@ static int find_resource(struct resource *root, struct resource *new, | |||
509 | return 0; | 430 | return 0; |
510 | } | 431 | } |
511 | } | 432 | } |
512 | |||
513 | if (!this) | 433 | if (!this) |
514 | break; | 434 | break; |
515 | |||
516 | tmp.start = this->end + 1; | 435 | tmp.start = this->end + 1; |
517 | this = this->sibling; | 436 | this = this->sibling; |
518 | } | 437 | } |
@@ -545,10 +464,7 @@ int allocate_resource(struct resource *root, struct resource *new, | |||
545 | alignf = simple_align_resource; | 464 | alignf = simple_align_resource; |
546 | 465 | ||
547 | write_lock(&resource_lock); | 466 | write_lock(&resource_lock); |
548 | if (resource_alloc_from_bottom) | 467 | err = find_resource(root, new, size, min, max, align, alignf, alignf_data); |
549 | err = find_resource(root, new, size, min, max, align, alignf, alignf_data); | ||
550 | else | ||
551 | err = find_resource_from_top(root, new, size, min, max, align, alignf, alignf_data); | ||
552 | if (err >= 0 && __request_resource(root, new)) | 468 | if (err >= 0 && __request_resource(root, new)) |
553 | err = -EBUSY; | 469 | err = -EBUSY; |
554 | write_unlock(&resource_lock); | 470 | write_unlock(&resource_lock); |
diff --git a/kernel/sched.c b/kernel/sched.c index dc91a4d09ac3..297d1a0eedb0 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -636,22 +636,18 @@ static inline struct task_group *task_group(struct task_struct *p) | |||
636 | 636 | ||
637 | #endif /* CONFIG_CGROUP_SCHED */ | 637 | #endif /* CONFIG_CGROUP_SCHED */ |
638 | 638 | ||
639 | static u64 irq_time_cpu(int cpu); | 639 | static void update_rq_clock_task(struct rq *rq, s64 delta); |
640 | static void sched_irq_time_avg_update(struct rq *rq, u64 irq_time); | ||
641 | 640 | ||
642 | inline void update_rq_clock(struct rq *rq) | 641 | static void update_rq_clock(struct rq *rq) |
643 | { | 642 | { |
644 | if (!rq->skip_clock_update) { | 643 | s64 delta; |
645 | int cpu = cpu_of(rq); | ||
646 | u64 irq_time; | ||
647 | 644 | ||
648 | rq->clock = sched_clock_cpu(cpu); | 645 | if (rq->skip_clock_update) |
649 | irq_time = irq_time_cpu(cpu); | 646 | return; |
650 | if (rq->clock - irq_time > rq->clock_task) | ||
651 | rq->clock_task = rq->clock - irq_time; | ||
652 | 647 | ||
653 | sched_irq_time_avg_update(rq, irq_time); | 648 | delta = sched_clock_cpu(cpu_of(rq)) - rq->clock; |
654 | } | 649 | rq->clock += delta; |
650 | update_rq_clock_task(rq, delta); | ||
655 | } | 651 | } |
656 | 652 | ||
657 | /* | 653 | /* |
@@ -1924,10 +1920,9 @@ static void deactivate_task(struct rq *rq, struct task_struct *p, int flags) | |||
1924 | * They are read and saved off onto struct rq in update_rq_clock(). | 1920 | * They are read and saved off onto struct rq in update_rq_clock(). |
1925 | * This may result in other CPU reading this CPU's irq time and can | 1921 | * This may result in other CPU reading this CPU's irq time and can |
1926 | * race with irq/account_system_vtime on this CPU. We would either get old | 1922 | * race with irq/account_system_vtime on this CPU. We would either get old |
1927 | * or new value (or semi updated value on 32 bit) with a side effect of | 1923 | * or new value with a side effect of accounting a slice of irq time to wrong |
1928 | * accounting a slice of irq time to wrong task when irq is in progress | 1924 | * task when irq is in progress while we read rq->clock. That is a worthy |
1929 | * while we read rq->clock. That is a worthy compromise in place of having | 1925 | * compromise in place of having locks on each irq in account_system_time. |
1930 | * locks on each irq in account_system_time. | ||
1931 | */ | 1926 | */ |
1932 | static DEFINE_PER_CPU(u64, cpu_hardirq_time); | 1927 | static DEFINE_PER_CPU(u64, cpu_hardirq_time); |
1933 | static DEFINE_PER_CPU(u64, cpu_softirq_time); | 1928 | static DEFINE_PER_CPU(u64, cpu_softirq_time); |
@@ -1945,19 +1940,58 @@ void disable_sched_clock_irqtime(void) | |||
1945 | sched_clock_irqtime = 0; | 1940 | sched_clock_irqtime = 0; |
1946 | } | 1941 | } |
1947 | 1942 | ||
1948 | static u64 irq_time_cpu(int cpu) | 1943 | #ifndef CONFIG_64BIT |
1944 | static DEFINE_PER_CPU(seqcount_t, irq_time_seq); | ||
1945 | |||
1946 | static inline void irq_time_write_begin(void) | ||
1949 | { | 1947 | { |
1950 | if (!sched_clock_irqtime) | 1948 | __this_cpu_inc(irq_time_seq.sequence); |
1951 | return 0; | 1949 | smp_wmb(); |
1950 | } | ||
1951 | |||
1952 | static inline void irq_time_write_end(void) | ||
1953 | { | ||
1954 | smp_wmb(); | ||
1955 | __this_cpu_inc(irq_time_seq.sequence); | ||
1956 | } | ||
1957 | |||
1958 | static inline u64 irq_time_read(int cpu) | ||
1959 | { | ||
1960 | u64 irq_time; | ||
1961 | unsigned seq; | ||
1952 | 1962 | ||
1963 | do { | ||
1964 | seq = read_seqcount_begin(&per_cpu(irq_time_seq, cpu)); | ||
1965 | irq_time = per_cpu(cpu_softirq_time, cpu) + | ||
1966 | per_cpu(cpu_hardirq_time, cpu); | ||
1967 | } while (read_seqcount_retry(&per_cpu(irq_time_seq, cpu), seq)); | ||
1968 | |||
1969 | return irq_time; | ||
1970 | } | ||
1971 | #else /* CONFIG_64BIT */ | ||
1972 | static inline void irq_time_write_begin(void) | ||
1973 | { | ||
1974 | } | ||
1975 | |||
1976 | static inline void irq_time_write_end(void) | ||
1977 | { | ||
1978 | } | ||
1979 | |||
1980 | static inline u64 irq_time_read(int cpu) | ||
1981 | { | ||
1953 | return per_cpu(cpu_softirq_time, cpu) + per_cpu(cpu_hardirq_time, cpu); | 1982 | return per_cpu(cpu_softirq_time, cpu) + per_cpu(cpu_hardirq_time, cpu); |
1954 | } | 1983 | } |
1984 | #endif /* CONFIG_64BIT */ | ||
1955 | 1985 | ||
1986 | /* | ||
1987 | * Called before incrementing preempt_count on {soft,}irq_enter | ||
1988 | * and before decrementing preempt_count on {soft,}irq_exit. | ||
1989 | */ | ||
1956 | void account_system_vtime(struct task_struct *curr) | 1990 | void account_system_vtime(struct task_struct *curr) |
1957 | { | 1991 | { |
1958 | unsigned long flags; | 1992 | unsigned long flags; |
1993 | s64 delta; | ||
1959 | int cpu; | 1994 | int cpu; |
1960 | u64 now, delta; | ||
1961 | 1995 | ||
1962 | if (!sched_clock_irqtime) | 1996 | if (!sched_clock_irqtime) |
1963 | return; | 1997 | return; |
@@ -1965,9 +1999,10 @@ void account_system_vtime(struct task_struct *curr) | |||
1965 | local_irq_save(flags); | 1999 | local_irq_save(flags); |
1966 | 2000 | ||
1967 | cpu = smp_processor_id(); | 2001 | cpu = smp_processor_id(); |
1968 | now = sched_clock_cpu(cpu); | 2002 | delta = sched_clock_cpu(cpu) - __this_cpu_read(irq_start_time); |
1969 | delta = now - per_cpu(irq_start_time, cpu); | 2003 | __this_cpu_add(irq_start_time, delta); |
1970 | per_cpu(irq_start_time, cpu) = now; | 2004 | |
2005 | irq_time_write_begin(); | ||
1971 | /* | 2006 | /* |
1972 | * We do not account for softirq time from ksoftirqd here. | 2007 | * We do not account for softirq time from ksoftirqd here. |
1973 | * We want to continue accounting softirq time to ksoftirqd thread | 2008 | * We want to continue accounting softirq time to ksoftirqd thread |
@@ -1975,33 +2010,55 @@ void account_system_vtime(struct task_struct *curr) | |||
1975 | * that do not consume any time, but still wants to run. | 2010 | * that do not consume any time, but still wants to run. |
1976 | */ | 2011 | */ |
1977 | if (hardirq_count()) | 2012 | if (hardirq_count()) |
1978 | per_cpu(cpu_hardirq_time, cpu) += delta; | 2013 | __this_cpu_add(cpu_hardirq_time, delta); |
1979 | else if (in_serving_softirq() && !(curr->flags & PF_KSOFTIRQD)) | 2014 | else if (in_serving_softirq() && !(curr->flags & PF_KSOFTIRQD)) |
1980 | per_cpu(cpu_softirq_time, cpu) += delta; | 2015 | __this_cpu_add(cpu_softirq_time, delta); |
1981 | 2016 | ||
2017 | irq_time_write_end(); | ||
1982 | local_irq_restore(flags); | 2018 | local_irq_restore(flags); |
1983 | } | 2019 | } |
1984 | EXPORT_SYMBOL_GPL(account_system_vtime); | 2020 | EXPORT_SYMBOL_GPL(account_system_vtime); |
1985 | 2021 | ||
1986 | static void sched_irq_time_avg_update(struct rq *rq, u64 curr_irq_time) | 2022 | static void update_rq_clock_task(struct rq *rq, s64 delta) |
1987 | { | 2023 | { |
1988 | if (sched_clock_irqtime && sched_feat(NONIRQ_POWER)) { | 2024 | s64 irq_delta; |
1989 | u64 delta_irq = curr_irq_time - rq->prev_irq_time; | 2025 | |
1990 | rq->prev_irq_time = curr_irq_time; | 2026 | irq_delta = irq_time_read(cpu_of(rq)) - rq->prev_irq_time; |
1991 | sched_rt_avg_update(rq, delta_irq); | 2027 | |
1992 | } | 2028 | /* |
2029 | * Since irq_time is only updated on {soft,}irq_exit, we might run into | ||
2030 | * this case when a previous update_rq_clock() happened inside a | ||
2031 | * {soft,}irq region. | ||
2032 | * | ||
2033 | * When this happens, we stop ->clock_task and only update the | ||
2034 | * prev_irq_time stamp to account for the part that fit, so that a next | ||
2035 | * update will consume the rest. This ensures ->clock_task is | ||
2036 | * monotonic. | ||
2037 | * | ||
2038 | * It does however cause some slight miss-attribution of {soft,}irq | ||
2039 | * time, a more accurate solution would be to update the irq_time using | ||
2040 | * the current rq->clock timestamp, except that would require using | ||
2041 | * atomic ops. | ||
2042 | */ | ||
2043 | if (irq_delta > delta) | ||
2044 | irq_delta = delta; | ||
2045 | |||
2046 | rq->prev_irq_time += irq_delta; | ||
2047 | delta -= irq_delta; | ||
2048 | rq->clock_task += delta; | ||
2049 | |||
2050 | if (irq_delta && sched_feat(NONIRQ_POWER)) | ||
2051 | sched_rt_avg_update(rq, irq_delta); | ||
1993 | } | 2052 | } |
1994 | 2053 | ||
1995 | #else | 2054 | #else /* CONFIG_IRQ_TIME_ACCOUNTING */ |
1996 | 2055 | ||
1997 | static u64 irq_time_cpu(int cpu) | 2056 | static void update_rq_clock_task(struct rq *rq, s64 delta) |
1998 | { | 2057 | { |
1999 | return 0; | 2058 | rq->clock_task += delta; |
2000 | } | 2059 | } |
2001 | 2060 | ||
2002 | static void sched_irq_time_avg_update(struct rq *rq, u64 curr_irq_time) { } | 2061 | #endif /* CONFIG_IRQ_TIME_ACCOUNTING */ |
2003 | |||
2004 | #endif | ||
2005 | 2062 | ||
2006 | #include "sched_idletask.c" | 2063 | #include "sched_idletask.c" |
2007 | #include "sched_fair.c" | 2064 | #include "sched_fair.c" |
@@ -2129,7 +2186,7 @@ static void check_preempt_curr(struct rq *rq, struct task_struct *p, int flags) | |||
2129 | * A queue event has occurred, and we're going to schedule. In | 2186 | * A queue event has occurred, and we're going to schedule. In |
2130 | * this case, we can save a useless back to back clock update. | 2187 | * this case, we can save a useless back to back clock update. |
2131 | */ | 2188 | */ |
2132 | if (test_tsk_need_resched(rq->curr)) | 2189 | if (rq->curr->se.on_rq && test_tsk_need_resched(rq->curr)) |
2133 | rq->skip_clock_update = 1; | 2190 | rq->skip_clock_update = 1; |
2134 | } | 2191 | } |
2135 | 2192 | ||
@@ -3119,6 +3176,15 @@ static long calc_load_fold_active(struct rq *this_rq) | |||
3119 | return delta; | 3176 | return delta; |
3120 | } | 3177 | } |
3121 | 3178 | ||
3179 | static unsigned long | ||
3180 | calc_load(unsigned long load, unsigned long exp, unsigned long active) | ||
3181 | { | ||
3182 | load *= exp; | ||
3183 | load += active * (FIXED_1 - exp); | ||
3184 | load += 1UL << (FSHIFT - 1); | ||
3185 | return load >> FSHIFT; | ||
3186 | } | ||
3187 | |||
3122 | #ifdef CONFIG_NO_HZ | 3188 | #ifdef CONFIG_NO_HZ |
3123 | /* | 3189 | /* |
3124 | * For NO_HZ we delay the active fold to the next LOAD_FREQ update. | 3190 | * For NO_HZ we delay the active fold to the next LOAD_FREQ update. |
@@ -3148,6 +3214,128 @@ static long calc_load_fold_idle(void) | |||
3148 | 3214 | ||
3149 | return delta; | 3215 | return delta; |
3150 | } | 3216 | } |
3217 | |||
3218 | /** | ||
3219 | * fixed_power_int - compute: x^n, in O(log n) time | ||
3220 | * | ||
3221 | * @x: base of the power | ||
3222 | * @frac_bits: fractional bits of @x | ||
3223 | * @n: power to raise @x to. | ||
3224 | * | ||
3225 | * By exploiting the relation between the definition of the natural power | ||
3226 | * function: x^n := x*x*...*x (x multiplied by itself for n times), and | ||
3227 | * the binary encoding of numbers used by computers: n := \Sum n_i * 2^i, | ||
3228 | * (where: n_i \elem {0, 1}, the binary vector representing n), | ||
3229 | * we find: x^n := x^(\Sum n_i * 2^i) := \Prod x^(n_i * 2^i), which is | ||
3230 | * of course trivially computable in O(log_2 n), the length of our binary | ||
3231 | * vector. | ||
3232 | */ | ||
3233 | static unsigned long | ||
3234 | fixed_power_int(unsigned long x, unsigned int frac_bits, unsigned int n) | ||
3235 | { | ||
3236 | unsigned long result = 1UL << frac_bits; | ||
3237 | |||
3238 | if (n) for (;;) { | ||
3239 | if (n & 1) { | ||
3240 | result *= x; | ||
3241 | result += 1UL << (frac_bits - 1); | ||
3242 | result >>= frac_bits; | ||
3243 | } | ||
3244 | n >>= 1; | ||
3245 | if (!n) | ||
3246 | break; | ||
3247 | x *= x; | ||
3248 | x += 1UL << (frac_bits - 1); | ||
3249 | x >>= frac_bits; | ||
3250 | } | ||
3251 | |||
3252 | return result; | ||
3253 | } | ||
3254 | |||
3255 | /* | ||
3256 | * a1 = a0 * e + a * (1 - e) | ||
3257 | * | ||
3258 | * a2 = a1 * e + a * (1 - e) | ||
3259 | * = (a0 * e + a * (1 - e)) * e + a * (1 - e) | ||
3260 | * = a0 * e^2 + a * (1 - e) * (1 + e) | ||
3261 | * | ||
3262 | * a3 = a2 * e + a * (1 - e) | ||
3263 | * = (a0 * e^2 + a * (1 - e) * (1 + e)) * e + a * (1 - e) | ||
3264 | * = a0 * e^3 + a * (1 - e) * (1 + e + e^2) | ||
3265 | * | ||
3266 | * ... | ||
3267 | * | ||
3268 | * an = a0 * e^n + a * (1 - e) * (1 + e + ... + e^n-1) [1] | ||
3269 | * = a0 * e^n + a * (1 - e) * (1 - e^n)/(1 - e) | ||
3270 | * = a0 * e^n + a * (1 - e^n) | ||
3271 | * | ||
3272 | * [1] application of the geometric series: | ||
3273 | * | ||
3274 | * n 1 - x^(n+1) | ||
3275 | * S_n := \Sum x^i = ------------- | ||
3276 | * i=0 1 - x | ||
3277 | */ | ||
3278 | static unsigned long | ||
3279 | calc_load_n(unsigned long load, unsigned long exp, | ||
3280 | unsigned long active, unsigned int n) | ||
3281 | { | ||
3282 | |||
3283 | return calc_load(load, fixed_power_int(exp, FSHIFT, n), active); | ||
3284 | } | ||
3285 | |||
3286 | /* | ||
3287 | * NO_HZ can leave us missing all per-cpu ticks calling | ||
3288 | * calc_load_account_active(), but since an idle CPU folds its delta into | ||
3289 | * calc_load_tasks_idle per calc_load_account_idle(), all we need to do is fold | ||
3290 | * in the pending idle delta if our idle period crossed a load cycle boundary. | ||
3291 | * | ||
3292 | * Once we've updated the global active value, we need to apply the exponential | ||
3293 | * weights adjusted to the number of cycles missed. | ||
3294 | */ | ||
3295 | static void calc_global_nohz(unsigned long ticks) | ||
3296 | { | ||
3297 | long delta, active, n; | ||
3298 | |||
3299 | if (time_before(jiffies, calc_load_update)) | ||
3300 | return; | ||
3301 | |||
3302 | /* | ||
3303 | * If we crossed a calc_load_update boundary, make sure to fold | ||
3304 | * any pending idle changes, the respective CPUs might have | ||
3305 | * missed the tick driven calc_load_account_active() update | ||
3306 | * due to NO_HZ. | ||
3307 | */ | ||
3308 | delta = calc_load_fold_idle(); | ||
3309 | if (delta) | ||
3310 | atomic_long_add(delta, &calc_load_tasks); | ||
3311 | |||
3312 | /* | ||
3313 | * If we were idle for multiple load cycles, apply them. | ||
3314 | */ | ||
3315 | if (ticks >= LOAD_FREQ) { | ||
3316 | n = ticks / LOAD_FREQ; | ||
3317 | |||
3318 | active = atomic_long_read(&calc_load_tasks); | ||
3319 | active = active > 0 ? active * FIXED_1 : 0; | ||
3320 | |||
3321 | avenrun[0] = calc_load_n(avenrun[0], EXP_1, active, n); | ||
3322 | avenrun[1] = calc_load_n(avenrun[1], EXP_5, active, n); | ||
3323 | avenrun[2] = calc_load_n(avenrun[2], EXP_15, active, n); | ||
3324 | |||
3325 | calc_load_update += n * LOAD_FREQ; | ||
3326 | } | ||
3327 | |||
3328 | /* | ||
3329 | * Its possible the remainder of the above division also crosses | ||
3330 | * a LOAD_FREQ period, the regular check in calc_global_load() | ||
3331 | * which comes after this will take care of that. | ||
3332 | * | ||
3333 | * Consider us being 11 ticks before a cycle completion, and us | ||
3334 | * sleeping for 4*LOAD_FREQ + 22 ticks, then the above code will | ||
3335 | * age us 4 cycles, and the test in calc_global_load() will | ||
3336 | * pick up the final one. | ||
3337 | */ | ||
3338 | } | ||
3151 | #else | 3339 | #else |
3152 | static void calc_load_account_idle(struct rq *this_rq) | 3340 | static void calc_load_account_idle(struct rq *this_rq) |
3153 | { | 3341 | { |
@@ -3157,6 +3345,10 @@ static inline long calc_load_fold_idle(void) | |||
3157 | { | 3345 | { |
3158 | return 0; | 3346 | return 0; |
3159 | } | 3347 | } |
3348 | |||
3349 | static void calc_global_nohz(unsigned long ticks) | ||
3350 | { | ||
3351 | } | ||
3160 | #endif | 3352 | #endif |
3161 | 3353 | ||
3162 | /** | 3354 | /** |
@@ -3174,24 +3366,17 @@ void get_avenrun(unsigned long *loads, unsigned long offset, int shift) | |||
3174 | loads[2] = (avenrun[2] + offset) << shift; | 3366 | loads[2] = (avenrun[2] + offset) << shift; |
3175 | } | 3367 | } |
3176 | 3368 | ||
3177 | static unsigned long | ||
3178 | calc_load(unsigned long load, unsigned long exp, unsigned long active) | ||
3179 | { | ||
3180 | load *= exp; | ||
3181 | load += active * (FIXED_1 - exp); | ||
3182 | return load >> FSHIFT; | ||
3183 | } | ||
3184 | |||
3185 | /* | 3369 | /* |
3186 | * calc_load - update the avenrun load estimates 10 ticks after the | 3370 | * calc_load - update the avenrun load estimates 10 ticks after the |
3187 | * CPUs have updated calc_load_tasks. | 3371 | * CPUs have updated calc_load_tasks. |
3188 | */ | 3372 | */ |
3189 | void calc_global_load(void) | 3373 | void calc_global_load(unsigned long ticks) |
3190 | { | 3374 | { |
3191 | unsigned long upd = calc_load_update + 10; | ||
3192 | long active; | 3375 | long active; |
3193 | 3376 | ||
3194 | if (time_before(jiffies, upd)) | 3377 | calc_global_nohz(ticks); |
3378 | |||
3379 | if (time_before(jiffies, calc_load_update + 10)) | ||
3195 | return; | 3380 | return; |
3196 | 3381 | ||
3197 | active = atomic_long_read(&calc_load_tasks); | 3382 | active = atomic_long_read(&calc_load_tasks); |
@@ -3845,7 +4030,6 @@ static void put_prev_task(struct rq *rq, struct task_struct *prev) | |||
3845 | { | 4030 | { |
3846 | if (prev->se.on_rq) | 4031 | if (prev->se.on_rq) |
3847 | update_rq_clock(rq); | 4032 | update_rq_clock(rq); |
3848 | rq->skip_clock_update = 0; | ||
3849 | prev->sched_class->put_prev_task(rq, prev); | 4033 | prev->sched_class->put_prev_task(rq, prev); |
3850 | } | 4034 | } |
3851 | 4035 | ||
@@ -3903,7 +4087,6 @@ need_resched_nonpreemptible: | |||
3903 | hrtick_clear(rq); | 4087 | hrtick_clear(rq); |
3904 | 4088 | ||
3905 | raw_spin_lock_irq(&rq->lock); | 4089 | raw_spin_lock_irq(&rq->lock); |
3906 | clear_tsk_need_resched(prev); | ||
3907 | 4090 | ||
3908 | switch_count = &prev->nivcsw; | 4091 | switch_count = &prev->nivcsw; |
3909 | if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) { | 4092 | if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) { |
@@ -3935,6 +4118,8 @@ need_resched_nonpreemptible: | |||
3935 | 4118 | ||
3936 | put_prev_task(rq, prev); | 4119 | put_prev_task(rq, prev); |
3937 | next = pick_next_task(rq); | 4120 | next = pick_next_task(rq); |
4121 | clear_tsk_need_resched(prev); | ||
4122 | rq->skip_clock_update = 0; | ||
3938 | 4123 | ||
3939 | if (likely(prev != next)) { | 4124 | if (likely(prev != next)) { |
3940 | sched_info_switch(prev, next); | 4125 | sched_info_switch(prev, next); |
diff --git a/kernel/taskstats.c b/kernel/taskstats.c index c8231fb15708..3308fd7f1b52 100644 --- a/kernel/taskstats.c +++ b/kernel/taskstats.c | |||
@@ -349,25 +349,47 @@ static int parse(struct nlattr *na, struct cpumask *mask) | |||
349 | return ret; | 349 | return ret; |
350 | } | 350 | } |
351 | 351 | ||
352 | #ifdef CONFIG_IA64 | ||
353 | #define TASKSTATS_NEEDS_PADDING 1 | ||
354 | #endif | ||
355 | |||
352 | static struct taskstats *mk_reply(struct sk_buff *skb, int type, u32 pid) | 356 | static struct taskstats *mk_reply(struct sk_buff *skb, int type, u32 pid) |
353 | { | 357 | { |
354 | struct nlattr *na, *ret; | 358 | struct nlattr *na, *ret; |
355 | int aggr; | 359 | int aggr; |
356 | 360 | ||
357 | /* If we don't pad, we end up with alignment on a 4 byte boundary. | ||
358 | * This causes lots of runtime warnings on systems requiring 8 byte | ||
359 | * alignment */ | ||
360 | u32 pids[2] = { pid, 0 }; | ||
361 | int pid_size = ALIGN(sizeof(pid), sizeof(long)); | ||
362 | |||
363 | aggr = (type == TASKSTATS_TYPE_PID) | 361 | aggr = (type == TASKSTATS_TYPE_PID) |
364 | ? TASKSTATS_TYPE_AGGR_PID | 362 | ? TASKSTATS_TYPE_AGGR_PID |
365 | : TASKSTATS_TYPE_AGGR_TGID; | 363 | : TASKSTATS_TYPE_AGGR_TGID; |
366 | 364 | ||
365 | /* | ||
366 | * The taskstats structure is internally aligned on 8 byte | ||
367 | * boundaries but the layout of the aggregrate reply, with | ||
368 | * two NLA headers and the pid (each 4 bytes), actually | ||
369 | * force the entire structure to be unaligned. This causes | ||
370 | * the kernel to issue unaligned access warnings on some | ||
371 | * architectures like ia64. Unfortunately, some software out there | ||
372 | * doesn't properly unroll the NLA packet and assumes that the start | ||
373 | * of the taskstats structure will always be 20 bytes from the start | ||
374 | * of the netlink payload. Aligning the start of the taskstats | ||
375 | * structure breaks this software, which we don't want. So, for now | ||
376 | * the alignment only happens on architectures that require it | ||
377 | * and those users will have to update to fixed versions of those | ||
378 | * packages. Space is reserved in the packet only when needed. | ||
379 | * This ifdef should be removed in several years e.g. 2012 once | ||
380 | * we can be confident that fixed versions are installed on most | ||
381 | * systems. We add the padding before the aggregate since the | ||
382 | * aggregate is already a defined type. | ||
383 | */ | ||
384 | #ifdef TASKSTATS_NEEDS_PADDING | ||
385 | if (nla_put(skb, TASKSTATS_TYPE_NULL, 0, NULL) < 0) | ||
386 | goto err; | ||
387 | #endif | ||
367 | na = nla_nest_start(skb, aggr); | 388 | na = nla_nest_start(skb, aggr); |
368 | if (!na) | 389 | if (!na) |
369 | goto err; | 390 | goto err; |
370 | if (nla_put(skb, type, pid_size, pids) < 0) | 391 | |
392 | if (nla_put(skb, type, sizeof(pid), &pid) < 0) | ||
371 | goto err; | 393 | goto err; |
372 | ret = nla_reserve(skb, TASKSTATS_TYPE_STATS, sizeof(struct taskstats)); | 394 | ret = nla_reserve(skb, TASKSTATS_TYPE_STATS, sizeof(struct taskstats)); |
373 | if (!ret) | 395 | if (!ret) |
@@ -456,6 +478,18 @@ out: | |||
456 | return rc; | 478 | return rc; |
457 | } | 479 | } |
458 | 480 | ||
481 | static size_t taskstats_packet_size(void) | ||
482 | { | ||
483 | size_t size; | ||
484 | |||
485 | size = nla_total_size(sizeof(u32)) + | ||
486 | nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); | ||
487 | #ifdef TASKSTATS_NEEDS_PADDING | ||
488 | size += nla_total_size(0); /* Padding for alignment */ | ||
489 | #endif | ||
490 | return size; | ||
491 | } | ||
492 | |||
459 | static int cmd_attr_pid(struct genl_info *info) | 493 | static int cmd_attr_pid(struct genl_info *info) |
460 | { | 494 | { |
461 | struct taskstats *stats; | 495 | struct taskstats *stats; |
@@ -464,8 +498,7 @@ static int cmd_attr_pid(struct genl_info *info) | |||
464 | u32 pid; | 498 | u32 pid; |
465 | int rc; | 499 | int rc; |
466 | 500 | ||
467 | size = nla_total_size(sizeof(u32)) + | 501 | size = taskstats_packet_size(); |
468 | nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); | ||
469 | 502 | ||
470 | rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, size); | 503 | rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, size); |
471 | if (rc < 0) | 504 | if (rc < 0) |
@@ -494,8 +527,7 @@ static int cmd_attr_tgid(struct genl_info *info) | |||
494 | u32 tgid; | 527 | u32 tgid; |
495 | int rc; | 528 | int rc; |
496 | 529 | ||
497 | size = nla_total_size(sizeof(u32)) + | 530 | size = taskstats_packet_size(); |
498 | nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); | ||
499 | 531 | ||
500 | rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, size); | 532 | rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, size); |
501 | if (rc < 0) | 533 | if (rc < 0) |
@@ -570,8 +602,7 @@ void taskstats_exit(struct task_struct *tsk, int group_dead) | |||
570 | /* | 602 | /* |
571 | * Size includes space for nested attributes | 603 | * Size includes space for nested attributes |
572 | */ | 604 | */ |
573 | size = nla_total_size(sizeof(u32)) + | 605 | size = taskstats_packet_size(); |
574 | nla_total_size(sizeof(struct taskstats)) + nla_total_size(0); | ||
575 | 606 | ||
576 | is_thread_group = !!taskstats_tgid_alloc(tsk); | 607 | is_thread_group = !!taskstats_tgid_alloc(tsk); |
577 | if (is_thread_group) { | 608 | if (is_thread_group) { |
diff --git a/kernel/timer.c b/kernel/timer.c index 68a9ae7679b7..353b9227c2ec 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -1252,6 +1252,12 @@ unsigned long get_next_timer_interrupt(unsigned long now) | |||
1252 | struct tvec_base *base = __get_cpu_var(tvec_bases); | 1252 | struct tvec_base *base = __get_cpu_var(tvec_bases); |
1253 | unsigned long expires; | 1253 | unsigned long expires; |
1254 | 1254 | ||
1255 | /* | ||
1256 | * Pretend that there is no timer pending if the cpu is offline. | ||
1257 | * Possible pending timers will be migrated later to an active cpu. | ||
1258 | */ | ||
1259 | if (cpu_is_offline(smp_processor_id())) | ||
1260 | return now + NEXT_TIMER_MAX_DELTA; | ||
1255 | spin_lock(&base->lock); | 1261 | spin_lock(&base->lock); |
1256 | if (time_before_eq(base->next_timer, base->timer_jiffies)) | 1262 | if (time_before_eq(base->next_timer, base->timer_jiffies)) |
1257 | base->next_timer = __next_timer_interrupt(base); | 1263 | base->next_timer = __next_timer_interrupt(base); |
@@ -1319,7 +1325,7 @@ void do_timer(unsigned long ticks) | |||
1319 | { | 1325 | { |
1320 | jiffies_64 += ticks; | 1326 | jiffies_64 += ticks; |
1321 | update_wall_time(); | 1327 | update_wall_time(); |
1322 | calc_global_load(); | 1328 | calc_global_load(ticks); |
1323 | } | 1329 | } |
1324 | 1330 | ||
1325 | #ifdef __ARCH_WANT_SYS_ALARM | 1331 | #ifdef __ARCH_WANT_SYS_ALARM |
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c index 9ed509a015d8..bd1c35a4fbcc 100644 --- a/kernel/trace/ring_buffer.c +++ b/kernel/trace/ring_buffer.c | |||
@@ -3853,6 +3853,13 @@ int ring_buffer_read_page(struct ring_buffer *buffer, | |||
3853 | 3853 | ||
3854 | /* Need to copy one event at a time */ | 3854 | /* Need to copy one event at a time */ |
3855 | do { | 3855 | do { |
3856 | /* We need the size of one event, because | ||
3857 | * rb_advance_reader only advances by one event, | ||
3858 | * whereas rb_event_ts_length may include the size of | ||
3859 | * one or two events. | ||
3860 | * We have already ensured there's enough space if this | ||
3861 | * is a time extend. */ | ||
3862 | size = rb_event_length(event); | ||
3856 | memcpy(bpage->data + pos, rpage->data + rpos, size); | 3863 | memcpy(bpage->data + pos, rpage->data + rpos, size); |
3857 | 3864 | ||
3858 | len -= size; | 3865 | len -= size; |
@@ -3867,7 +3874,7 @@ int ring_buffer_read_page(struct ring_buffer *buffer, | |||
3867 | event = rb_reader_event(cpu_buffer); | 3874 | event = rb_reader_event(cpu_buffer); |
3868 | /* Always keep the time extend and data together */ | 3875 | /* Always keep the time extend and data together */ |
3869 | size = rb_event_ts_length(event); | 3876 | size = rb_event_ts_length(event); |
3870 | } while (len > size); | 3877 | } while (len >= size); |
3871 | 3878 | ||
3872 | /* update bpage */ | 3879 | /* update bpage */ |
3873 | local_set(&bpage->commit, pos); | 3880 | local_set(&bpage->commit, pos); |
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index c380612273bf..f8cf959bad45 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c | |||
@@ -2338,11 +2338,19 @@ tracing_write_stub(struct file *filp, const char __user *ubuf, | |||
2338 | return count; | 2338 | return count; |
2339 | } | 2339 | } |
2340 | 2340 | ||
2341 | static loff_t tracing_seek(struct file *file, loff_t offset, int origin) | ||
2342 | { | ||
2343 | if (file->f_mode & FMODE_READ) | ||
2344 | return seq_lseek(file, offset, origin); | ||
2345 | else | ||
2346 | return 0; | ||
2347 | } | ||
2348 | |||
2341 | static const struct file_operations tracing_fops = { | 2349 | static const struct file_operations tracing_fops = { |
2342 | .open = tracing_open, | 2350 | .open = tracing_open, |
2343 | .read = seq_read, | 2351 | .read = seq_read, |
2344 | .write = tracing_write_stub, | 2352 | .write = tracing_write_stub, |
2345 | .llseek = seq_lseek, | 2353 | .llseek = tracing_seek, |
2346 | .release = tracing_release, | 2354 | .release = tracing_release, |
2347 | }; | 2355 | }; |
2348 | 2356 | ||
diff --git a/kernel/user.c b/kernel/user.c index 2c7d8d5914b1..5c598ca781df 100644 --- a/kernel/user.c +++ b/kernel/user.c | |||
@@ -158,6 +158,7 @@ struct user_struct *alloc_uid(struct user_namespace *ns, uid_t uid) | |||
158 | spin_lock_irq(&uidhash_lock); | 158 | spin_lock_irq(&uidhash_lock); |
159 | up = uid_hash_find(uid, hashent); | 159 | up = uid_hash_find(uid, hashent); |
160 | if (up) { | 160 | if (up) { |
161 | put_user_ns(ns); | ||
161 | key_put(new->uid_keyring); | 162 | key_put(new->uid_keyring); |
162 | key_put(new->session_keyring); | 163 | key_put(new->session_keyring); |
163 | kmem_cache_free(uid_cachep, new); | 164 | kmem_cache_free(uid_cachep, new); |
diff --git a/kernel/watchdog.c b/kernel/watchdog.c index 6e3c41a4024c..5b082156cd21 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c | |||
@@ -364,7 +364,8 @@ static int watchdog_nmi_enable(int cpu) | |||
364 | goto out_save; | 364 | goto out_save; |
365 | } | 365 | } |
366 | 366 | ||
367 | printk(KERN_ERR "NMI watchdog failed to create perf event on cpu%i: %p\n", cpu, event); | 367 | printk(KERN_ERR "NMI watchdog disabled for cpu%i: unable to create perf event: %ld\n", |
368 | cpu, PTR_ERR(event)); | ||
368 | return PTR_ERR(event); | 369 | return PTR_ERR(event); |
369 | 370 | ||
370 | /* success path */ | 371 | /* success path */ |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index 90db1bd1a978..e785b0f2aea5 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -661,7 +661,7 @@ void wq_worker_waking_up(struct task_struct *task, unsigned int cpu) | |||
661 | { | 661 | { |
662 | struct worker *worker = kthread_data(task); | 662 | struct worker *worker = kthread_data(task); |
663 | 663 | ||
664 | if (likely(!(worker->flags & WORKER_NOT_RUNNING))) | 664 | if (!(worker->flags & WORKER_NOT_RUNNING)) |
665 | atomic_inc(get_gcwq_nr_running(cpu)); | 665 | atomic_inc(get_gcwq_nr_running(cpu)); |
666 | } | 666 | } |
667 | 667 | ||
@@ -687,7 +687,7 @@ struct task_struct *wq_worker_sleeping(struct task_struct *task, | |||
687 | struct global_cwq *gcwq = get_gcwq(cpu); | 687 | struct global_cwq *gcwq = get_gcwq(cpu); |
688 | atomic_t *nr_running = get_gcwq_nr_running(cpu); | 688 | atomic_t *nr_running = get_gcwq_nr_running(cpu); |
689 | 689 | ||
690 | if (unlikely(worker->flags & WORKER_NOT_RUNNING)) | 690 | if (worker->flags & WORKER_NOT_RUNNING) |
691 | return NULL; | 691 | return NULL; |
692 | 692 | ||
693 | /* this can only happen on the local cpu */ | 693 | /* this can only happen on the local cpu */ |
@@ -3692,7 +3692,8 @@ static int __init init_workqueues(void) | |||
3692 | system_nrt_wq = alloc_workqueue("events_nrt", WQ_NON_REENTRANT, 0); | 3692 | system_nrt_wq = alloc_workqueue("events_nrt", WQ_NON_REENTRANT, 0); |
3693 | system_unbound_wq = alloc_workqueue("events_unbound", WQ_UNBOUND, | 3693 | system_unbound_wq = alloc_workqueue("events_unbound", WQ_UNBOUND, |
3694 | WQ_UNBOUND_MAX_ACTIVE); | 3694 | WQ_UNBOUND_MAX_ACTIVE); |
3695 | BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq); | 3695 | BUG_ON(!system_wq || !system_long_wq || !system_nrt_wq || |
3696 | !system_unbound_wq); | ||
3696 | return 0; | 3697 | return 0; |
3697 | } | 3698 | } |
3698 | early_initcall(init_workqueues); | 3699 | early_initcall(init_workqueues); |
diff --git a/mm/compaction.c b/mm/compaction.c index 4d709ee59013..1a8894eadf72 100644 --- a/mm/compaction.c +++ b/mm/compaction.c | |||
@@ -279,7 +279,6 @@ static unsigned long isolate_migratepages(struct zone *zone, | |||
279 | /* Successfully isolated */ | 279 | /* Successfully isolated */ |
280 | del_page_from_lru_list(zone, page, page_lru(page)); | 280 | del_page_from_lru_list(zone, page, page_lru(page)); |
281 | list_add(&page->lru, migratelist); | 281 | list_add(&page->lru, migratelist); |
282 | mem_cgroup_del_lru(page); | ||
283 | cc->nr_migratepages++; | 282 | cc->nr_migratepages++; |
284 | 283 | ||
285 | /* Avoid isolating too much */ | 284 | /* Avoid isolating too much */ |
diff --git a/mm/filemap.c b/mm/filemap.c index ea89840fc65f..6b9aee20f242 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -143,13 +143,18 @@ void __remove_from_page_cache(struct page *page) | |||
143 | void remove_from_page_cache(struct page *page) | 143 | void remove_from_page_cache(struct page *page) |
144 | { | 144 | { |
145 | struct address_space *mapping = page->mapping; | 145 | struct address_space *mapping = page->mapping; |
146 | void (*freepage)(struct page *); | ||
146 | 147 | ||
147 | BUG_ON(!PageLocked(page)); | 148 | BUG_ON(!PageLocked(page)); |
148 | 149 | ||
150 | freepage = mapping->a_ops->freepage; | ||
149 | spin_lock_irq(&mapping->tree_lock); | 151 | spin_lock_irq(&mapping->tree_lock); |
150 | __remove_from_page_cache(page); | 152 | __remove_from_page_cache(page); |
151 | spin_unlock_irq(&mapping->tree_lock); | 153 | spin_unlock_irq(&mapping->tree_lock); |
152 | mem_cgroup_uncharge_cache_page(page); | 154 | mem_cgroup_uncharge_cache_page(page); |
155 | |||
156 | if (freepage) | ||
157 | freepage(page); | ||
153 | } | 158 | } |
154 | EXPORT_SYMBOL(remove_from_page_cache); | 159 | EXPORT_SYMBOL(remove_from_page_cache); |
155 | 160 | ||
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 7a22b4129211..00bb8a64d028 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -1925,19 +1925,18 @@ again: | |||
1925 | 1925 | ||
1926 | rcu_read_lock(); | 1926 | rcu_read_lock(); |
1927 | p = rcu_dereference(mm->owner); | 1927 | p = rcu_dereference(mm->owner); |
1928 | VM_BUG_ON(!p); | ||
1929 | /* | 1928 | /* |
1930 | * because we don't have task_lock(), "p" can exit while | 1929 | * Because we don't have task_lock(), "p" can exit. |
1931 | * we're here. In that case, "mem" can point to root | 1930 | * In that case, "mem" can point to root or p can be NULL with |
1932 | * cgroup but never be NULL. (and task_struct itself is freed | 1931 | * race with swapoff. Then, we have small risk of mis-accouning. |
1933 | * by RCU, cgroup itself is RCU safe.) Then, we have small | 1932 | * But such kind of mis-account by race always happens because |
1934 | * risk here to get wrong cgroup. But such kind of mis-account | 1933 | * we don't have cgroup_mutex(). It's overkill and we allo that |
1935 | * by race always happens because we don't have cgroup_mutex(). | 1934 | * small race, here. |
1936 | * It's overkill and we allow that small race, here. | 1935 | * (*) swapoff at el will charge against mm-struct not against |
1936 | * task-struct. So, mm->owner can be NULL. | ||
1937 | */ | 1937 | */ |
1938 | mem = mem_cgroup_from_task(p); | 1938 | mem = mem_cgroup_from_task(p); |
1939 | VM_BUG_ON(!mem); | 1939 | if (!mem || mem_cgroup_is_root(mem)) { |
1940 | if (mem_cgroup_is_root(mem)) { | ||
1941 | rcu_read_unlock(); | 1940 | rcu_read_unlock(); |
1942 | goto done; | 1941 | goto done; |
1943 | } | 1942 | } |
diff --git a/mm/migrate.c b/mm/migrate.c index fe5a3c6a5426..6ae8a66a7045 100644 --- a/mm/migrate.c +++ b/mm/migrate.c | |||
@@ -35,6 +35,8 @@ | |||
35 | #include <linux/hugetlb.h> | 35 | #include <linux/hugetlb.h> |
36 | #include <linux/gfp.h> | 36 | #include <linux/gfp.h> |
37 | 37 | ||
38 | #include <asm/tlbflush.h> | ||
39 | |||
38 | #include "internal.h" | 40 | #include "internal.h" |
39 | 41 | ||
40 | #define lru_to_page(_head) (list_entry((_head)->prev, struct page, lru)) | 42 | #define lru_to_page(_head) (list_entry((_head)->prev, struct page, lru)) |
@@ -2462,6 +2462,7 @@ int install_special_mapping(struct mm_struct *mm, | |||
2462 | unsigned long addr, unsigned long len, | 2462 | unsigned long addr, unsigned long len, |
2463 | unsigned long vm_flags, struct page **pages) | 2463 | unsigned long vm_flags, struct page **pages) |
2464 | { | 2464 | { |
2465 | int ret; | ||
2465 | struct vm_area_struct *vma; | 2466 | struct vm_area_struct *vma; |
2466 | 2467 | ||
2467 | vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); | 2468 | vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL); |
@@ -2479,16 +2480,23 @@ int install_special_mapping(struct mm_struct *mm, | |||
2479 | vma->vm_ops = &special_mapping_vmops; | 2480 | vma->vm_ops = &special_mapping_vmops; |
2480 | vma->vm_private_data = pages; | 2481 | vma->vm_private_data = pages; |
2481 | 2482 | ||
2482 | if (unlikely(insert_vm_struct(mm, vma))) { | 2483 | ret = security_file_mmap(NULL, 0, 0, 0, vma->vm_start, 1); |
2483 | kmem_cache_free(vm_area_cachep, vma); | 2484 | if (ret) |
2484 | return -ENOMEM; | 2485 | goto out; |
2485 | } | 2486 | |
2487 | ret = insert_vm_struct(mm, vma); | ||
2488 | if (ret) | ||
2489 | goto out; | ||
2486 | 2490 | ||
2487 | mm->total_vm += len >> PAGE_SHIFT; | 2491 | mm->total_vm += len >> PAGE_SHIFT; |
2488 | 2492 | ||
2489 | perf_event_mmap(vma); | 2493 | perf_event_mmap(vma); |
2490 | 2494 | ||
2491 | return 0; | 2495 | return 0; |
2496 | |||
2497 | out: | ||
2498 | kmem_cache_free(vm_area_cachep, vma); | ||
2499 | return ret; | ||
2492 | } | 2500 | } |
2493 | 2501 | ||
2494 | static DEFINE_MUTEX(mm_all_locks_mutex); | 2502 | static DEFINE_MUTEX(mm_all_locks_mutex); |
diff --git a/mm/nommu.c b/mm/nommu.c index 27a9ac588516..ef4045d010d5 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
@@ -10,7 +10,7 @@ | |||
10 | * Copyright (c) 2000-2003 David McCullough <davidm@snapgear.com> | 10 | * Copyright (c) 2000-2003 David McCullough <davidm@snapgear.com> |
11 | * Copyright (c) 2000-2001 D Jeff Dionne <jeff@uClinux.org> | 11 | * Copyright (c) 2000-2001 D Jeff Dionne <jeff@uClinux.org> |
12 | * Copyright (c) 2002 Greg Ungerer <gerg@snapgear.com> | 12 | * Copyright (c) 2002 Greg Ungerer <gerg@snapgear.com> |
13 | * Copyright (c) 2007-2009 Paul Mundt <lethal@linux-sh.org> | 13 | * Copyright (c) 2007-2010 Paul Mundt <lethal@linux-sh.org> |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
@@ -328,6 +328,7 @@ void *vmalloc_node(unsigned long size, int node) | |||
328 | { | 328 | { |
329 | return vmalloc(size); | 329 | return vmalloc(size); |
330 | } | 330 | } |
331 | EXPORT_SYMBOL(vmalloc_node); | ||
331 | 332 | ||
332 | /** | 333 | /** |
333 | * vzalloc_node - allocate memory on a specific node with zero fill | 334 | * vzalloc_node - allocate memory on a specific node with zero fill |
@@ -440,6 +441,31 @@ void __attribute__((weak)) vmalloc_sync_all(void) | |||
440 | { | 441 | { |
441 | } | 442 | } |
442 | 443 | ||
444 | /** | ||
445 | * alloc_vm_area - allocate a range of kernel address space | ||
446 | * @size: size of the area | ||
447 | * | ||
448 | * Returns: NULL on failure, vm_struct on success | ||
449 | * | ||
450 | * This function reserves a range of kernel address space, and | ||
451 | * allocates pagetables to map that range. No actual mappings | ||
452 | * are created. If the kernel address space is not shared | ||
453 | * between processes, it syncs the pagetable across all | ||
454 | * processes. | ||
455 | */ | ||
456 | struct vm_struct *alloc_vm_area(size_t size) | ||
457 | { | ||
458 | BUG(); | ||
459 | return NULL; | ||
460 | } | ||
461 | EXPORT_SYMBOL_GPL(alloc_vm_area); | ||
462 | |||
463 | void free_vm_area(struct vm_struct *area) | ||
464 | { | ||
465 | BUG(); | ||
466 | } | ||
467 | EXPORT_SYMBOL_GPL(free_vm_area); | ||
468 | |||
443 | int vm_insert_page(struct vm_area_struct *vma, unsigned long addr, | 469 | int vm_insert_page(struct vm_area_struct *vma, unsigned long addr, |
444 | struct page *page) | 470 | struct page *page) |
445 | { | 471 | { |
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index b840afa89761..b4edfe7ce06c 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -563,7 +563,7 @@ static void balance_dirty_pages(struct address_space *mapping, | |||
563 | break; /* We've done our duty */ | 563 | break; /* We've done our duty */ |
564 | } | 564 | } |
565 | trace_wbc_balance_dirty_wait(&wbc, bdi); | 565 | trace_wbc_balance_dirty_wait(&wbc, bdi); |
566 | __set_current_state(TASK_INTERRUPTIBLE); | 566 | __set_current_state(TASK_UNINTERRUPTIBLE); |
567 | io_schedule_timeout(pause); | 567 | io_schedule_timeout(pause); |
568 | 568 | ||
569 | /* | 569 | /* |
diff --git a/mm/percpu.c b/mm/percpu.c index efe816856a9d..02ba91230b99 100644 --- a/mm/percpu.c +++ b/mm/percpu.c | |||
@@ -1268,7 +1268,7 @@ int __init pcpu_setup_first_chunk(const struct pcpu_alloc_info *ai, | |||
1268 | 1268 | ||
1269 | /* we're done parsing the input, undefine BUG macro and dump config */ | 1269 | /* we're done parsing the input, undefine BUG macro and dump config */ |
1270 | #undef PCPU_SETUP_BUG_ON | 1270 | #undef PCPU_SETUP_BUG_ON |
1271 | pcpu_dump_alloc_info(KERN_INFO, ai); | 1271 | pcpu_dump_alloc_info(KERN_DEBUG, ai); |
1272 | 1272 | ||
1273 | pcpu_nr_groups = ai->nr_groups; | 1273 | pcpu_nr_groups = ai->nr_groups; |
1274 | pcpu_group_offsets = group_offsets; | 1274 | pcpu_group_offsets = group_offsets; |
diff --git a/mm/truncate.c b/mm/truncate.c index ba887bff48c5..3c2d5ddfa0d4 100644 --- a/mm/truncate.c +++ b/mm/truncate.c | |||
@@ -390,6 +390,10 @@ invalidate_complete_page2(struct address_space *mapping, struct page *page) | |||
390 | __remove_from_page_cache(page); | 390 | __remove_from_page_cache(page); |
391 | spin_unlock_irq(&mapping->tree_lock); | 391 | spin_unlock_irq(&mapping->tree_lock); |
392 | mem_cgroup_uncharge_cache_page(page); | 392 | mem_cgroup_uncharge_cache_page(page); |
393 | |||
394 | if (mapping->a_ops->freepage) | ||
395 | mapping->a_ops->freepage(page); | ||
396 | |||
393 | page_cache_release(page); /* pagecache ref */ | 397 | page_cache_release(page); /* pagecache ref */ |
394 | return 1; | 398 | return 1; |
395 | failed: | 399 | failed: |
diff --git a/mm/vmscan.c b/mm/vmscan.c index d31d7ce52c0e..9ca587c69274 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -494,9 +494,16 @@ static int __remove_mapping(struct address_space *mapping, struct page *page) | |||
494 | spin_unlock_irq(&mapping->tree_lock); | 494 | spin_unlock_irq(&mapping->tree_lock); |
495 | swapcache_free(swap, page); | 495 | swapcache_free(swap, page); |
496 | } else { | 496 | } else { |
497 | void (*freepage)(struct page *); | ||
498 | |||
499 | freepage = mapping->a_ops->freepage; | ||
500 | |||
497 | __remove_from_page_cache(page); | 501 | __remove_from_page_cache(page); |
498 | spin_unlock_irq(&mapping->tree_lock); | 502 | spin_unlock_irq(&mapping->tree_lock); |
499 | mem_cgroup_uncharge_cache_page(page); | 503 | mem_cgroup_uncharge_cache_page(page); |
504 | |||
505 | if (freepage != NULL) | ||
506 | freepage(page); | ||
500 | } | 507 | } |
501 | 508 | ||
502 | return 1; | 509 | return 1; |
diff --git a/net/atm/atm_sysfs.c b/net/atm/atm_sysfs.c index 799c631f0fed..f7fa67c78766 100644 --- a/net/atm/atm_sysfs.c +++ b/net/atm/atm_sysfs.c | |||
@@ -143,12 +143,13 @@ static struct class atm_class = { | |||
143 | .dev_uevent = atm_uevent, | 143 | .dev_uevent = atm_uevent, |
144 | }; | 144 | }; |
145 | 145 | ||
146 | int atm_register_sysfs(struct atm_dev *adev) | 146 | int atm_register_sysfs(struct atm_dev *adev, struct device *parent) |
147 | { | 147 | { |
148 | struct device *cdev = &adev->class_dev; | 148 | struct device *cdev = &adev->class_dev; |
149 | int i, j, err; | 149 | int i, j, err; |
150 | 150 | ||
151 | cdev->class = &atm_class; | 151 | cdev->class = &atm_class; |
152 | cdev->parent = parent; | ||
152 | dev_set_drvdata(cdev, adev); | 153 | dev_set_drvdata(cdev, adev); |
153 | 154 | ||
154 | dev_set_name(cdev, "%s%d", adev->type, adev->number); | 155 | dev_set_name(cdev, "%s%d", adev->type, adev->number); |
diff --git a/net/atm/resources.c b/net/atm/resources.c index d29e58261511..23f45ce6f351 100644 --- a/net/atm/resources.c +++ b/net/atm/resources.c | |||
@@ -74,8 +74,9 @@ struct atm_dev *atm_dev_lookup(int number) | |||
74 | } | 74 | } |
75 | EXPORT_SYMBOL(atm_dev_lookup); | 75 | EXPORT_SYMBOL(atm_dev_lookup); |
76 | 76 | ||
77 | struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, | 77 | struct atm_dev *atm_dev_register(const char *type, struct device *parent, |
78 | int number, unsigned long *flags) | 78 | const struct atmdev_ops *ops, int number, |
79 | unsigned long *flags) | ||
79 | { | 80 | { |
80 | struct atm_dev *dev, *inuse; | 81 | struct atm_dev *dev, *inuse; |
81 | 82 | ||
@@ -115,7 +116,7 @@ struct atm_dev *atm_dev_register(const char *type, const struct atmdev_ops *ops, | |||
115 | goto out_fail; | 116 | goto out_fail; |
116 | } | 117 | } |
117 | 118 | ||
118 | if (atm_register_sysfs(dev) < 0) { | 119 | if (atm_register_sysfs(dev, parent) < 0) { |
119 | pr_err("atm_register_sysfs failed for dev %s\n", type); | 120 | pr_err("atm_register_sysfs failed for dev %s\n", type); |
120 | atm_proc_dev_deregister(dev); | 121 | atm_proc_dev_deregister(dev); |
121 | goto out_fail; | 122 | goto out_fail; |
diff --git a/net/atm/resources.h b/net/atm/resources.h index 126fb1840dfb..521431e30507 100644 --- a/net/atm/resources.h +++ b/net/atm/resources.h | |||
@@ -42,6 +42,6 @@ static inline void atm_proc_dev_deregister(struct atm_dev *dev) | |||
42 | 42 | ||
43 | #endif /* CONFIG_PROC_FS */ | 43 | #endif /* CONFIG_PROC_FS */ |
44 | 44 | ||
45 | int atm_register_sysfs(struct atm_dev *adev); | 45 | int atm_register_sysfs(struct atm_dev *adev, struct device *parent); |
46 | void atm_unregister_sysfs(struct atm_dev *adev); | 46 | void atm_unregister_sysfs(struct atm_dev *adev); |
47 | #endif | 47 | #endif |
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index fa642aa652bd..432a9a633e8d 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
@@ -311,6 +311,7 @@ static void rfcomm_dlc_clear_state(struct rfcomm_dlc *d) | |||
311 | d->state = BT_OPEN; | 311 | d->state = BT_OPEN; |
312 | d->flags = 0; | 312 | d->flags = 0; |
313 | d->mscex = 0; | 313 | d->mscex = 0; |
314 | d->sec_level = BT_SECURITY_LOW; | ||
314 | d->mtu = RFCOMM_DEFAULT_MTU; | 315 | d->mtu = RFCOMM_DEFAULT_MTU; |
315 | d->v24_sig = RFCOMM_V24_RTC | RFCOMM_V24_RTR | RFCOMM_V24_DV; | 316 | d->v24_sig = RFCOMM_V24_RTC | RFCOMM_V24_RTR | RFCOMM_V24_DV; |
316 | 317 | ||
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index d0927d1fdada..66b9e5c0523a 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -882,7 +882,7 @@ static int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 type) | |||
882 | int lm = 0; | 882 | int lm = 0; |
883 | 883 | ||
884 | if (type != SCO_LINK && type != ESCO_LINK) | 884 | if (type != SCO_LINK && type != ESCO_LINK) |
885 | return 0; | 885 | return -EINVAL; |
886 | 886 | ||
887 | BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); | 887 | BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr)); |
888 | 888 | ||
@@ -908,7 +908,7 @@ static int sco_connect_cfm(struct hci_conn *hcon, __u8 status) | |||
908 | BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); | 908 | BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status); |
909 | 909 | ||
910 | if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) | 910 | if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) |
911 | return 0; | 911 | return -EINVAL; |
912 | 912 | ||
913 | if (!status) { | 913 | if (!status) { |
914 | struct sco_conn *conn; | 914 | struct sco_conn *conn; |
@@ -927,7 +927,7 @@ static int sco_disconn_cfm(struct hci_conn *hcon, __u8 reason) | |||
927 | BT_DBG("hcon %p reason %d", hcon, reason); | 927 | BT_DBG("hcon %p reason %d", hcon, reason); |
928 | 928 | ||
929 | if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) | 929 | if (hcon->type != SCO_LINK && hcon->type != ESCO_LINK) |
930 | return 0; | 930 | return -EINVAL; |
931 | 931 | ||
932 | sco_conn_del(hcon, bt_err(reason)); | 932 | sco_conn_del(hcon, bt_err(reason)); |
933 | 933 | ||
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index eb5b256ffc88..543b3262d002 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
@@ -437,7 +437,7 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br, | |||
437 | ip6h = ipv6_hdr(skb); | 437 | ip6h = ipv6_hdr(skb); |
438 | 438 | ||
439 | *(__force __be32 *)ip6h = htonl(0x60000000); | 439 | *(__force __be32 *)ip6h = htonl(0x60000000); |
440 | ip6h->payload_len = 8 + sizeof(*mldq); | 440 | ip6h->payload_len = htons(8 + sizeof(*mldq)); |
441 | ip6h->nexthdr = IPPROTO_HOPOPTS; | 441 | ip6h->nexthdr = IPPROTO_HOPOPTS; |
442 | ip6h->hop_limit = 1; | 442 | ip6h->hop_limit = 1; |
443 | ipv6_addr_set(&ip6h->saddr, 0, 0, 0, 0); | 443 | ipv6_addr_set(&ip6h->saddr, 0, 0, 0, 0); |
@@ -1430,7 +1430,7 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, | |||
1430 | struct net_bridge_port *port, | 1430 | struct net_bridge_port *port, |
1431 | struct sk_buff *skb) | 1431 | struct sk_buff *skb) |
1432 | { | 1432 | { |
1433 | struct sk_buff *skb2 = skb; | 1433 | struct sk_buff *skb2; |
1434 | struct ipv6hdr *ip6h; | 1434 | struct ipv6hdr *ip6h; |
1435 | struct icmp6hdr *icmp6h; | 1435 | struct icmp6hdr *icmp6h; |
1436 | u8 nexthdr; | 1436 | u8 nexthdr; |
@@ -1469,15 +1469,15 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, | |||
1469 | if (!skb2) | 1469 | if (!skb2) |
1470 | return -ENOMEM; | 1470 | return -ENOMEM; |
1471 | 1471 | ||
1472 | err = -EINVAL; | ||
1473 | if (!pskb_may_pull(skb2, offset + sizeof(struct icmp6hdr))) | ||
1474 | goto out; | ||
1475 | |||
1472 | len -= offset - skb_network_offset(skb2); | 1476 | len -= offset - skb_network_offset(skb2); |
1473 | 1477 | ||
1474 | __skb_pull(skb2, offset); | 1478 | __skb_pull(skb2, offset); |
1475 | skb_reset_transport_header(skb2); | 1479 | skb_reset_transport_header(skb2); |
1476 | 1480 | ||
1477 | err = -EINVAL; | ||
1478 | if (!pskb_may_pull(skb2, sizeof(*icmp6h))) | ||
1479 | goto out; | ||
1480 | |||
1481 | icmp6h = icmp6_hdr(skb2); | 1481 | icmp6h = icmp6_hdr(skb2); |
1482 | 1482 | ||
1483 | switch (icmp6h->icmp6_type) { | 1483 | switch (icmp6h->icmp6_type) { |
@@ -1516,7 +1516,12 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, | |||
1516 | switch (icmp6h->icmp6_type) { | 1516 | switch (icmp6h->icmp6_type) { |
1517 | case ICMPV6_MGM_REPORT: | 1517 | case ICMPV6_MGM_REPORT: |
1518 | { | 1518 | { |
1519 | struct mld_msg *mld = (struct mld_msg *)icmp6h; | 1519 | struct mld_msg *mld; |
1520 | if (!pskb_may_pull(skb2, sizeof(*mld))) { | ||
1521 | err = -EINVAL; | ||
1522 | goto out; | ||
1523 | } | ||
1524 | mld = (struct mld_msg *)skb_transport_header(skb2); | ||
1520 | BR_INPUT_SKB_CB(skb2)->mrouters_only = 1; | 1525 | BR_INPUT_SKB_CB(skb2)->mrouters_only = 1; |
1521 | err = br_ip6_multicast_add_group(br, port, &mld->mld_mca); | 1526 | err = br_ip6_multicast_add_group(br, port, &mld->mld_mca); |
1522 | break; | 1527 | break; |
@@ -1529,15 +1534,18 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br, | |||
1529 | break; | 1534 | break; |
1530 | case ICMPV6_MGM_REDUCTION: | 1535 | case ICMPV6_MGM_REDUCTION: |
1531 | { | 1536 | { |
1532 | struct mld_msg *mld = (struct mld_msg *)icmp6h; | 1537 | struct mld_msg *mld; |
1538 | if (!pskb_may_pull(skb2, sizeof(*mld))) { | ||
1539 | err = -EINVAL; | ||
1540 | goto out; | ||
1541 | } | ||
1542 | mld = (struct mld_msg *)skb_transport_header(skb2); | ||
1533 | br_ip6_multicast_leave_group(br, port, &mld->mld_mca); | 1543 | br_ip6_multicast_leave_group(br, port, &mld->mld_mca); |
1534 | } | 1544 | } |
1535 | } | 1545 | } |
1536 | 1546 | ||
1537 | out: | 1547 | out: |
1538 | __skb_push(skb2, offset); | 1548 | kfree_skb(skb2); |
1539 | if (skb2 != skb) | ||
1540 | kfree_skb(skb2); | ||
1541 | return err; | 1549 | return err; |
1542 | } | 1550 | } |
1543 | #endif | 1551 | #endif |
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c index 35cf27087b56..e3d7aefa9181 100644 --- a/net/bridge/br_stp_bpdu.c +++ b/net/bridge/br_stp_bpdu.c | |||
@@ -50,6 +50,8 @@ static void br_send_bpdu(struct net_bridge_port *p, | |||
50 | 50 | ||
51 | llc_mac_hdr_init(skb, p->dev->dev_addr, p->br->group_addr); | 51 | llc_mac_hdr_init(skb, p->dev->dev_addr, p->br->group_addr); |
52 | 52 | ||
53 | skb_reset_mac_header(skb); | ||
54 | |||
53 | NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, | 55 | NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, |
54 | dev_queue_xmit); | 56 | dev_queue_xmit); |
55 | } | 57 | } |
diff --git a/net/can/bcm.c b/net/can/bcm.c index 6faa8256e10c..9d5e8accfab1 100644 --- a/net/can/bcm.c +++ b/net/can/bcm.c | |||
@@ -125,7 +125,7 @@ struct bcm_sock { | |||
125 | struct list_head tx_ops; | 125 | struct list_head tx_ops; |
126 | unsigned long dropped_usr_msgs; | 126 | unsigned long dropped_usr_msgs; |
127 | struct proc_dir_entry *bcm_proc_read; | 127 | struct proc_dir_entry *bcm_proc_read; |
128 | char procname [20]; /* pointer printed in ASCII with \0 */ | 128 | char procname [32]; /* inode number in decimal with \0 */ |
129 | }; | 129 | }; |
130 | 130 | ||
131 | static inline struct bcm_sock *bcm_sk(const struct sock *sk) | 131 | static inline struct bcm_sock *bcm_sk(const struct sock *sk) |
@@ -1521,7 +1521,7 @@ static int bcm_connect(struct socket *sock, struct sockaddr *uaddr, int len, | |||
1521 | 1521 | ||
1522 | if (proc_dir) { | 1522 | if (proc_dir) { |
1523 | /* unique socket address as filename */ | 1523 | /* unique socket address as filename */ |
1524 | sprintf(bo->procname, "%p", sock); | 1524 | sprintf(bo->procname, "%lu", sock_i_ino(sk)); |
1525 | bo->bcm_proc_read = proc_create_data(bo->procname, 0644, | 1525 | bo->bcm_proc_read = proc_create_data(bo->procname, 0644, |
1526 | proc_dir, | 1526 | proc_dir, |
1527 | &bcm_proc_fops, sk); | 1527 | &bcm_proc_fops, sk); |
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 1c7a2ec4f3cc..b6ff4a1519ab 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c | |||
@@ -97,11 +97,9 @@ struct workqueue_struct *ceph_msgr_wq; | |||
97 | int ceph_msgr_init(void) | 97 | int ceph_msgr_init(void) |
98 | { | 98 | { |
99 | ceph_msgr_wq = create_workqueue("ceph-msgr"); | 99 | ceph_msgr_wq = create_workqueue("ceph-msgr"); |
100 | if (IS_ERR(ceph_msgr_wq)) { | 100 | if (!ceph_msgr_wq) { |
101 | int ret = PTR_ERR(ceph_msgr_wq); | 101 | pr_err("msgr_init failed to create workqueue\n"); |
102 | pr_err("msgr_init failed to create workqueue: %d\n", ret); | 102 | return -ENOMEM; |
103 | ceph_msgr_wq = NULL; | ||
104 | return ret; | ||
105 | } | 103 | } |
106 | return 0; | 104 | return 0; |
107 | } | 105 | } |
diff --git a/net/ceph/pagevec.c b/net/ceph/pagevec.c index ac34feeb2b3a..1a040e64c69f 100644 --- a/net/ceph/pagevec.c +++ b/net/ceph/pagevec.c | |||
@@ -13,7 +13,7 @@ | |||
13 | * build a vector of user pages | 13 | * build a vector of user pages |
14 | */ | 14 | */ |
15 | struct page **ceph_get_direct_page_vector(const char __user *data, | 15 | struct page **ceph_get_direct_page_vector(const char __user *data, |
16 | int num_pages) | 16 | int num_pages, bool write_page) |
17 | { | 17 | { |
18 | struct page **pages; | 18 | struct page **pages; |
19 | int rc; | 19 | int rc; |
@@ -24,24 +24,27 @@ struct page **ceph_get_direct_page_vector(const char __user *data, | |||
24 | 24 | ||
25 | down_read(¤t->mm->mmap_sem); | 25 | down_read(¤t->mm->mmap_sem); |
26 | rc = get_user_pages(current, current->mm, (unsigned long)data, | 26 | rc = get_user_pages(current, current->mm, (unsigned long)data, |
27 | num_pages, 0, 0, pages, NULL); | 27 | num_pages, write_page, 0, pages, NULL); |
28 | up_read(¤t->mm->mmap_sem); | 28 | up_read(¤t->mm->mmap_sem); |
29 | if (rc < 0) | 29 | if (rc < num_pages) |
30 | goto fail; | 30 | goto fail; |
31 | return pages; | 31 | return pages; |
32 | 32 | ||
33 | fail: | 33 | fail: |
34 | kfree(pages); | 34 | ceph_put_page_vector(pages, rc > 0 ? rc : 0, false); |
35 | return ERR_PTR(rc); | 35 | return ERR_PTR(rc); |
36 | } | 36 | } |
37 | EXPORT_SYMBOL(ceph_get_direct_page_vector); | 37 | EXPORT_SYMBOL(ceph_get_direct_page_vector); |
38 | 38 | ||
39 | void ceph_put_page_vector(struct page **pages, int num_pages) | 39 | void ceph_put_page_vector(struct page **pages, int num_pages, bool dirty) |
40 | { | 40 | { |
41 | int i; | 41 | int i; |
42 | 42 | ||
43 | for (i = 0; i < num_pages; i++) | 43 | for (i = 0; i < num_pages; i++) { |
44 | if (dirty) | ||
45 | set_page_dirty_lock(pages[i]); | ||
44 | put_page(pages[i]); | 46 | put_page(pages[i]); |
47 | } | ||
45 | kfree(pages); | 48 | kfree(pages); |
46 | } | 49 | } |
47 | EXPORT_SYMBOL(ceph_put_page_vector); | 50 | EXPORT_SYMBOL(ceph_put_page_vector); |
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 82a4369ae150..a20e5d3bbfa0 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c | |||
@@ -181,8 +181,7 @@ static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops, | |||
181 | { | 181 | { |
182 | int ret = 0; | 182 | int ret = 0; |
183 | 183 | ||
184 | if (rule->iifindex && (rule->iifindex != fl->iif) && | 184 | if (rule->iifindex && (rule->iifindex != fl->iif)) |
185 | !(fl->flags & FLOWI_FLAG_MATCH_ANY_IIF)) | ||
186 | goto out; | 185 | goto out; |
187 | 186 | ||
188 | if (rule->oifindex && (rule->oifindex != fl->oif)) | 187 | if (rule->oifindex && (rule->oifindex != fl->oif)) |
diff --git a/net/core/filter.c b/net/core/filter.c index c1ee800bc080..ae21a0d3c4a2 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -589,23 +589,16 @@ int sk_chk_filter(struct sock_filter *filter, int flen) | |||
589 | EXPORT_SYMBOL(sk_chk_filter); | 589 | EXPORT_SYMBOL(sk_chk_filter); |
590 | 590 | ||
591 | /** | 591 | /** |
592 | * sk_filter_rcu_release - Release a socket filter by rcu_head | 592 | * sk_filter_release_rcu - Release a socket filter by rcu_head |
593 | * @rcu: rcu_head that contains the sk_filter to free | 593 | * @rcu: rcu_head that contains the sk_filter to free |
594 | */ | 594 | */ |
595 | static void sk_filter_rcu_release(struct rcu_head *rcu) | 595 | void sk_filter_release_rcu(struct rcu_head *rcu) |
596 | { | 596 | { |
597 | struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu); | 597 | struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu); |
598 | 598 | ||
599 | sk_filter_release(fp); | 599 | kfree(fp); |
600 | } | ||
601 | |||
602 | static void sk_filter_delayed_uncharge(struct sock *sk, struct sk_filter *fp) | ||
603 | { | ||
604 | unsigned int size = sk_filter_len(fp); | ||
605 | |||
606 | atomic_sub(size, &sk->sk_omem_alloc); | ||
607 | call_rcu_bh(&fp->rcu, sk_filter_rcu_release); | ||
608 | } | 600 | } |
601 | EXPORT_SYMBOL(sk_filter_release_rcu); | ||
609 | 602 | ||
610 | /** | 603 | /** |
611 | * sk_attach_filter - attach a socket filter | 604 | * sk_attach_filter - attach a socket filter |
@@ -649,7 +642,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) | |||
649 | rcu_assign_pointer(sk->sk_filter, fp); | 642 | rcu_assign_pointer(sk->sk_filter, fp); |
650 | 643 | ||
651 | if (old_fp) | 644 | if (old_fp) |
652 | sk_filter_delayed_uncharge(sk, old_fp); | 645 | sk_filter_uncharge(sk, old_fp); |
653 | return 0; | 646 | return 0; |
654 | } | 647 | } |
655 | EXPORT_SYMBOL_GPL(sk_attach_filter); | 648 | EXPORT_SYMBOL_GPL(sk_attach_filter); |
@@ -663,7 +656,7 @@ int sk_detach_filter(struct sock *sk) | |||
663 | sock_owned_by_user(sk)); | 656 | sock_owned_by_user(sk)); |
664 | if (filter) { | 657 | if (filter) { |
665 | rcu_assign_pointer(sk->sk_filter, NULL); | 658 | rcu_assign_pointer(sk->sk_filter, NULL); |
666 | sk_filter_delayed_uncharge(sk, filter); | 659 | sk_filter_uncharge(sk, filter); |
667 | ret = 0; | 660 | ret = 0; |
668 | } | 661 | } |
669 | return ret; | 662 | return ret; |
diff --git a/net/core/sock.c b/net/core/sock.c index fb6080111461..e5af8d5d5b50 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -1009,6 +1009,36 @@ static void sock_copy(struct sock *nsk, const struct sock *osk) | |||
1009 | #endif | 1009 | #endif |
1010 | } | 1010 | } |
1011 | 1011 | ||
1012 | /* | ||
1013 | * caches using SLAB_DESTROY_BY_RCU should let .next pointer from nulls nodes | ||
1014 | * un-modified. Special care is taken when initializing object to zero. | ||
1015 | */ | ||
1016 | static inline void sk_prot_clear_nulls(struct sock *sk, int size) | ||
1017 | { | ||
1018 | if (offsetof(struct sock, sk_node.next) != 0) | ||
1019 | memset(sk, 0, offsetof(struct sock, sk_node.next)); | ||
1020 | memset(&sk->sk_node.pprev, 0, | ||
1021 | size - offsetof(struct sock, sk_node.pprev)); | ||
1022 | } | ||
1023 | |||
1024 | void sk_prot_clear_portaddr_nulls(struct sock *sk, int size) | ||
1025 | { | ||
1026 | unsigned long nulls1, nulls2; | ||
1027 | |||
1028 | nulls1 = offsetof(struct sock, __sk_common.skc_node.next); | ||
1029 | nulls2 = offsetof(struct sock, __sk_common.skc_portaddr_node.next); | ||
1030 | if (nulls1 > nulls2) | ||
1031 | swap(nulls1, nulls2); | ||
1032 | |||
1033 | if (nulls1 != 0) | ||
1034 | memset((char *)sk, 0, nulls1); | ||
1035 | memset((char *)sk + nulls1 + sizeof(void *), 0, | ||
1036 | nulls2 - nulls1 - sizeof(void *)); | ||
1037 | memset((char *)sk + nulls2 + sizeof(void *), 0, | ||
1038 | size - nulls2 - sizeof(void *)); | ||
1039 | } | ||
1040 | EXPORT_SYMBOL(sk_prot_clear_portaddr_nulls); | ||
1041 | |||
1012 | static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, | 1042 | static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, |
1013 | int family) | 1043 | int family) |
1014 | { | 1044 | { |
@@ -1021,19 +1051,12 @@ static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, | |||
1021 | if (!sk) | 1051 | if (!sk) |
1022 | return sk; | 1052 | return sk; |
1023 | if (priority & __GFP_ZERO) { | 1053 | if (priority & __GFP_ZERO) { |
1024 | /* | 1054 | if (prot->clear_sk) |
1025 | * caches using SLAB_DESTROY_BY_RCU should let | 1055 | prot->clear_sk(sk, prot->obj_size); |
1026 | * sk_node.next un-modified. Special care is taken | 1056 | else |
1027 | * when initializing object to zero. | 1057 | sk_prot_clear_nulls(sk, prot->obj_size); |
1028 | */ | ||
1029 | if (offsetof(struct sock, sk_node.next) != 0) | ||
1030 | memset(sk, 0, offsetof(struct sock, sk_node.next)); | ||
1031 | memset(&sk->sk_node.pprev, 0, | ||
1032 | prot->obj_size - offsetof(struct sock, | ||
1033 | sk_node.pprev)); | ||
1034 | } | 1058 | } |
1035 | } | 1059 | } else |
1036 | else | ||
1037 | sk = kmalloc(prot->obj_size, priority); | 1060 | sk = kmalloc(prot->obj_size, priority); |
1038 | 1061 | ||
1039 | if (sk != NULL) { | 1062 | if (sk != NULL) { |
diff --git a/net/core/timestamping.c b/net/core/timestamping.c index 0ae6c22da85b..c19bb4ee405e 100644 --- a/net/core/timestamping.c +++ b/net/core/timestamping.c | |||
@@ -96,11 +96,13 @@ bool skb_defer_rx_timestamp(struct sk_buff *skb) | |||
96 | struct phy_device *phydev; | 96 | struct phy_device *phydev; |
97 | unsigned int type; | 97 | unsigned int type; |
98 | 98 | ||
99 | skb_push(skb, ETH_HLEN); | 99 | if (skb_headroom(skb) < ETH_HLEN) |
100 | return false; | ||
101 | __skb_push(skb, ETH_HLEN); | ||
100 | 102 | ||
101 | type = classify(skb); | 103 | type = classify(skb); |
102 | 104 | ||
103 | skb_pull(skb, ETH_HLEN); | 105 | __skb_pull(skb, ETH_HLEN); |
104 | 106 | ||
105 | switch (type) { | 107 | switch (type) { |
106 | case PTP_CLASS_V1_IPV4: | 108 | case PTP_CLASS_V1_IPV4: |
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index 13992e1d2726..15dcc1a586b4 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c | |||
@@ -661,8 +661,10 @@ static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void __user *arg) | |||
661 | err = 0; | 661 | err = 0; |
662 | switch (cmd) { | 662 | switch (cmd) { |
663 | case SIOCSIFADDR: | 663 | case SIOCSIFADDR: |
664 | if (!capable(CAP_NET_ADMIN)) | 664 | if (!capable(CAP_NET_ADMIN)) { |
665 | return -EPERM; | 665 | err = -EPERM; |
666 | break; | ||
667 | } | ||
666 | 668 | ||
667 | edev = dev->ec_ptr; | 669 | edev = dev->ec_ptr; |
668 | if (edev == NULL) { | 670 | if (edev == NULL) { |
@@ -849,9 +851,13 @@ static void aun_incoming(struct sk_buff *skb, struct aunhdr *ah, size_t len) | |||
849 | { | 851 | { |
850 | struct iphdr *ip = ip_hdr(skb); | 852 | struct iphdr *ip = ip_hdr(skb); |
851 | unsigned char stn = ntohl(ip->saddr) & 0xff; | 853 | unsigned char stn = ntohl(ip->saddr) & 0xff; |
854 | struct dst_entry *dst = skb_dst(skb); | ||
855 | struct ec_device *edev = NULL; | ||
852 | struct sock *sk = NULL; | 856 | struct sock *sk = NULL; |
853 | struct sk_buff *newskb; | 857 | struct sk_buff *newskb; |
854 | struct ec_device *edev = skb->dev->ec_ptr; | 858 | |
859 | if (dst) | ||
860 | edev = dst->dev->ec_ptr; | ||
855 | 861 | ||
856 | if (! edev) | 862 | if (! edev) |
857 | goto bad; | 863 | goto bad; |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index eb6f69a8f27a..c19c1f739fba 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -163,13 +163,19 @@ struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref) | |||
163 | .daddr = addr | 163 | .daddr = addr |
164 | } | 164 | } |
165 | }, | 165 | }, |
166 | .flags = FLOWI_FLAG_MATCH_ANY_IIF | ||
167 | }; | 166 | }; |
168 | struct fib_result res = { 0 }; | 167 | struct fib_result res = { 0 }; |
169 | struct net_device *dev = NULL; | 168 | struct net_device *dev = NULL; |
169 | struct fib_table *local_table; | ||
170 | |||
171 | #ifdef CONFIG_IP_MULTIPLE_TABLES | ||
172 | res.r = NULL; | ||
173 | #endif | ||
170 | 174 | ||
171 | rcu_read_lock(); | 175 | rcu_read_lock(); |
172 | if (fib_lookup(net, &fl, &res)) { | 176 | local_table = fib_get_table(net, RT_TABLE_LOCAL); |
177 | if (!local_table || | ||
178 | fib_table_lookup(local_table, &fl, &res, FIB_LOOKUP_NOREF)) { | ||
173 | rcu_read_unlock(); | 179 | rcu_read_unlock(); |
174 | return NULL; | 180 | return NULL; |
175 | } | 181 | } |
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c index 1b48eb1ed453..b14ec7d03b6e 100644 --- a/net/ipv4/proc.c +++ b/net/ipv4/proc.c | |||
@@ -253,6 +253,7 @@ static const struct snmp_mib snmp4_net_list[] = { | |||
253 | SNMP_MIB_ITEM("TCPMinTTLDrop", LINUX_MIB_TCPMINTTLDROP), | 253 | SNMP_MIB_ITEM("TCPMinTTLDrop", LINUX_MIB_TCPMINTTLDROP), |
254 | SNMP_MIB_ITEM("TCPDeferAcceptDrop", LINUX_MIB_TCPDEFERACCEPTDROP), | 254 | SNMP_MIB_ITEM("TCPDeferAcceptDrop", LINUX_MIB_TCPDEFERACCEPTDROP), |
255 | SNMP_MIB_ITEM("IPReversePathFilter", LINUX_MIB_IPRPFILTER), | 255 | SNMP_MIB_ITEM("IPReversePathFilter", LINUX_MIB_IPRPFILTER), |
256 | SNMP_MIB_ITEM("TCPTimeWaitOverflow", LINUX_MIB_TCPTIMEWAITOVERFLOW), | ||
256 | SNMP_MIB_SENTINEL | 257 | SNMP_MIB_SENTINEL |
257 | }; | 258 | }; |
258 | 259 | ||
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 987bf9adb318..93bfd95584f4 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -2585,9 +2585,10 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, | |||
2585 | goto out; | 2585 | goto out; |
2586 | 2586 | ||
2587 | /* RACE: Check return value of inet_select_addr instead. */ | 2587 | /* RACE: Check return value of inet_select_addr instead. */ |
2588 | if (rcu_dereference(dev_out->ip_ptr) == NULL) | 2588 | if (!(dev_out->flags & IFF_UP) || !__in_dev_get_rcu(dev_out)) { |
2589 | goto out; /* Wrong error code */ | 2589 | err = -ENETUNREACH; |
2590 | 2590 | goto out; | |
2591 | } | ||
2591 | if (ipv4_is_local_multicast(oldflp->fl4_dst) || | 2592 | if (ipv4_is_local_multicast(oldflp->fl4_dst) || |
2592 | ipv4_is_lbcast(oldflp->fl4_dst)) { | 2593 | ipv4_is_lbcast(oldflp->fl4_dst)) { |
2593 | if (!fl.fl4_src) | 2594 | if (!fl.fl4_src) |
@@ -2648,8 +2649,12 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, | |||
2648 | } | 2649 | } |
2649 | 2650 | ||
2650 | if (res.type == RTN_LOCAL) { | 2651 | if (res.type == RTN_LOCAL) { |
2651 | if (!fl.fl4_src) | 2652 | if (!fl.fl4_src) { |
2652 | fl.fl4_src = fl.fl4_dst; | 2653 | if (res.fi->fib_prefsrc) |
2654 | fl.fl4_src = res.fi->fib_prefsrc; | ||
2655 | else | ||
2656 | fl.fl4_src = fl.fl4_dst; | ||
2657 | } | ||
2653 | dev_out = net->loopback_dev; | 2658 | dev_out = net->loopback_dev; |
2654 | fl.oif = dev_out->ifindex; | 2659 | fl.oif = dev_out->ifindex; |
2655 | res.fi = NULL; | 2660 | res.fi = NULL; |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index e13da6de1fc7..d978bb2f748b 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -2030,7 +2030,7 @@ static void *listening_get_next(struct seq_file *seq, void *cur) | |||
2030 | get_req: | 2030 | get_req: |
2031 | req = icsk->icsk_accept_queue.listen_opt->syn_table[st->sbucket]; | 2031 | req = icsk->icsk_accept_queue.listen_opt->syn_table[st->sbucket]; |
2032 | } | 2032 | } |
2033 | sk = sk_next(st->syn_wait_sk); | 2033 | sk = sk_nulls_next(st->syn_wait_sk); |
2034 | st->state = TCP_SEQ_STATE_LISTENING; | 2034 | st->state = TCP_SEQ_STATE_LISTENING; |
2035 | read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock); | 2035 | read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock); |
2036 | } else { | 2036 | } else { |
@@ -2039,7 +2039,7 @@ get_req: | |||
2039 | if (reqsk_queue_len(&icsk->icsk_accept_queue)) | 2039 | if (reqsk_queue_len(&icsk->icsk_accept_queue)) |
2040 | goto start_req; | 2040 | goto start_req; |
2041 | read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock); | 2041 | read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock); |
2042 | sk = sk_next(sk); | 2042 | sk = sk_nulls_next(sk); |
2043 | } | 2043 | } |
2044 | get_sk: | 2044 | get_sk: |
2045 | sk_nulls_for_each_from(sk, node) { | 2045 | sk_nulls_for_each_from(sk, node) { |
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 43cf901d7659..a66735f75963 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
@@ -347,7 +347,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo) | |||
347 | * socket up. We've got bigger problems than | 347 | * socket up. We've got bigger problems than |
348 | * non-graceful socket closings. | 348 | * non-graceful socket closings. |
349 | */ | 349 | */ |
350 | LIMIT_NETDEBUG(KERN_INFO "TCP: time wait bucket table overflow\n"); | 350 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPTIMEWAITOVERFLOW); |
351 | } | 351 | } |
352 | 352 | ||
353 | tcp_update_metrics(sk); | 353 | tcp_update_metrics(sk); |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 05b1ecf36763..61c2463e2753 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -231,11 +231,10 @@ void tcp_select_initial_window(int __space, __u32 mss, | |||
231 | /* when initializing use the value from init_rcv_wnd | 231 | /* when initializing use the value from init_rcv_wnd |
232 | * rather than the default from above | 232 | * rather than the default from above |
233 | */ | 233 | */ |
234 | if (init_rcv_wnd && | 234 | if (init_rcv_wnd) |
235 | (*rcv_wnd > init_rcv_wnd * mss)) | 235 | *rcv_wnd = min(*rcv_wnd, init_rcv_wnd * mss); |
236 | *rcv_wnd = init_rcv_wnd * mss; | 236 | else |
237 | else if (*rcv_wnd > init_cwnd * mss) | 237 | *rcv_wnd = min(*rcv_wnd, init_cwnd * mss); |
238 | *rcv_wnd = init_cwnd * mss; | ||
239 | } | 238 | } |
240 | 239 | ||
241 | /* Set the clamp no higher than max representable value */ | 240 | /* Set the clamp no higher than max representable value */ |
@@ -386,27 +385,30 @@ struct tcp_out_options { | |||
386 | */ | 385 | */ |
387 | static u8 tcp_cookie_size_check(u8 desired) | 386 | static u8 tcp_cookie_size_check(u8 desired) |
388 | { | 387 | { |
389 | if (desired > 0) { | 388 | int cookie_size; |
389 | |||
390 | if (desired > 0) | ||
390 | /* previously specified */ | 391 | /* previously specified */ |
391 | return desired; | 392 | return desired; |
392 | } | 393 | |
393 | if (sysctl_tcp_cookie_size <= 0) { | 394 | cookie_size = ACCESS_ONCE(sysctl_tcp_cookie_size); |
395 | if (cookie_size <= 0) | ||
394 | /* no default specified */ | 396 | /* no default specified */ |
395 | return 0; | 397 | return 0; |
396 | } | 398 | |
397 | if (sysctl_tcp_cookie_size <= TCP_COOKIE_MIN) { | 399 | if (cookie_size <= TCP_COOKIE_MIN) |
398 | /* value too small, specify minimum */ | 400 | /* value too small, specify minimum */ |
399 | return TCP_COOKIE_MIN; | 401 | return TCP_COOKIE_MIN; |
400 | } | 402 | |
401 | if (sysctl_tcp_cookie_size >= TCP_COOKIE_MAX) { | 403 | if (cookie_size >= TCP_COOKIE_MAX) |
402 | /* value too large, specify maximum */ | 404 | /* value too large, specify maximum */ |
403 | return TCP_COOKIE_MAX; | 405 | return TCP_COOKIE_MAX; |
404 | } | 406 | |
405 | if (0x1 & sysctl_tcp_cookie_size) { | 407 | if (cookie_size & 1) |
406 | /* 8-bit multiple, illegal, fix it */ | 408 | /* 8-bit multiple, illegal, fix it */ |
407 | return (u8)(sysctl_tcp_cookie_size + 0x1); | 409 | cookie_size++; |
408 | } | 410 | |
409 | return (u8)sysctl_tcp_cookie_size; | 411 | return (u8)cookie_size; |
410 | } | 412 | } |
411 | 413 | ||
412 | /* Write previously computed TCP options to the packet. | 414 | /* Write previously computed TCP options to the packet. |
@@ -1513,6 +1515,7 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb) | |||
1513 | struct tcp_sock *tp = tcp_sk(sk); | 1515 | struct tcp_sock *tp = tcp_sk(sk); |
1514 | const struct inet_connection_sock *icsk = inet_csk(sk); | 1516 | const struct inet_connection_sock *icsk = inet_csk(sk); |
1515 | u32 send_win, cong_win, limit, in_flight; | 1517 | u32 send_win, cong_win, limit, in_flight; |
1518 | int win_divisor; | ||
1516 | 1519 | ||
1517 | if (TCP_SKB_CB(skb)->flags & TCPHDR_FIN) | 1520 | if (TCP_SKB_CB(skb)->flags & TCPHDR_FIN) |
1518 | goto send_now; | 1521 | goto send_now; |
@@ -1544,13 +1547,14 @@ static int tcp_tso_should_defer(struct sock *sk, struct sk_buff *skb) | |||
1544 | if ((skb != tcp_write_queue_tail(sk)) && (limit >= skb->len)) | 1547 | if ((skb != tcp_write_queue_tail(sk)) && (limit >= skb->len)) |
1545 | goto send_now; | 1548 | goto send_now; |
1546 | 1549 | ||
1547 | if (sysctl_tcp_tso_win_divisor) { | 1550 | win_divisor = ACCESS_ONCE(sysctl_tcp_tso_win_divisor); |
1551 | if (win_divisor) { | ||
1548 | u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); | 1552 | u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); |
1549 | 1553 | ||
1550 | /* If at least some fraction of a window is available, | 1554 | /* If at least some fraction of a window is available, |
1551 | * just use it. | 1555 | * just use it. |
1552 | */ | 1556 | */ |
1553 | chunk /= sysctl_tcp_tso_win_divisor; | 1557 | chunk /= win_divisor; |
1554 | if (limit >= chunk) | 1558 | if (limit >= chunk) |
1555 | goto send_now; | 1559 | goto send_now; |
1556 | } else { | 1560 | } else { |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 5e0a3a582a59..2d3ded4d0786 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -1899,6 +1899,7 @@ struct proto udp_prot = { | |||
1899 | .compat_setsockopt = compat_udp_setsockopt, | 1899 | .compat_setsockopt = compat_udp_setsockopt, |
1900 | .compat_getsockopt = compat_udp_getsockopt, | 1900 | .compat_getsockopt = compat_udp_getsockopt, |
1901 | #endif | 1901 | #endif |
1902 | .clear_sk = sk_prot_clear_portaddr_nulls, | ||
1902 | }; | 1903 | }; |
1903 | EXPORT_SYMBOL(udp_prot); | 1904 | EXPORT_SYMBOL(udp_prot); |
1904 | 1905 | ||
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c index ab76aa928fa9..aee9963f7f5a 100644 --- a/net/ipv4/udplite.c +++ b/net/ipv4/udplite.c | |||
@@ -57,6 +57,7 @@ struct proto udplite_prot = { | |||
57 | .compat_setsockopt = compat_udp_setsockopt, | 57 | .compat_setsockopt = compat_udp_setsockopt, |
58 | .compat_getsockopt = compat_udp_getsockopt, | 58 | .compat_getsockopt = compat_udp_getsockopt, |
59 | #endif | 59 | #endif |
60 | .clear_sk = sk_prot_clear_portaddr_nulls, | ||
60 | }; | 61 | }; |
61 | EXPORT_SYMBOL(udplite_prot); | 62 | EXPORT_SYMBOL(udplite_prot); |
62 | 63 | ||
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 23cc8e1ce8d4..848b35591042 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -2669,7 +2669,9 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
2669 | 2669 | ||
2670 | ASSERT_RTNL(); | 2670 | ASSERT_RTNL(); |
2671 | 2671 | ||
2672 | rt6_ifdown(net, dev); | 2672 | /* Flush routes if device is being removed or it is not loopback */ |
2673 | if (how || !(dev->flags & IFF_LOOPBACK)) | ||
2674 | rt6_ifdown(net, dev); | ||
2673 | neigh_ifdown(&nd_tbl, dev); | 2675 | neigh_ifdown(&nd_tbl, dev); |
2674 | 2676 | ||
2675 | idev = __in6_dev_get(dev); | 2677 | idev = __in6_dev_get(dev); |
@@ -4021,11 +4023,11 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev) | |||
4021 | kfree_skb(skb); | 4023 | kfree_skb(skb); |
4022 | goto errout; | 4024 | goto errout; |
4023 | } | 4025 | } |
4024 | rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); | 4026 | rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFINFO, NULL, GFP_ATOMIC); |
4025 | return; | 4027 | return; |
4026 | errout: | 4028 | errout: |
4027 | if (err < 0) | 4029 | if (err < 0) |
4028 | rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err); | 4030 | rtnl_set_sk_err(net, RTNLGRP_IPV6_IFINFO, err); |
4029 | } | 4031 | } |
4030 | 4032 | ||
4031 | static inline size_t inet6_prefix_nlmsg_size(void) | 4033 | static inline size_t inet6_prefix_nlmsg_size(void) |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 99157b4cd56e..94b5bf132b2e 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -56,7 +56,7 @@ | |||
56 | #include <net/checksum.h> | 56 | #include <net/checksum.h> |
57 | #include <linux/mroute6.h> | 57 | #include <linux/mroute6.h> |
58 | 58 | ||
59 | static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)); | 59 | int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)); |
60 | 60 | ||
61 | int __ip6_local_out(struct sk_buff *skb) | 61 | int __ip6_local_out(struct sk_buff *skb) |
62 | { | 62 | { |
@@ -145,14 +145,6 @@ static int ip6_finish_output2(struct sk_buff *skb) | |||
145 | return -EINVAL; | 145 | return -EINVAL; |
146 | } | 146 | } |
147 | 147 | ||
148 | static inline int ip6_skb_dst_mtu(struct sk_buff *skb) | ||
149 | { | ||
150 | struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL; | ||
151 | |||
152 | return (np && np->pmtudisc == IPV6_PMTUDISC_PROBE) ? | ||
153 | skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb)); | ||
154 | } | ||
155 | |||
156 | static int ip6_finish_output(struct sk_buff *skb) | 148 | static int ip6_finish_output(struct sk_buff *skb) |
157 | { | 149 | { |
158 | if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || | 150 | if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || |
@@ -601,7 +593,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) | |||
601 | return offset; | 593 | return offset; |
602 | } | 594 | } |
603 | 595 | ||
604 | static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | 596 | int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) |
605 | { | 597 | { |
606 | struct sk_buff *frag; | 598 | struct sk_buff *frag; |
607 | struct rt6_info *rt = (struct rt6_info*)skb_dst(skb); | 599 | struct rt6_info *rt = (struct rt6_info*)skb_dst(skb); |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 2a59610c2a58..70e891a20fb9 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -1175,6 +1175,8 @@ static void ip6_tnl_link_config(struct ip6_tnl *t) | |||
1175 | sizeof (struct ipv6hdr); | 1175 | sizeof (struct ipv6hdr); |
1176 | 1176 | ||
1177 | dev->mtu = rt->rt6i_dev->mtu - sizeof (struct ipv6hdr); | 1177 | dev->mtu = rt->rt6i_dev->mtu - sizeof (struct ipv6hdr); |
1178 | if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) | ||
1179 | dev->mtu-=8; | ||
1178 | 1180 | ||
1179 | if (dev->mtu < IPV6_MIN_MTU) | 1181 | if (dev->mtu < IPV6_MIN_MTU) |
1180 | dev->mtu = IPV6_MIN_MTU; | 1182 | dev->mtu = IPV6_MIN_MTU; |
@@ -1363,12 +1365,17 @@ static const struct net_device_ops ip6_tnl_netdev_ops = { | |||
1363 | 1365 | ||
1364 | static void ip6_tnl_dev_setup(struct net_device *dev) | 1366 | static void ip6_tnl_dev_setup(struct net_device *dev) |
1365 | { | 1367 | { |
1368 | struct ip6_tnl *t; | ||
1369 | |||
1366 | dev->netdev_ops = &ip6_tnl_netdev_ops; | 1370 | dev->netdev_ops = &ip6_tnl_netdev_ops; |
1367 | dev->destructor = ip6_dev_free; | 1371 | dev->destructor = ip6_dev_free; |
1368 | 1372 | ||
1369 | dev->type = ARPHRD_TUNNEL6; | 1373 | dev->type = ARPHRD_TUNNEL6; |
1370 | dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr); | 1374 | dev->hard_header_len = LL_MAX_HEADER + sizeof (struct ipv6hdr); |
1371 | dev->mtu = ETH_DATA_LEN - sizeof (struct ipv6hdr); | 1375 | dev->mtu = ETH_DATA_LEN - sizeof (struct ipv6hdr); |
1376 | t = netdev_priv(dev); | ||
1377 | if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) | ||
1378 | dev->mtu-=8; | ||
1372 | dev->flags |= IFF_NOARP; | 1379 | dev->flags |= IFF_NOARP; |
1373 | dev->addr_len = sizeof(struct in6_addr); | 1380 | dev->addr_len = sizeof(struct in6_addr); |
1374 | dev->features |= NETIF_F_NETNS_LOCAL; | 1381 | dev->features |= NETIF_F_NETNS_LOCAL; |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 96455ffb76fb..7659d6f16e6b 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -1565,11 +1565,16 @@ static void rt6_do_pmtu_disc(struct in6_addr *daddr, struct in6_addr *saddr, | |||
1565 | { | 1565 | { |
1566 | struct rt6_info *rt, *nrt; | 1566 | struct rt6_info *rt, *nrt; |
1567 | int allfrag = 0; | 1567 | int allfrag = 0; |
1568 | 1568 | again: | |
1569 | rt = rt6_lookup(net, daddr, saddr, ifindex, 0); | 1569 | rt = rt6_lookup(net, daddr, saddr, ifindex, 0); |
1570 | if (rt == NULL) | 1570 | if (rt == NULL) |
1571 | return; | 1571 | return; |
1572 | 1572 | ||
1573 | if (rt6_check_expired(rt)) { | ||
1574 | ip6_del_rt(rt); | ||
1575 | goto again; | ||
1576 | } | ||
1577 | |||
1573 | if (pmtu >= dst_mtu(&rt->dst)) | 1578 | if (pmtu >= dst_mtu(&rt->dst)) |
1574 | goto out; | 1579 | goto out; |
1575 | 1580 | ||
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index d6bfaec3bbbf..8c4d00c7cd2b 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -606,8 +606,9 @@ static int ipip6_rcv(struct sk_buff *skb) | |||
606 | return 0; | 606 | return 0; |
607 | } | 607 | } |
608 | 608 | ||
609 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_PORT_UNREACH, 0); | 609 | /* no tunnel matched, let upstream know, ipsec may handle it */ |
610 | rcu_read_unlock(); | 610 | rcu_read_unlock(); |
611 | return 1; | ||
611 | out: | 612 | out: |
612 | kfree_skb(skb); | 613 | kfree_skb(skb); |
613 | return 0; | 614 | return 0; |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 91def93bec85..cd6cb7c3e563 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
@@ -1477,6 +1477,7 @@ struct proto udpv6_prot = { | |||
1477 | .compat_setsockopt = compat_udpv6_setsockopt, | 1477 | .compat_setsockopt = compat_udpv6_setsockopt, |
1478 | .compat_getsockopt = compat_udpv6_getsockopt, | 1478 | .compat_getsockopt = compat_udpv6_getsockopt, |
1479 | #endif | 1479 | #endif |
1480 | .clear_sk = sk_prot_clear_portaddr_nulls, | ||
1480 | }; | 1481 | }; |
1481 | 1482 | ||
1482 | static struct inet_protosw udpv6_protosw = { | 1483 | static struct inet_protosw udpv6_protosw = { |
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c index 5f48fadc27f7..986c4de5292e 100644 --- a/net/ipv6/udplite.c +++ b/net/ipv6/udplite.c | |||
@@ -55,6 +55,7 @@ struct proto udplitev6_prot = { | |||
55 | .compat_setsockopt = compat_udpv6_setsockopt, | 55 | .compat_setsockopt = compat_udpv6_setsockopt, |
56 | .compat_getsockopt = compat_udpv6_getsockopt, | 56 | .compat_getsockopt = compat_udpv6_getsockopt, |
57 | #endif | 57 | #endif |
58 | .clear_sk = sk_prot_clear_portaddr_nulls, | ||
58 | }; | 59 | }; |
59 | 60 | ||
60 | static struct inet_protosw udplite6_protosw = { | 61 | static struct inet_protosw udplite6_protosw = { |
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index 6434bd5ce088..8e688b3de9ab 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/netfilter_ipv6.h> | 17 | #include <linux/netfilter_ipv6.h> |
18 | #include <net/dst.h> | 18 | #include <net/dst.h> |
19 | #include <net/ipv6.h> | 19 | #include <net/ipv6.h> |
20 | #include <net/ip6_route.h> | ||
20 | #include <net/xfrm.h> | 21 | #include <net/xfrm.h> |
21 | 22 | ||
22 | int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb, | 23 | int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb, |
@@ -88,8 +89,21 @@ static int xfrm6_output_finish(struct sk_buff *skb) | |||
88 | return xfrm_output(skb); | 89 | return xfrm_output(skb); |
89 | } | 90 | } |
90 | 91 | ||
92 | static int __xfrm6_output(struct sk_buff *skb) | ||
93 | { | ||
94 | struct dst_entry *dst = skb_dst(skb); | ||
95 | struct xfrm_state *x = dst->xfrm; | ||
96 | |||
97 | if ((x && x->props.mode == XFRM_MODE_TUNNEL) && | ||
98 | ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || | ||
99 | dst_allfrag(skb_dst(skb)))) { | ||
100 | return ip6_fragment(skb, xfrm6_output_finish); | ||
101 | } | ||
102 | return xfrm6_output_finish(skb); | ||
103 | } | ||
104 | |||
91 | int xfrm6_output(struct sk_buff *skb) | 105 | int xfrm6_output(struct sk_buff *skb) |
92 | { | 106 | { |
93 | return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL, | 107 | return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL, |
94 | skb_dst(skb)->dev, xfrm6_output_finish); | 108 | skb_dst(skb)->dev, __xfrm6_output); |
95 | } | 109 | } |
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index a6de3059746d..c9890e25cd4c 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c | |||
@@ -2280,6 +2280,16 @@ static int irda_getsockopt(struct socket *sock, int level, int optname, | |||
2280 | 2280 | ||
2281 | switch (optname) { | 2281 | switch (optname) { |
2282 | case IRLMP_ENUMDEVICES: | 2282 | case IRLMP_ENUMDEVICES: |
2283 | |||
2284 | /* Offset to first device entry */ | ||
2285 | offset = sizeof(struct irda_device_list) - | ||
2286 | sizeof(struct irda_device_info); | ||
2287 | |||
2288 | if (len < offset) { | ||
2289 | err = -EINVAL; | ||
2290 | goto out; | ||
2291 | } | ||
2292 | |||
2283 | /* Ask lmp for the current discovery log */ | 2293 | /* Ask lmp for the current discovery log */ |
2284 | discoveries = irlmp_get_discoveries(&list.len, self->mask.word, | 2294 | discoveries = irlmp_get_discoveries(&list.len, self->mask.word, |
2285 | self->nslots); | 2295 | self->nslots); |
@@ -2290,15 +2300,9 @@ static int irda_getsockopt(struct socket *sock, int level, int optname, | |||
2290 | } | 2300 | } |
2291 | 2301 | ||
2292 | /* Write total list length back to client */ | 2302 | /* Write total list length back to client */ |
2293 | if (copy_to_user(optval, &list, | 2303 | if (copy_to_user(optval, &list, offset)) |
2294 | sizeof(struct irda_device_list) - | ||
2295 | sizeof(struct irda_device_info))) | ||
2296 | err = -EFAULT; | 2304 | err = -EFAULT; |
2297 | 2305 | ||
2298 | /* Offset to first device entry */ | ||
2299 | offset = sizeof(struct irda_device_list) - | ||
2300 | sizeof(struct irda_device_info); | ||
2301 | |||
2302 | /* Copy the list itself - watch for overflow */ | 2306 | /* Copy the list itself - watch for overflow */ |
2303 | if (list.len > 2048) { | 2307 | if (list.len > 2048) { |
2304 | err = -EINVAL; | 2308 | err = -EINVAL; |
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c index 0bf6a59545ab..522e219f3558 100644 --- a/net/l2tp/l2tp_ip.c +++ b/net/l2tp/l2tp_ip.c | |||
@@ -674,4 +674,8 @@ MODULE_LICENSE("GPL"); | |||
674 | MODULE_AUTHOR("James Chapman <jchapman@katalix.com>"); | 674 | MODULE_AUTHOR("James Chapman <jchapman@katalix.com>"); |
675 | MODULE_DESCRIPTION("L2TP over IP"); | 675 | MODULE_DESCRIPTION("L2TP over IP"); |
676 | MODULE_VERSION("1.0"); | 676 | MODULE_VERSION("1.0"); |
677 | MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, SOCK_DGRAM, IPPROTO_L2TP); | 677 | |
678 | /* Use the value of SOCK_DGRAM (2) directory, because __stringify does't like | ||
679 | * enums | ||
680 | */ | ||
681 | MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 2, IPPROTO_L2TP); | ||
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index 582612998211..e35dbe55f520 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c | |||
@@ -317,8 +317,9 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) | |||
317 | goto out; | 317 | goto out; |
318 | rc = -ENODEV; | 318 | rc = -ENODEV; |
319 | rtnl_lock(); | 319 | rtnl_lock(); |
320 | rcu_read_lock(); | ||
320 | if (sk->sk_bound_dev_if) { | 321 | if (sk->sk_bound_dev_if) { |
321 | llc->dev = dev_get_by_index(&init_net, sk->sk_bound_dev_if); | 322 | llc->dev = dev_get_by_index_rcu(&init_net, sk->sk_bound_dev_if); |
322 | if (llc->dev) { | 323 | if (llc->dev) { |
323 | if (!addr->sllc_arphrd) | 324 | if (!addr->sllc_arphrd) |
324 | addr->sllc_arphrd = llc->dev->type; | 325 | addr->sllc_arphrd = llc->dev->type; |
@@ -329,13 +330,13 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) | |||
329 | !llc_mac_match(addr->sllc_mac, | 330 | !llc_mac_match(addr->sllc_mac, |
330 | llc->dev->dev_addr)) { | 331 | llc->dev->dev_addr)) { |
331 | rc = -EINVAL; | 332 | rc = -EINVAL; |
332 | dev_put(llc->dev); | ||
333 | llc->dev = NULL; | 333 | llc->dev = NULL; |
334 | } | 334 | } |
335 | } | 335 | } |
336 | } else | 336 | } else |
337 | llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd, | 337 | llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd, |
338 | addr->sllc_mac); | 338 | addr->sllc_mac); |
339 | rcu_read_unlock(); | ||
339 | rtnl_unlock(); | 340 | rtnl_unlock(); |
340 | if (!llc->dev) | 341 | if (!llc->dev) |
341 | goto out; | 342 | goto out; |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 239c4836a946..077a93dd1671 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -780,6 +780,9 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
780 | 780 | ||
781 | mutex_lock(&sdata->u.ibss.mtx); | 781 | mutex_lock(&sdata->u.ibss.mtx); |
782 | 782 | ||
783 | if (!sdata->u.ibss.ssid_len) | ||
784 | goto mgmt_out; /* not ready to merge yet */ | ||
785 | |||
783 | switch (fc & IEEE80211_FCTL_STYPE) { | 786 | switch (fc & IEEE80211_FCTL_STYPE) { |
784 | case IEEE80211_STYPE_PROBE_REQ: | 787 | case IEEE80211_STYPE_PROBE_REQ: |
785 | ieee80211_rx_mgmt_probe_req(sdata, mgmt, skb->len); | 788 | ieee80211_rx_mgmt_probe_req(sdata, mgmt, skb->len); |
@@ -797,6 +800,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
797 | break; | 800 | break; |
798 | } | 801 | } |
799 | 802 | ||
803 | mgmt_out: | ||
800 | mutex_unlock(&sdata->u.ibss.mtx); | 804 | mutex_unlock(&sdata->u.ibss.mtx); |
801 | } | 805 | } |
802 | 806 | ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 902b03ee8f60..b01e467b76c6 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1788,9 +1788,11 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1788 | 1788 | ||
1789 | fwd_skb = skb_copy(skb, GFP_ATOMIC); | 1789 | fwd_skb = skb_copy(skb, GFP_ATOMIC); |
1790 | 1790 | ||
1791 | if (!fwd_skb && net_ratelimit()) | 1791 | if (!fwd_skb && net_ratelimit()) { |
1792 | printk(KERN_DEBUG "%s: failed to clone mesh frame\n", | 1792 | printk(KERN_DEBUG "%s: failed to clone mesh frame\n", |
1793 | sdata->name); | 1793 | sdata->name); |
1794 | goto out; | ||
1795 | } | ||
1794 | 1796 | ||
1795 | fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; | 1797 | fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; |
1796 | memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); | 1798 | memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); |
@@ -1828,6 +1830,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1828 | } | 1830 | } |
1829 | } | 1831 | } |
1830 | 1832 | ||
1833 | out: | ||
1831 | if (is_multicast_ether_addr(hdr->addr1) || | 1834 | if (is_multicast_ether_addr(hdr->addr1) || |
1832 | sdata->dev->flags & IFF_PROMISC) | 1835 | sdata->dev->flags & IFF_PROMISC) |
1833 | return RX_CONTINUE; | 1836 | return RX_CONTINUE; |
@@ -2247,6 +2250,10 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx) | |||
2247 | break; | 2250 | break; |
2248 | case cpu_to_le16(IEEE80211_STYPE_DEAUTH): | 2251 | case cpu_to_le16(IEEE80211_STYPE_DEAUTH): |
2249 | case cpu_to_le16(IEEE80211_STYPE_DISASSOC): | 2252 | case cpu_to_le16(IEEE80211_STYPE_DISASSOC): |
2253 | if (is_multicast_ether_addr(mgmt->da) && | ||
2254 | !is_broadcast_ether_addr(mgmt->da)) | ||
2255 | return RX_DROP_MONITOR; | ||
2256 | |||
2250 | /* process only for station */ | 2257 | /* process only for station */ |
2251 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | 2258 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
2252 | return RX_DROP_MONITOR; | 2259 | return RX_DROP_MONITOR; |
@@ -2741,6 +2748,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2741 | 2748 | ||
2742 | if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) | 2749 | if (ieee80211_prepare_and_rx_handle(&rx, skb, true)) |
2743 | return; | 2750 | return; |
2751 | goto out; | ||
2744 | } | 2752 | } |
2745 | } | 2753 | } |
2746 | 2754 | ||
@@ -2780,6 +2788,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2780 | return; | 2788 | return; |
2781 | } | 2789 | } |
2782 | 2790 | ||
2791 | out: | ||
2783 | dev_kfree_skb(skb); | 2792 | dev_kfree_skb(skb); |
2784 | } | 2793 | } |
2785 | 2794 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 96c594309506..7a637b80a62e 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1587,7 +1587,12 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1587 | list) { | 1587 | list) { |
1588 | if (!ieee80211_sdata_running(tmp_sdata)) | 1588 | if (!ieee80211_sdata_running(tmp_sdata)) |
1589 | continue; | 1589 | continue; |
1590 | if (tmp_sdata->vif.type != NL80211_IFTYPE_AP) | 1590 | if (tmp_sdata->vif.type == |
1591 | NL80211_IFTYPE_MONITOR || | ||
1592 | tmp_sdata->vif.type == | ||
1593 | NL80211_IFTYPE_AP_VLAN || | ||
1594 | tmp_sdata->vif.type == | ||
1595 | NL80211_IFTYPE_WDS) | ||
1591 | continue; | 1596 | continue; |
1592 | if (compare_ether_addr(tmp_sdata->vif.addr, | 1597 | if (compare_ether_addr(tmp_sdata->vif.addr, |
1593 | hdr->addr2) == 0) { | 1598 | hdr->addr2) == 0) { |
@@ -1732,15 +1737,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1732 | int nh_pos, h_pos; | 1737 | int nh_pos, h_pos; |
1733 | struct sta_info *sta = NULL; | 1738 | struct sta_info *sta = NULL; |
1734 | u32 sta_flags = 0; | 1739 | u32 sta_flags = 0; |
1740 | struct sk_buff *tmp_skb; | ||
1735 | 1741 | ||
1736 | if (unlikely(skb->len < ETH_HLEN)) { | 1742 | if (unlikely(skb->len < ETH_HLEN)) { |
1737 | ret = NETDEV_TX_OK; | 1743 | ret = NETDEV_TX_OK; |
1738 | goto fail; | 1744 | goto fail; |
1739 | } | 1745 | } |
1740 | 1746 | ||
1741 | nh_pos = skb_network_header(skb) - skb->data; | ||
1742 | h_pos = skb_transport_header(skb) - skb->data; | ||
1743 | |||
1744 | /* convert Ethernet header to proper 802.11 header (based on | 1747 | /* convert Ethernet header to proper 802.11 header (based on |
1745 | * operation mode) */ | 1748 | * operation mode) */ |
1746 | ethertype = (skb->data[12] << 8) | skb->data[13]; | 1749 | ethertype = (skb->data[12] << 8) | skb->data[13]; |
@@ -1913,6 +1916,20 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1913 | goto fail; | 1916 | goto fail; |
1914 | } | 1917 | } |
1915 | 1918 | ||
1919 | /* | ||
1920 | * If the skb is shared we need to obtain our own copy. | ||
1921 | */ | ||
1922 | if (skb_shared(skb)) { | ||
1923 | tmp_skb = skb; | ||
1924 | skb = skb_copy(skb, GFP_ATOMIC); | ||
1925 | kfree_skb(tmp_skb); | ||
1926 | |||
1927 | if (!skb) { | ||
1928 | ret = NETDEV_TX_OK; | ||
1929 | goto fail; | ||
1930 | } | ||
1931 | } | ||
1932 | |||
1916 | hdr.frame_control = fc; | 1933 | hdr.frame_control = fc; |
1917 | hdr.duration_id = 0; | 1934 | hdr.duration_id = 0; |
1918 | hdr.seq_ctrl = 0; | 1935 | hdr.seq_ctrl = 0; |
@@ -1931,6 +1948,9 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1931 | encaps_len = 0; | 1948 | encaps_len = 0; |
1932 | } | 1949 | } |
1933 | 1950 | ||
1951 | nh_pos = skb_network_header(skb) - skb->data; | ||
1952 | h_pos = skb_transport_header(skb) - skb->data; | ||
1953 | |||
1934 | skb_pull(skb, skip_header_bytes); | 1954 | skb_pull(skb, skip_header_bytes); |
1935 | nh_pos -= skip_header_bytes; | 1955 | nh_pos -= skip_header_bytes; |
1936 | h_pos -= skip_header_bytes; | 1956 | h_pos -= skip_header_bytes; |
diff --git a/net/mac80211/work.c b/net/mac80211/work.c index ae344d1ba056..146097cb43a7 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c | |||
@@ -1051,11 +1051,13 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata) | |||
1051 | { | 1051 | { |
1052 | struct ieee80211_local *local = sdata->local; | 1052 | struct ieee80211_local *local = sdata->local; |
1053 | struct ieee80211_work *wk; | 1053 | struct ieee80211_work *wk; |
1054 | bool cleanup = false; | ||
1054 | 1055 | ||
1055 | mutex_lock(&local->mtx); | 1056 | mutex_lock(&local->mtx); |
1056 | list_for_each_entry(wk, &local->work_list, list) { | 1057 | list_for_each_entry(wk, &local->work_list, list) { |
1057 | if (wk->sdata != sdata) | 1058 | if (wk->sdata != sdata) |
1058 | continue; | 1059 | continue; |
1060 | cleanup = true; | ||
1059 | wk->type = IEEE80211_WORK_ABORT; | 1061 | wk->type = IEEE80211_WORK_ABORT; |
1060 | wk->started = true; | 1062 | wk->started = true; |
1061 | wk->timeout = jiffies; | 1063 | wk->timeout = jiffies; |
@@ -1063,7 +1065,8 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata) | |||
1063 | mutex_unlock(&local->mtx); | 1065 | mutex_unlock(&local->mtx); |
1064 | 1066 | ||
1065 | /* run cleanups etc. */ | 1067 | /* run cleanups etc. */ |
1066 | ieee80211_work_work(&local->work_work); | 1068 | if (cleanup) |
1069 | ieee80211_work_work(&local->work_work); | ||
1067 | 1070 | ||
1068 | mutex_lock(&local->mtx); | 1071 | mutex_lock(&local->mtx); |
1069 | list_for_each_entry(wk, &local->work_list, list) { | 1072 | list_for_each_entry(wk, &local->work_list, list) { |
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 3cf478d012dd..7150705f1d0b 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c | |||
@@ -270,7 +270,6 @@ static unsigned int sfq_drop(struct Qdisc *sch) | |||
270 | /* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */ | 270 | /* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */ |
271 | d = q->next[q->tail]; | 271 | d = q->next[q->tail]; |
272 | q->next[q->tail] = q->next[d]; | 272 | q->next[q->tail] = q->next[d]; |
273 | q->allot[q->next[d]] += q->quantum; | ||
274 | skb = q->qs[d].prev; | 273 | skb = q->qs[d].prev; |
275 | len = qdisc_pkt_len(skb); | 274 | len = qdisc_pkt_len(skb); |
276 | __skb_unlink(skb, &q->qs[d]); | 275 | __skb_unlink(skb, &q->qs[d]); |
@@ -321,14 +320,13 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
321 | sfq_inc(q, x); | 320 | sfq_inc(q, x); |
322 | if (q->qs[x].qlen == 1) { /* The flow is new */ | 321 | if (q->qs[x].qlen == 1) { /* The flow is new */ |
323 | if (q->tail == SFQ_DEPTH) { /* It is the first flow */ | 322 | if (q->tail == SFQ_DEPTH) { /* It is the first flow */ |
324 | q->tail = x; | ||
325 | q->next[x] = x; | 323 | q->next[x] = x; |
326 | q->allot[x] = q->quantum; | ||
327 | } else { | 324 | } else { |
328 | q->next[x] = q->next[q->tail]; | 325 | q->next[x] = q->next[q->tail]; |
329 | q->next[q->tail] = x; | 326 | q->next[q->tail] = x; |
330 | q->tail = x; | ||
331 | } | 327 | } |
328 | q->tail = x; | ||
329 | q->allot[x] = q->quantum; | ||
332 | } | 330 | } |
333 | if (++sch->q.qlen <= q->limit) { | 331 | if (++sch->q.qlen <= q->limit) { |
334 | sch->bstats.bytes += qdisc_pkt_len(skb); | 332 | sch->bstats.bytes += qdisc_pkt_len(skb); |
@@ -359,13 +357,13 @@ sfq_dequeue(struct Qdisc *sch) | |||
359 | { | 357 | { |
360 | struct sfq_sched_data *q = qdisc_priv(sch); | 358 | struct sfq_sched_data *q = qdisc_priv(sch); |
361 | struct sk_buff *skb; | 359 | struct sk_buff *skb; |
362 | sfq_index a, old_a; | 360 | sfq_index a, next_a; |
363 | 361 | ||
364 | /* No active slots */ | 362 | /* No active slots */ |
365 | if (q->tail == SFQ_DEPTH) | 363 | if (q->tail == SFQ_DEPTH) |
366 | return NULL; | 364 | return NULL; |
367 | 365 | ||
368 | a = old_a = q->next[q->tail]; | 366 | a = q->next[q->tail]; |
369 | 367 | ||
370 | /* Grab packet */ | 368 | /* Grab packet */ |
371 | skb = __skb_dequeue(&q->qs[a]); | 369 | skb = __skb_dequeue(&q->qs[a]); |
@@ -376,17 +374,15 @@ sfq_dequeue(struct Qdisc *sch) | |||
376 | /* Is the slot empty? */ | 374 | /* Is the slot empty? */ |
377 | if (q->qs[a].qlen == 0) { | 375 | if (q->qs[a].qlen == 0) { |
378 | q->ht[q->hash[a]] = SFQ_DEPTH; | 376 | q->ht[q->hash[a]] = SFQ_DEPTH; |
379 | a = q->next[a]; | 377 | next_a = q->next[a]; |
380 | if (a == old_a) { | 378 | if (a == next_a) { |
381 | q->tail = SFQ_DEPTH; | 379 | q->tail = SFQ_DEPTH; |
382 | return skb; | 380 | return skb; |
383 | } | 381 | } |
384 | q->next[q->tail] = a; | 382 | q->next[q->tail] = next_a; |
385 | q->allot[a] += q->quantum; | ||
386 | } else if ((q->allot[a] -= qdisc_pkt_len(skb)) <= 0) { | 383 | } else if ((q->allot[a] -= qdisc_pkt_len(skb)) <= 0) { |
387 | q->tail = a; | ||
388 | a = q->next[a]; | ||
389 | q->allot[a] += q->quantum; | 384 | q->allot[a] += q->quantum; |
385 | q->tail = a; | ||
390 | } | 386 | } |
391 | return skb; | 387 | return skb; |
392 | } | 388 | } |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 6bd554323a34..fff0926b1111 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -2932,6 +2932,7 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva | |||
2932 | struct sctp_association *asoc = NULL; | 2932 | struct sctp_association *asoc = NULL; |
2933 | struct sctp_setpeerprim prim; | 2933 | struct sctp_setpeerprim prim; |
2934 | struct sctp_chunk *chunk; | 2934 | struct sctp_chunk *chunk; |
2935 | struct sctp_af *af; | ||
2935 | int err; | 2936 | int err; |
2936 | 2937 | ||
2937 | sp = sctp_sk(sk); | 2938 | sp = sctp_sk(sk); |
@@ -2959,6 +2960,13 @@ static int sctp_setsockopt_peer_primary_addr(struct sock *sk, char __user *optva | |||
2959 | if (!sctp_state(asoc, ESTABLISHED)) | 2960 | if (!sctp_state(asoc, ESTABLISHED)) |
2960 | return -ENOTCONN; | 2961 | return -ENOTCONN; |
2961 | 2962 | ||
2963 | af = sctp_get_af_specific(prim.sspp_addr.ss_family); | ||
2964 | if (!af) | ||
2965 | return -EINVAL; | ||
2966 | |||
2967 | if (!af->addr_valid((union sctp_addr *)&prim.sspp_addr, sp, NULL)) | ||
2968 | return -EADDRNOTAVAIL; | ||
2969 | |||
2962 | if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr)) | 2970 | if (!sctp_assoc_lookup_laddr(asoc, (union sctp_addr *)&prim.sspp_addr)) |
2963 | return -EADDRNOTAVAIL; | 2971 | return -EADDRNOTAVAIL; |
2964 | 2972 | ||
@@ -5045,7 +5053,7 @@ static int sctp_getsockopt_partial_delivery_point(struct sock *sk, int len, | |||
5045 | if (copy_to_user(optval, &val, len)) | 5053 | if (copy_to_user(optval, &val, len)) |
5046 | return -EFAULT; | 5054 | return -EFAULT; |
5047 | 5055 | ||
5048 | return -ENOTSUPP; | 5056 | return 0; |
5049 | } | 5057 | } |
5050 | 5058 | ||
5051 | /* | 5059 | /* |
diff --git a/net/socket.c b/net/socket.c index 3ca2fd9e3720..088fb3fd45e0 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -732,6 +732,21 @@ static int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg, | |||
732 | return ret; | 732 | return ret; |
733 | } | 733 | } |
734 | 734 | ||
735 | /** | ||
736 | * kernel_recvmsg - Receive a message from a socket (kernel space) | ||
737 | * @sock: The socket to receive the message from | ||
738 | * @msg: Received message | ||
739 | * @vec: Input s/g array for message data | ||
740 | * @num: Size of input s/g array | ||
741 | * @size: Number of bytes to read | ||
742 | * @flags: Message flags (MSG_DONTWAIT, etc...) | ||
743 | * | ||
744 | * On return the msg structure contains the scatter/gather array passed in the | ||
745 | * vec argument. The array is modified so that it consists of the unfilled | ||
746 | * portion of the original array. | ||
747 | * | ||
748 | * The returned value is the total number of bytes received, or an error. | ||
749 | */ | ||
735 | int kernel_recvmsg(struct socket *sock, struct msghdr *msg, | 750 | int kernel_recvmsg(struct socket *sock, struct msghdr *msg, |
736 | struct kvec *vec, size_t num, size_t size, int flags) | 751 | struct kvec *vec, size_t num, size_t size, int flags) |
737 | { | 752 | { |
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index ea2ff78dcf7b..3f2c5559ca1a 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
@@ -212,6 +212,7 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name, | |||
212 | spin_lock(&svc_xprt_class_lock); | 212 | spin_lock(&svc_xprt_class_lock); |
213 | list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) { | 213 | list_for_each_entry(xcl, &svc_xprt_class_list, xcl_list) { |
214 | struct svc_xprt *newxprt; | 214 | struct svc_xprt *newxprt; |
215 | unsigned short newport; | ||
215 | 216 | ||
216 | if (strcmp(xprt_name, xcl->xcl_name)) | 217 | if (strcmp(xprt_name, xcl->xcl_name)) |
217 | continue; | 218 | continue; |
@@ -230,8 +231,9 @@ int svc_create_xprt(struct svc_serv *serv, const char *xprt_name, | |||
230 | spin_lock_bh(&serv->sv_lock); | 231 | spin_lock_bh(&serv->sv_lock); |
231 | list_add(&newxprt->xpt_list, &serv->sv_permsocks); | 232 | list_add(&newxprt->xpt_list, &serv->sv_permsocks); |
232 | spin_unlock_bh(&serv->sv_lock); | 233 | spin_unlock_bh(&serv->sv_lock); |
234 | newport = svc_xprt_local_port(newxprt); | ||
233 | clear_bit(XPT_BUSY, &newxprt->xpt_flags); | 235 | clear_bit(XPT_BUSY, &newxprt->xpt_flags); |
234 | return svc_xprt_local_port(newxprt); | 236 | return newport; |
235 | } | 237 | } |
236 | err: | 238 | err: |
237 | spin_unlock(&svc_xprt_class_lock); | 239 | spin_unlock(&svc_xprt_class_lock); |
@@ -425,8 +427,13 @@ void svc_xprt_received(struct svc_xprt *xprt) | |||
425 | { | 427 | { |
426 | BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags)); | 428 | BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags)); |
427 | xprt->xpt_pool = NULL; | 429 | xprt->xpt_pool = NULL; |
430 | /* As soon as we clear busy, the xprt could be closed and | ||
431 | * 'put', so we need a reference to call svc_xprt_enqueue with: | ||
432 | */ | ||
433 | svc_xprt_get(xprt); | ||
428 | clear_bit(XPT_BUSY, &xprt->xpt_flags); | 434 | clear_bit(XPT_BUSY, &xprt->xpt_flags); |
429 | svc_xprt_enqueue(xprt); | 435 | svc_xprt_enqueue(xprt); |
436 | svc_xprt_put(xprt); | ||
430 | } | 437 | } |
431 | EXPORT_SYMBOL_GPL(svc_xprt_received); | 438 | EXPORT_SYMBOL_GPL(svc_xprt_received); |
432 | 439 | ||
diff --git a/net/x25/x25_link.c b/net/x25/x25_link.c index 73e7b954ad28..b25c6463c3e9 100644 --- a/net/x25/x25_link.c +++ b/net/x25/x25_link.c | |||
@@ -394,6 +394,7 @@ void __exit x25_link_free(void) | |||
394 | list_for_each_safe(entry, tmp, &x25_neigh_list) { | 394 | list_for_each_safe(entry, tmp, &x25_neigh_list) { |
395 | nb = list_entry(entry, struct x25_neigh, node); | 395 | nb = list_entry(entry, struct x25_neigh, node); |
396 | __x25_remove_neigh(nb); | 396 | __x25_remove_neigh(nb); |
397 | dev_put(nb->dev); | ||
397 | } | 398 | } |
398 | write_unlock_bh(&x25_neigh_list_lock); | 399 | write_unlock_bh(&x25_neigh_list_lock); |
399 | } | 400 | } |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index eb96ce52f178..220ebc05c7af 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -1268,7 +1268,7 @@ struct xfrm_state * xfrm_state_migrate(struct xfrm_state *x, | |||
1268 | 1268 | ||
1269 | return xc; | 1269 | return xc; |
1270 | error: | 1270 | error: |
1271 | kfree(xc); | 1271 | xfrm_state_put(xc); |
1272 | return NULL; | 1272 | return NULL; |
1273 | } | 1273 | } |
1274 | EXPORT_SYMBOL(xfrm_state_migrate); | 1274 | EXPORT_SYMBOL(xfrm_state_migrate); |
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index b9d9aa18e6d6..5f77dcb8977e 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c | |||
@@ -140,6 +140,20 @@ struct property *menu_add_prop(enum prop_type type, char *prompt, struct expr *e | |||
140 | } | 140 | } |
141 | if (current_entry->prompt && current_entry != &rootmenu) | 141 | if (current_entry->prompt && current_entry != &rootmenu) |
142 | prop_warn(prop, "prompt redefined"); | 142 | prop_warn(prop, "prompt redefined"); |
143 | |||
144 | /* Apply all upper menus' visibilities to actual prompts. */ | ||
145 | if(type == P_PROMPT) { | ||
146 | struct menu *menu = current_entry; | ||
147 | |||
148 | while ((menu = menu->parent) != NULL) { | ||
149 | if (!menu->visibility) | ||
150 | continue; | ||
151 | prop->visible.expr | ||
152 | = expr_alloc_and(prop->visible.expr, | ||
153 | menu->visibility); | ||
154 | } | ||
155 | } | ||
156 | |||
143 | current_entry->prompt = prop; | 157 | current_entry->prompt = prop; |
144 | } | 158 | } |
145 | prop->text = prompt; | 159 | prop->text = prompt; |
diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h index 58e933a20544..39667174971d 100644 --- a/scripts/recordmcount.h +++ b/scripts/recordmcount.h | |||
@@ -119,7 +119,7 @@ static uint_t (*Elf_r_sym)(Elf_Rel const *rp) = fn_ELF_R_SYM; | |||
119 | 119 | ||
120 | static void fn_ELF_R_INFO(Elf_Rel *const rp, unsigned sym, unsigned type) | 120 | static void fn_ELF_R_INFO(Elf_Rel *const rp, unsigned sym, unsigned type) |
121 | { | 121 | { |
122 | rp->r_info = ELF_R_INFO(sym, type); | 122 | rp->r_info = _w(ELF_R_INFO(sym, type)); |
123 | } | 123 | } |
124 | static void (*Elf_r_info)(Elf_Rel *const rp, unsigned sym, unsigned type) = fn_ELF_R_INFO; | 124 | static void (*Elf_r_info)(Elf_Rel *const rp, unsigned sym, unsigned type) = fn_ELF_R_INFO; |
125 | 125 | ||
diff --git a/scripts/tags.sh b/scripts/tags.sh index 8509bb512935..bbbe584d4494 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh | |||
@@ -125,7 +125,9 @@ exuberant() | |||
125 | -I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \ | 125 | -I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \ |
126 | --extra=+f --c-kinds=-px \ | 126 | --extra=+f --c-kinds=-px \ |
127 | --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \ | 127 | --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \ |
128 | --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' | 128 | --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' \ |
129 | --regex-c++='/^TRACE_EVENT\(([^,)]*).*/trace_\1/' \ | ||
130 | --regex-c++='/^DEFINE_EVENT\(([^,)]*).*/trace_\1/' | ||
129 | 131 | ||
130 | all_kconfigs | xargs $1 -a \ | 132 | all_kconfigs | xargs $1 -a \ |
131 | --langdef=kconfig --language-force=kconfig \ | 133 | --langdef=kconfig --language-force=kconfig \ |
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index aef8c0a923ab..d661afbe474c 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c | |||
@@ -253,6 +253,8 @@ static int ima_lsm_rule_init(struct ima_measure_rule_entry *entry, | |||
253 | result = security_filter_rule_init(entry->lsm[lsm_rule].type, | 253 | result = security_filter_rule_init(entry->lsm[lsm_rule].type, |
254 | Audit_equal, args, | 254 | Audit_equal, args, |
255 | &entry->lsm[lsm_rule].rule); | 255 | &entry->lsm[lsm_rule].rule); |
256 | if (!entry->lsm[lsm_rule].rule) | ||
257 | return -EINVAL; | ||
256 | return result; | 258 | return result; |
257 | } | 259 | } |
258 | 260 | ||
diff --git a/security/keys/request_key.c b/security/keys/request_key.c index 0088dd8bf68a..0ea52d25a6bd 100644 --- a/security/keys/request_key.c +++ b/security/keys/request_key.c | |||
@@ -403,7 +403,6 @@ link_check_failed: | |||
403 | return ret; | 403 | return ret; |
404 | 404 | ||
405 | link_prealloc_failed: | 405 | link_prealloc_failed: |
406 | up_write(&dest_keyring->sem); | ||
407 | mutex_unlock(&user->cons_lock); | 406 | mutex_unlock(&user->cons_lock); |
408 | kleave(" = %d [prelink]", ret); | 407 | kleave(" = %d [prelink]", ret); |
409 | return ret; | 408 | return ret; |
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index b75db8e9cc0f..11446a1506da 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -1070,8 +1070,10 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond, | |||
1070 | struct snd_pcm_hw_rule *new; | 1070 | struct snd_pcm_hw_rule *new; |
1071 | unsigned int new_rules = constrs->rules_all + 16; | 1071 | unsigned int new_rules = constrs->rules_all + 16; |
1072 | new = kcalloc(new_rules, sizeof(*c), GFP_KERNEL); | 1072 | new = kcalloc(new_rules, sizeof(*c), GFP_KERNEL); |
1073 | if (!new) | 1073 | if (!new) { |
1074 | va_end(args); | ||
1074 | return -ENOMEM; | 1075 | return -ENOMEM; |
1076 | } | ||
1075 | if (constrs->rules) { | 1077 | if (constrs->rules) { |
1076 | memcpy(new, constrs->rules, | 1078 | memcpy(new, constrs->rules, |
1077 | constrs->rules_num * sizeof(*c)); | 1079 | constrs->rules_num * sizeof(*c)); |
@@ -1087,8 +1089,10 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond, | |||
1087 | c->private = private; | 1089 | c->private = private; |
1088 | k = 0; | 1090 | k = 0; |
1089 | while (1) { | 1091 | while (1) { |
1090 | if (snd_BUG_ON(k >= ARRAY_SIZE(c->deps))) | 1092 | if (snd_BUG_ON(k >= ARRAY_SIZE(c->deps))) { |
1093 | va_end(args); | ||
1091 | return -EINVAL; | 1094 | return -EINVAL; |
1095 | } | ||
1092 | c->deps[k++] = dep; | 1096 | c->deps[k++] = dep; |
1093 | if (dep < 0) | 1097 | if (dep < 0) |
1094 | break; | 1098 | break; |
@@ -1097,7 +1101,7 @@ int snd_pcm_hw_rule_add(struct snd_pcm_runtime *runtime, unsigned int cond, | |||
1097 | constrs->rules_num++; | 1101 | constrs->rules_num++; |
1098 | va_end(args); | 1102 | va_end(args); |
1099 | return 0; | 1103 | return 0; |
1100 | } | 1104 | } |
1101 | 1105 | ||
1102 | EXPORT_SYMBOL(snd_pcm_hw_rule_add); | 1106 | EXPORT_SYMBOL(snd_pcm_hw_rule_add); |
1103 | 1107 | ||
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c index 46c0d03dbecc..fcb14a099822 100644 --- a/sound/oss/soundcard.c +++ b/sound/oss/soundcard.c | |||
@@ -87,7 +87,7 @@ int *load_mixer_volumes(char *name, int *levels, int present) | |||
87 | int i, n; | 87 | int i, n; |
88 | 88 | ||
89 | for (i = 0; i < num_mixer_volumes; i++) { | 89 | for (i = 0; i < num_mixer_volumes; i++) { |
90 | if (strcmp(name, mixer_vols[i].name) == 0) { | 90 | if (strncmp(name, mixer_vols[i].name, 32) == 0) { |
91 | if (present) | 91 | if (present) |
92 | mixer_vols[i].num = i; | 92 | mixer_vols[i].num = i; |
93 | return mixer_vols[i].levels; | 93 | return mixer_vols[i].levels; |
@@ -99,7 +99,7 @@ int *load_mixer_volumes(char *name, int *levels, int present) | |||
99 | } | 99 | } |
100 | n = num_mixer_volumes++; | 100 | n = num_mixer_volumes++; |
101 | 101 | ||
102 | strcpy(mixer_vols[n].name, name); | 102 | strncpy(mixer_vols[n].name, name, 32); |
103 | 103 | ||
104 | if (present) | 104 | if (present) |
105 | mixer_vols[n].num = n; | 105 | mixer_vols[n].num = n; |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 644e3f14f8ca..98b6d02a36c9 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -1919,6 +1919,16 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, | |||
1919 | } | 1919 | } |
1920 | EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); | 1920 | EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl); |
1921 | 1921 | ||
1922 | static int find_empty_mixer_ctl_idx(struct hda_codec *codec, const char *name) | ||
1923 | { | ||
1924 | int idx; | ||
1925 | for (idx = 0; idx < 16; idx++) { /* 16 ctlrs should be large enough */ | ||
1926 | if (!_snd_hda_find_mixer_ctl(codec, name, idx)) | ||
1927 | return idx; | ||
1928 | } | ||
1929 | return -EBUSY; | ||
1930 | } | ||
1931 | |||
1922 | /** | 1932 | /** |
1923 | * snd_hda_ctl_add - Add a control element and assign to the codec | 1933 | * snd_hda_ctl_add - Add a control element and assign to the codec |
1924 | * @codec: HD-audio codec | 1934 | * @codec: HD-audio codec |
@@ -2654,8 +2664,6 @@ static struct snd_kcontrol_new dig_mixes[] = { | |||
2654 | { } /* end */ | 2664 | { } /* end */ |
2655 | }; | 2665 | }; |
2656 | 2666 | ||
2657 | #define SPDIF_MAX_IDX 4 /* 4 instances should be enough to probe */ | ||
2658 | |||
2659 | /** | 2667 | /** |
2660 | * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls | 2668 | * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls |
2661 | * @codec: the HDA codec | 2669 | * @codec: the HDA codec |
@@ -2673,12 +2681,8 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) | |||
2673 | struct snd_kcontrol_new *dig_mix; | 2681 | struct snd_kcontrol_new *dig_mix; |
2674 | int idx; | 2682 | int idx; |
2675 | 2683 | ||
2676 | for (idx = 0; idx < SPDIF_MAX_IDX; idx++) { | 2684 | idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch"); |
2677 | if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Playback Switch", | 2685 | if (idx < 0) { |
2678 | idx)) | ||
2679 | break; | ||
2680 | } | ||
2681 | if (idx >= SPDIF_MAX_IDX) { | ||
2682 | printk(KERN_ERR "hda_codec: too many IEC958 outputs\n"); | 2686 | printk(KERN_ERR "hda_codec: too many IEC958 outputs\n"); |
2683 | return -EBUSY; | 2687 | return -EBUSY; |
2684 | } | 2688 | } |
@@ -2829,12 +2833,8 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) | |||
2829 | struct snd_kcontrol_new *dig_mix; | 2833 | struct snd_kcontrol_new *dig_mix; |
2830 | int idx; | 2834 | int idx; |
2831 | 2835 | ||
2832 | for (idx = 0; idx < SPDIF_MAX_IDX; idx++) { | 2836 | idx = find_empty_mixer_ctl_idx(codec, "IEC958 Capture Switch"); |
2833 | if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Capture Switch", | 2837 | if (idx < 0) { |
2834 | idx)) | ||
2835 | break; | ||
2836 | } | ||
2837 | if (idx >= SPDIF_MAX_IDX) { | ||
2838 | printk(KERN_ERR "hda_codec: too many IEC958 inputs\n"); | 2838 | printk(KERN_ERR "hda_codec: too many IEC958 inputs\n"); |
2839 | return -EBUSY; | 2839 | return -EBUSY; |
2840 | } | 2840 | } |
@@ -3808,21 +3808,32 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) | |||
3808 | 3808 | ||
3809 | for (; knew->name; knew++) { | 3809 | for (; knew->name; knew++) { |
3810 | struct snd_kcontrol *kctl; | 3810 | struct snd_kcontrol *kctl; |
3811 | int addr = 0, idx = 0; | ||
3811 | if (knew->iface == -1) /* skip this codec private value */ | 3812 | if (knew->iface == -1) /* skip this codec private value */ |
3812 | continue; | 3813 | continue; |
3813 | kctl = snd_ctl_new1(knew, codec); | 3814 | for (;;) { |
3814 | if (!kctl) | ||
3815 | return -ENOMEM; | ||
3816 | err = snd_hda_ctl_add(codec, 0, kctl); | ||
3817 | if (err < 0) { | ||
3818 | if (!codec->addr) | ||
3819 | return err; | ||
3820 | kctl = snd_ctl_new1(knew, codec); | 3815 | kctl = snd_ctl_new1(knew, codec); |
3821 | if (!kctl) | 3816 | if (!kctl) |
3822 | return -ENOMEM; | 3817 | return -ENOMEM; |
3823 | kctl->id.device = codec->addr; | 3818 | if (addr > 0) |
3819 | kctl->id.device = addr; | ||
3820 | if (idx > 0) | ||
3821 | kctl->id.index = idx; | ||
3824 | err = snd_hda_ctl_add(codec, 0, kctl); | 3822 | err = snd_hda_ctl_add(codec, 0, kctl); |
3825 | if (err < 0) | 3823 | if (!err) |
3824 | break; | ||
3825 | /* try first with another device index corresponding to | ||
3826 | * the codec addr; if it still fails (or it's the | ||
3827 | * primary codec), then try another control index | ||
3828 | */ | ||
3829 | if (!addr && codec->addr) | ||
3830 | addr = codec->addr; | ||
3831 | else if (!idx && !knew->index) { | ||
3832 | idx = find_empty_mixer_ctl_idx(codec, | ||
3833 | knew->name); | ||
3834 | if (idx <= 0) | ||
3835 | return err; | ||
3836 | } else | ||
3826 | return err; | 3837 | return err; |
3827 | } | 3838 | } |
3828 | } | 3839 | } |
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index cb0c23a6b473..4a663471dadc 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c | |||
@@ -189,6 +189,9 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a, | |||
189 | a->channels = GRAB_BITS(buf, 0, 0, 3); | 189 | a->channels = GRAB_BITS(buf, 0, 0, 3); |
190 | a->channels++; | 190 | a->channels++; |
191 | 191 | ||
192 | a->sample_bits = 0; | ||
193 | a->max_bitrate = 0; | ||
194 | |||
192 | a->format = GRAB_BITS(buf, 0, 3, 4); | 195 | a->format = GRAB_BITS(buf, 0, 3, 4); |
193 | switch (a->format) { | 196 | switch (a->format) { |
194 | case AUDIO_CODING_TYPE_REF_STREAM_HEADER: | 197 | case AUDIO_CODING_TYPE_REF_STREAM_HEADER: |
@@ -198,7 +201,6 @@ static void hdmi_update_short_audio_desc(struct cea_sad *a, | |||
198 | 201 | ||
199 | case AUDIO_CODING_TYPE_LPCM: | 202 | case AUDIO_CODING_TYPE_LPCM: |
200 | val = GRAB_BITS(buf, 2, 0, 3); | 203 | val = GRAB_BITS(buf, 2, 0, 3); |
201 | a->sample_bits = 0; | ||
202 | for (i = 0; i < 3; i++) | 204 | for (i = 0; i < 3; i++) |
203 | if (val & (1 << i)) | 205 | if (val & (1 << i)) |
204 | a->sample_bits |= cea_sample_sizes[i + 1]; | 206 | a->sample_bits |= cea_sample_sizes[i + 1]; |
@@ -598,24 +600,19 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, | |||
598 | { | 600 | { |
599 | int i; | 601 | int i; |
600 | 602 | ||
601 | pcm->rates = 0; | 603 | /* assume basic audio support (the basic audio flag is not in ELD; |
602 | pcm->formats = 0; | 604 | * however, all audio capable sinks are required to support basic |
603 | pcm->maxbps = 0; | 605 | * audio) */ |
604 | pcm->channels_min = -1; | 606 | pcm->rates = SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; |
605 | pcm->channels_max = 0; | 607 | pcm->formats = SNDRV_PCM_FMTBIT_S16_LE; |
608 | pcm->maxbps = 16; | ||
609 | pcm->channels_max = 2; | ||
606 | for (i = 0; i < eld->sad_count; i++) { | 610 | for (i = 0; i < eld->sad_count; i++) { |
607 | struct cea_sad *a = &eld->sad[i]; | 611 | struct cea_sad *a = &eld->sad[i]; |
608 | pcm->rates |= a->rates; | 612 | pcm->rates |= a->rates; |
609 | if (a->channels < pcm->channels_min) | ||
610 | pcm->channels_min = a->channels; | ||
611 | if (a->channels > pcm->channels_max) | 613 | if (a->channels > pcm->channels_max) |
612 | pcm->channels_max = a->channels; | 614 | pcm->channels_max = a->channels; |
613 | if (a->format == AUDIO_CODING_TYPE_LPCM) { | 615 | if (a->format == AUDIO_CODING_TYPE_LPCM) { |
614 | if (a->sample_bits & AC_SUPPCM_BITS_16) { | ||
615 | pcm->formats |= SNDRV_PCM_FMTBIT_S16_LE; | ||
616 | if (pcm->maxbps < 16) | ||
617 | pcm->maxbps = 16; | ||
618 | } | ||
619 | if (a->sample_bits & AC_SUPPCM_BITS_20) { | 616 | if (a->sample_bits & AC_SUPPCM_BITS_20) { |
620 | pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE; | 617 | pcm->formats |= SNDRV_PCM_FMTBIT_S32_LE; |
621 | if (pcm->maxbps < 20) | 618 | if (pcm->maxbps < 20) |
@@ -635,7 +632,6 @@ void hdmi_eld_update_pcm_info(struct hdmi_eld *eld, struct hda_pcm_stream *pcm, | |||
635 | /* restrict the parameters by the values the codec provides */ | 632 | /* restrict the parameters by the values the codec provides */ |
636 | pcm->rates &= codec_pars->rates; | 633 | pcm->rates &= codec_pars->rates; |
637 | pcm->formats &= codec_pars->formats; | 634 | pcm->formats &= codec_pars->formats; |
638 | pcm->channels_min = max(pcm->channels_min, codec_pars->channels_min); | ||
639 | pcm->channels_max = min(pcm->channels_max, codec_pars->channels_max); | 635 | pcm->channels_max = min(pcm->channels_max, codec_pars->channels_max); |
640 | pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps); | 636 | pcm->maxbps = min(pcm->maxbps, codec_pars->maxbps); |
641 | } | 637 | } |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 21aa9b0e28f6..a1c4008af891 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -2296,9 +2296,11 @@ static int azx_dev_free(struct snd_device *device) | |||
2296 | */ | 2296 | */ |
2297 | static struct snd_pci_quirk position_fix_list[] __devinitdata = { | 2297 | static struct snd_pci_quirk position_fix_list[] __devinitdata = { |
2298 | SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB), | 2298 | SND_PCI_QUIRK(0x1025, 0x009f, "Acer Aspire 5110", POS_FIX_LPIB), |
2299 | SND_PCI_QUIRK(0x1025, 0x026f, "Acer Aspire 5538", POS_FIX_LPIB), | ||
2299 | SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), | 2300 | SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_LPIB), |
2300 | SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), | 2301 | SND_PCI_QUIRK(0x1028, 0x01de, "Dell Precision 390", POS_FIX_LPIB), |
2301 | SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB), | 2302 | SND_PCI_QUIRK(0x1028, 0x01f6, "Dell Latitude 131L", POS_FIX_LPIB), |
2303 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell Inspiron 1120", POS_FIX_LPIB), | ||
2302 | SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), | 2304 | SND_PCI_QUIRK(0x103c, 0x306d, "HP dv3", POS_FIX_LPIB), |
2303 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), | 2305 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), |
2304 | SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB), | 2306 | SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB), |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 846d1ead47fd..76bd58a0e2b6 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -2116,8 +2116,8 @@ static void cxt5066_update_speaker(struct hda_codec *codec) | |||
2116 | struct conexant_spec *spec = codec->spec; | 2116 | struct conexant_spec *spec = codec->spec; |
2117 | unsigned int pinctl; | 2117 | unsigned int pinctl; |
2118 | 2118 | ||
2119 | snd_printdd("CXT5066: update speaker, hp_present=%d\n", | 2119 | snd_printdd("CXT5066: update speaker, hp_present=%d, cur_eapd=%d\n", |
2120 | spec->hp_present); | 2120 | spec->hp_present, spec->cur_eapd); |
2121 | 2121 | ||
2122 | /* Port A (HP) */ | 2122 | /* Port A (HP) */ |
2123 | pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0; | 2123 | pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0; |
@@ -2125,11 +2125,20 @@ static void cxt5066_update_speaker(struct hda_codec *codec) | |||
2125 | pinctl); | 2125 | pinctl); |
2126 | 2126 | ||
2127 | /* Port D (HP/LO) */ | 2127 | /* Port D (HP/LO) */ |
2128 | pinctl = ((spec->hp_present & 2) && spec->cur_eapd) | 2128 | if (spec->dell_automute) { |
2129 | ? spec->port_d_mode : 0; | 2129 | /* DELL AIO Port Rule: PortA> PortD> IntSpk */ |
2130 | /* Mute if Port A is connected on Thinkpad */ | 2130 | pinctl = (!(spec->hp_present & 1) && spec->cur_eapd) |
2131 | if (spec->thinkpad && (spec->hp_present & 1)) | 2131 | ? PIN_OUT : 0; |
2132 | pinctl = 0; | 2132 | } else if (spec->thinkpad) { |
2133 | if (spec->cur_eapd) | ||
2134 | pinctl = spec->port_d_mode; | ||
2135 | /* Mute dock line-out if Port A (laptop HP) is present */ | ||
2136 | if (spec->hp_present& 1) | ||
2137 | pinctl = 0; | ||
2138 | } else { | ||
2139 | pinctl = ((spec->hp_present & 2) && spec->cur_eapd) | ||
2140 | ? spec->port_d_mode : 0; | ||
2141 | } | ||
2133 | snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 2142 | snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
2134 | pinctl); | 2143 | pinctl); |
2135 | 2144 | ||
@@ -2137,14 +2146,6 @@ static void cxt5066_update_speaker(struct hda_codec *codec) | |||
2137 | pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; | 2146 | pinctl = (!spec->hp_present && spec->cur_eapd) ? PIN_OUT : 0; |
2138 | snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 2147 | snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
2139 | pinctl); | 2148 | pinctl); |
2140 | |||
2141 | if (spec->dell_automute) { | ||
2142 | /* DELL AIO Port Rule: PortA > PortD > IntSpk */ | ||
2143 | pinctl = (!(spec->hp_present & 1) && spec->cur_eapd) | ||
2144 | ? PIN_OUT : 0; | ||
2145 | snd_hda_codec_write(codec, 0x1c, 0, | ||
2146 | AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl); | ||
2147 | } | ||
2148 | } | 2149 | } |
2149 | 2150 | ||
2150 | /* turn on/off EAPD (+ mute HP) as a master switch */ | 2151 | /* turn on/off EAPD (+ mute HP) as a master switch */ |
@@ -3095,8 +3096,7 @@ static const char *cxt5066_models[CXT5066_MODELS] = { | |||
3095 | static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | 3096 | static struct snd_pci_quirk cxt5066_cfg_tbl[] = { |
3096 | SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD), | 3097 | SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD), |
3097 | SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO), | 3098 | SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO), |
3098 | SND_PCI_QUIRK(0x1028, 0x02f5, "Dell", | 3099 | SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD), |
3099 | CXT5066_DELL_LAPTOP), | ||
3100 | SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO), | 3100 | SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO), |
3101 | SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), | 3101 | SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), |
3102 | SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP), | 3102 | SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP), |
@@ -3109,6 +3109,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
3109 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), | 3109 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), |
3110 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), | 3110 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), |
3111 | SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), | 3111 | SND_PCI_QUIRK(0x17aa, 0x21b2, "Thinkpad X100e", CXT5066_IDEAPAD), |
3112 | SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), | ||
3112 | SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD), | 3113 | SND_PCI_QUIRK(0x17aa, 0x21b3, "Thinkpad Edge 13 (197)", CXT5066_IDEAPAD), |
3113 | SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD), | 3114 | SND_PCI_QUIRK(0x17aa, 0x21b4, "Thinkpad Edge", CXT5066_IDEAPAD), |
3114 | SND_PCI_QUIRK(0x17aa, 0x21c8, "Thinkpad Edge 11", CXT5066_IDEAPAD), | 3115 | SND_PCI_QUIRK(0x17aa, 0x21c8, "Thinkpad Edge 11", CXT5066_IDEAPAD), |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index d3e49aa5b9ec..31df7747990d 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -834,7 +834,6 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, | |||
834 | return -ENODEV; | 834 | return -ENODEV; |
835 | } else { | 835 | } else { |
836 | /* fallback to the codec default */ | 836 | /* fallback to the codec default */ |
837 | hinfo->channels_min = codec_pars->channels_min; | ||
838 | hinfo->channels_max = codec_pars->channels_max; | 837 | hinfo->channels_max = codec_pars->channels_max; |
839 | hinfo->rates = codec_pars->rates; | 838 | hinfo->rates = codec_pars->rates; |
840 | hinfo->formats = codec_pars->formats; | 839 | hinfo->formats = codec_pars->formats; |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8fddc9d08726..552a09e9211f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -4595,6 +4595,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = { | |||
4595 | SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), | 4595 | SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), |
4596 | SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), | 4596 | SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), |
4597 | SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), | 4597 | SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), |
4598 | SND_PCI_QUIRK(0x1854, 0x005f, "LG P1 Express", ALC880_LG), | ||
4598 | SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), | 4599 | SND_PCI_QUIRK(0x1854, 0x0068, "LG w1", ALC880_LG), |
4599 | SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), | 4600 | SND_PCI_QUIRK(0x1854, 0x0077, "LG LW25", ALC880_LG_LW), |
4600 | SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), | 4601 | SND_PCI_QUIRK(0x19db, 0x4188, "TCL S700", ALC880_TCL_S700), |
@@ -10829,7 +10830,8 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec) | |||
10829 | { | 10830 | { |
10830 | struct alc_spec *spec = codec->spec; | 10831 | struct alc_spec *spec = codec->spec; |
10831 | struct auto_pin_cfg *cfg = &spec->autocfg; | 10832 | struct auto_pin_cfg *cfg = &spec->autocfg; |
10832 | int i, err; | 10833 | int i, err, type; |
10834 | int type_idx = 0; | ||
10833 | hda_nid_t nid; | 10835 | hda_nid_t nid; |
10834 | 10836 | ||
10835 | for (i = 0; i < cfg->num_inputs; i++) { | 10837 | for (i = 0; i < cfg->num_inputs; i++) { |
@@ -10838,9 +10840,15 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec) | |||
10838 | nid = cfg->inputs[i].pin; | 10840 | nid = cfg->inputs[i].pin; |
10839 | if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) { | 10841 | if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) { |
10840 | char label[32]; | 10842 | char label[32]; |
10843 | type = cfg->inputs[i].type; | ||
10844 | if (i > 0 && type == cfg->inputs[i - 1].type) | ||
10845 | type_idx++; | ||
10846 | else | ||
10847 | type_idx = 0; | ||
10841 | snprintf(label, sizeof(label), "%s Boost", | 10848 | snprintf(label, sizeof(label), "%s Boost", |
10842 | hda_get_autocfg_input_label(codec, cfg, i)); | 10849 | hda_get_autocfg_input_label(codec, cfg, i)); |
10843 | err = add_control(spec, ALC_CTL_WIDGET_VOL, label, 0, | 10850 | err = add_control(spec, ALC_CTL_WIDGET_VOL, label, |
10851 | type_idx, | ||
10844 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); | 10852 | HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT)); |
10845 | if (err < 0) | 10853 | if (err < 0) |
10846 | return err; | 10854 | return err; |
@@ -14798,7 +14806,10 @@ static int alc269_resume(struct hda_codec *codec) | |||
14798 | 14806 | ||
14799 | enum { | 14807 | enum { |
14800 | ALC269_FIXUP_SONY_VAIO, | 14808 | ALC269_FIXUP_SONY_VAIO, |
14809 | ALC275_FIX_SONY_VAIO_GPIO2, | ||
14801 | ALC269_FIXUP_DELL_M101Z, | 14810 | ALC269_FIXUP_DELL_M101Z, |
14811 | ALC269_FIXUP_SKU_IGNORE, | ||
14812 | ALC269_FIXUP_ASUS_G73JW, | ||
14802 | }; | 14813 | }; |
14803 | 14814 | ||
14804 | static const struct alc_fixup alc269_fixups[] = { | 14815 | static const struct alc_fixup alc269_fixups[] = { |
@@ -14808,6 +14819,14 @@ static const struct alc_fixup alc269_fixups[] = { | |||
14808 | {} | 14819 | {} |
14809 | } | 14820 | } |
14810 | }, | 14821 | }, |
14822 | [ALC275_FIX_SONY_VAIO_GPIO2] = { | ||
14823 | .verbs = (const struct hda_verb[]) { | ||
14824 | {0x01, AC_VERB_SET_GPIO_MASK, 0x04}, | ||
14825 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x04}, | ||
14826 | {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, | ||
14827 | { } | ||
14828 | } | ||
14829 | }, | ||
14811 | [ALC269_FIXUP_DELL_M101Z] = { | 14830 | [ALC269_FIXUP_DELL_M101Z] = { |
14812 | .verbs = (const struct hda_verb[]) { | 14831 | .verbs = (const struct hda_verb[]) { |
14813 | /* Enables internal speaker */ | 14832 | /* Enables internal speaker */ |
@@ -14816,11 +14835,26 @@ static const struct alc_fixup alc269_fixups[] = { | |||
14816 | {} | 14835 | {} |
14817 | } | 14836 | } |
14818 | }, | 14837 | }, |
14838 | [ALC269_FIXUP_SKU_IGNORE] = { | ||
14839 | .sku = ALC_FIXUP_SKU_IGNORE, | ||
14840 | }, | ||
14841 | [ALC269_FIXUP_ASUS_G73JW] = { | ||
14842 | .pins = (const struct alc_pincfg[]) { | ||
14843 | { 0x17, 0x99130111 }, /* subwoofer */ | ||
14844 | { } | ||
14845 | } | ||
14846 | }, | ||
14819 | }; | 14847 | }; |
14820 | 14848 | ||
14821 | static struct snd_pci_quirk alc269_fixup_tbl[] = { | 14849 | static struct snd_pci_quirk alc269_fixup_tbl[] = { |
14850 | SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2), | ||
14851 | SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2), | ||
14852 | SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIX_SONY_VAIO_GPIO2), | ||
14822 | SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), | 14853 | SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), |
14823 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), | 14854 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), |
14855 | SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), | ||
14856 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), | ||
14857 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), | ||
14824 | {} | 14858 | {} |
14825 | }; | 14859 | }; |
14826 | 14860 | ||
@@ -15070,28 +15104,29 @@ static int patch_alc269(struct hda_codec *codec) | |||
15070 | 15104 | ||
15071 | alc_auto_parse_customize_define(codec); | 15105 | alc_auto_parse_customize_define(codec); |
15072 | 15106 | ||
15073 | coef = alc_read_coef_idx(codec, 0); | 15107 | if (codec->vendor_id == 0x10ec0269) { |
15074 | if ((coef & 0x00f0) == 0x0010) { | 15108 | coef = alc_read_coef_idx(codec, 0); |
15075 | if (codec->bus->pci->subsystem_vendor == 0x1025 && | 15109 | if ((coef & 0x00f0) == 0x0010) { |
15076 | spec->cdefine.platform_type == 1) { | 15110 | if (codec->bus->pci->subsystem_vendor == 0x1025 && |
15077 | alc_codec_rename(codec, "ALC271X"); | 15111 | spec->cdefine.platform_type == 1) { |
15078 | spec->codec_variant = ALC269_TYPE_ALC271X; | 15112 | alc_codec_rename(codec, "ALC271X"); |
15079 | } else if ((coef & 0xf000) == 0x1000) { | 15113 | spec->codec_variant = ALC269_TYPE_ALC271X; |
15080 | spec->codec_variant = ALC269_TYPE_ALC270; | 15114 | } else if ((coef & 0xf000) == 0x1000) { |
15081 | } else if ((coef & 0xf000) == 0x2000) { | 15115 | spec->codec_variant = ALC269_TYPE_ALC270; |
15082 | alc_codec_rename(codec, "ALC259"); | 15116 | } else if ((coef & 0xf000) == 0x2000) { |
15083 | spec->codec_variant = ALC269_TYPE_ALC259; | 15117 | alc_codec_rename(codec, "ALC259"); |
15084 | } else if ((coef & 0xf000) == 0x3000) { | 15118 | spec->codec_variant = ALC269_TYPE_ALC259; |
15085 | alc_codec_rename(codec, "ALC258"); | 15119 | } else if ((coef & 0xf000) == 0x3000) { |
15086 | spec->codec_variant = ALC269_TYPE_ALC258; | 15120 | alc_codec_rename(codec, "ALC258"); |
15087 | } else { | 15121 | spec->codec_variant = ALC269_TYPE_ALC258; |
15088 | alc_codec_rename(codec, "ALC269VB"); | 15122 | } else { |
15089 | spec->codec_variant = ALC269_TYPE_ALC269VB; | 15123 | alc_codec_rename(codec, "ALC269VB"); |
15090 | } | 15124 | spec->codec_variant = ALC269_TYPE_ALC269VB; |
15091 | } else | 15125 | } |
15092 | alc_fix_pll_init(codec, 0x20, 0x04, 15); | 15126 | } else |
15093 | 15127 | alc_fix_pll_init(codec, 0x20, 0x04, 15); | |
15094 | alc269_fill_coef(codec); | 15128 | alc269_fill_coef(codec); |
15129 | } | ||
15095 | 15130 | ||
15096 | board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, | 15131 | board_config = snd_hda_check_board_config(codec, ALC269_MODEL_LAST, |
15097 | alc269_models, | 15132 | alc269_models, |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index efa4225f5fd6..f03b2ff90496 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -3481,6 +3481,8 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | |||
3481 | 3481 | ||
3482 | label = hda_get_input_pin_label(codec, nid, 1); | 3482 | label = hda_get_input_pin_label(codec, nid, 1); |
3483 | snd_hda_add_imux_item(dimux, label, index, &type_idx); | 3483 | snd_hda_add_imux_item(dimux, label, index, &type_idx); |
3484 | if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) | ||
3485 | snd_hda_add_imux_item(imux, label, index, &type_idx); | ||
3484 | 3486 | ||
3485 | err = create_elem_capture_vol(codec, nid, label, type_idx, | 3487 | err = create_elem_capture_vol(codec, nid, label, type_idx, |
3486 | HDA_INPUT); | 3488 | HDA_INPUT); |
@@ -3492,9 +3494,6 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, | |||
3492 | if (err < 0) | 3494 | if (err < 0) |
3493 | return err; | 3495 | return err; |
3494 | } | 3496 | } |
3495 | |||
3496 | if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) | ||
3497 | snd_hda_add_imux_item(imux, label, index, NULL); | ||
3498 | } | 3497 | } |
3499 | 3498 | ||
3500 | return 0; | 3499 | return 0; |
diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index d63e28773eb1..6447dbb2f123 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c | |||
@@ -40,7 +40,6 @@ struct max98088_cdata { | |||
40 | }; | 40 | }; |
41 | 41 | ||
42 | struct max98088_priv { | 42 | struct max98088_priv { |
43 | u8 reg_cache[M98088_REG_CNT]; | ||
44 | enum max98088_type devtype; | 43 | enum max98088_type devtype; |
45 | void *control_data; | 44 | void *control_data; |
46 | struct max98088_pdata *pdata; | 45 | struct max98088_pdata *pdata; |
@@ -1588,7 +1587,7 @@ static int max98088_dai2_set_fmt(struct snd_soc_dai *codec_dai, | |||
1588 | 1587 | ||
1589 | static void max98088_sync_cache(struct snd_soc_codec *codec) | 1588 | static void max98088_sync_cache(struct snd_soc_codec *codec) |
1590 | { | 1589 | { |
1591 | struct max98088_priv *max98088 = snd_soc_codec_get_drvdata(codec); | 1590 | u16 *reg_cache = codec->reg_cache; |
1592 | int i; | 1591 | int i; |
1593 | 1592 | ||
1594 | if (!codec->cache_sync) | 1593 | if (!codec->cache_sync) |
@@ -1599,14 +1598,14 @@ static void max98088_sync_cache(struct snd_soc_codec *codec) | |||
1599 | /* write back cached values if they're writeable and | 1598 | /* write back cached values if they're writeable and |
1600 | * different from the hardware default. | 1599 | * different from the hardware default. |
1601 | */ | 1600 | */ |
1602 | for (i = 1; i < ARRAY_SIZE(max98088->reg_cache); i++) { | 1601 | for (i = 1; i < codec->driver->reg_cache_size; i++) { |
1603 | if (!max98088_access[i].writable) | 1602 | if (!max98088_access[i].writable) |
1604 | continue; | 1603 | continue; |
1605 | 1604 | ||
1606 | if (max98088->reg_cache[i] == max98088_reg[i]) | 1605 | if (reg_cache[i] == max98088_reg[i]) |
1607 | continue; | 1606 | continue; |
1608 | 1607 | ||
1609 | snd_soc_write(codec, i, max98088->reg_cache[i]); | 1608 | snd_soc_write(codec, i, reg_cache[i]); |
1610 | } | 1609 | } |
1611 | 1610 | ||
1612 | codec->cache_sync = 0; | 1611 | codec->cache_sync = 0; |
@@ -1951,7 +1950,6 @@ static int max98088_probe(struct snd_soc_codec *codec) | |||
1951 | int ret = 0; | 1950 | int ret = 0; |
1952 | 1951 | ||
1953 | codec->cache_sync = 1; | 1952 | codec->cache_sync = 1; |
1954 | memcpy(codec->reg_cache, max98088_reg, sizeof(max98088_reg)); | ||
1955 | 1953 | ||
1956 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); | 1954 | ret = snd_soc_codec_set_cache_io(codec, 8, 8, SND_SOC_I2C); |
1957 | if (ret != 0) { | 1955 | if (ret != 0) { |
diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index 9a433a5396cb..deca79ea2b4b 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c | |||
@@ -41,7 +41,6 @@ static const char *wm8523_supply_names[WM8523_NUM_SUPPLIES] = { | |||
41 | /* codec private data */ | 41 | /* codec private data */ |
42 | struct wm8523_priv { | 42 | struct wm8523_priv { |
43 | enum snd_soc_control_type control_type; | 43 | enum snd_soc_control_type control_type; |
44 | u16 reg_cache[WM8523_REGISTER_COUNT]; | ||
45 | struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES]; | 44 | struct regulator_bulk_data supplies[WM8523_NUM_SUPPLIES]; |
46 | unsigned int sysclk; | 45 | unsigned int sysclk; |
47 | unsigned int rate_constraint_list[WM8523_NUM_RATES]; | 46 | unsigned int rate_constraint_list[WM8523_NUM_RATES]; |
@@ -314,6 +313,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec, | |||
314 | enum snd_soc_bias_level level) | 313 | enum snd_soc_bias_level level) |
315 | { | 314 | { |
316 | struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); | 315 | struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); |
316 | u16 *reg_cache = codec->reg_cache; | ||
317 | int ret, i; | 317 | int ret, i; |
318 | 318 | ||
319 | switch (level) { | 319 | switch (level) { |
@@ -344,7 +344,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec, | |||
344 | /* Sync back default/cached values */ | 344 | /* Sync back default/cached values */ |
345 | for (i = WM8523_AIF_CTRL1; | 345 | for (i = WM8523_AIF_CTRL1; |
346 | i < WM8523_MAX_REGISTER; i++) | 346 | i < WM8523_MAX_REGISTER; i++) |
347 | snd_soc_write(codec, i, wm8523->reg_cache[i]); | 347 | snd_soc_write(codec, i, reg_cache[i]); |
348 | 348 | ||
349 | 349 | ||
350 | msleep(100); | 350 | msleep(100); |
@@ -414,6 +414,7 @@ static int wm8523_resume(struct snd_soc_codec *codec) | |||
414 | static int wm8523_probe(struct snd_soc_codec *codec) | 414 | static int wm8523_probe(struct snd_soc_codec *codec) |
415 | { | 415 | { |
416 | struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); | 416 | struct wm8523_priv *wm8523 = snd_soc_codec_get_drvdata(codec); |
417 | u16 *reg_cache = codec->reg_cache; | ||
417 | int ret, i; | 418 | int ret, i; |
418 | 419 | ||
419 | codec->hw_write = (hw_write_t)i2c_master_send; | 420 | codec->hw_write = (hw_write_t)i2c_master_send; |
@@ -470,8 +471,8 @@ static int wm8523_probe(struct snd_soc_codec *codec) | |||
470 | } | 471 | } |
471 | 472 | ||
472 | /* Change some default settings - latch VU and enable ZC */ | 473 | /* Change some default settings - latch VU and enable ZC */ |
473 | wm8523->reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU; | 474 | reg_cache[WM8523_DAC_GAINR] |= WM8523_DACR_VU; |
474 | wm8523->reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC; | 475 | reg_cache[WM8523_DAC_CTRL3] |= WM8523_ZC; |
475 | 476 | ||
476 | wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 477 | wm8523_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
477 | 478 | ||
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index a2e0ed59b376..8725d4e75431 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c | |||
@@ -161,7 +161,7 @@ | |||
161 | static const u16 wm8580_reg[] = { | 161 | static const u16 wm8580_reg[] = { |
162 | 0x0121, 0x017e, 0x007d, 0x0014, /*R3*/ | 162 | 0x0121, 0x017e, 0x007d, 0x0014, /*R3*/ |
163 | 0x0121, 0x017e, 0x007d, 0x0194, /*R7*/ | 163 | 0x0121, 0x017e, 0x007d, 0x0194, /*R7*/ |
164 | 0x001c, 0x0002, 0x0002, 0x00c2, /*R11*/ | 164 | 0x0010, 0x0002, 0x0002, 0x00c2, /*R11*/ |
165 | 0x0182, 0x0082, 0x000a, 0x0024, /*R15*/ | 165 | 0x0182, 0x0082, 0x000a, 0x0024, /*R15*/ |
166 | 0x0009, 0x0000, 0x00ff, 0x0000, /*R19*/ | 166 | 0x0009, 0x0000, 0x00ff, 0x0000, /*R19*/ |
167 | 0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R23*/ | 167 | 0x00ff, 0x00ff, 0x00ff, 0x00ff, /*R23*/ |
@@ -491,16 +491,16 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream, | |||
491 | paifa |= 0x8; | 491 | paifa |= 0x8; |
492 | break; | 492 | break; |
493 | case SNDRV_PCM_FORMAT_S20_3LE: | 493 | case SNDRV_PCM_FORMAT_S20_3LE: |
494 | paifa |= 0x10; | 494 | paifa |= 0x0; |
495 | paifb |= WM8580_AIF_LENGTH_20; | 495 | paifb |= WM8580_AIF_LENGTH_20; |
496 | break; | 496 | break; |
497 | case SNDRV_PCM_FORMAT_S24_LE: | 497 | case SNDRV_PCM_FORMAT_S24_LE: |
498 | paifa |= 0x10; | 498 | paifa |= 0x0; |
499 | paifb |= WM8580_AIF_LENGTH_24; | 499 | paifb |= WM8580_AIF_LENGTH_24; |
500 | break; | 500 | break; |
501 | case SNDRV_PCM_FORMAT_S32_LE: | 501 | case SNDRV_PCM_FORMAT_S32_LE: |
502 | paifa |= 0x10; | 502 | paifa |= 0x0; |
503 | paifb |= WM8580_AIF_LENGTH_24; | 503 | paifb |= WM8580_AIF_LENGTH_32; |
504 | break; | 504 | break; |
505 | default: | 505 | default: |
506 | return -EINVAL; | 506 | return -EINVAL; |
diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index 90e31e9aa6f7..aea60ef8aba7 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c | |||
@@ -41,7 +41,6 @@ static const char *wm8741_supply_names[WM8741_NUM_SUPPLIES] = { | |||
41 | /* codec private data */ | 41 | /* codec private data */ |
42 | struct wm8741_priv { | 42 | struct wm8741_priv { |
43 | enum snd_soc_control_type control_type; | 43 | enum snd_soc_control_type control_type; |
44 | u16 reg_cache[WM8741_REGISTER_COUNT]; | ||
45 | struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES]; | 44 | struct regulator_bulk_data supplies[WM8741_NUM_SUPPLIES]; |
46 | unsigned int sysclk; | 45 | unsigned int sysclk; |
47 | struct snd_pcm_hw_constraint_list *sysclk_constraints; | 46 | struct snd_pcm_hw_constraint_list *sysclk_constraints; |
@@ -422,6 +421,7 @@ static int wm8741_resume(struct snd_soc_codec *codec) | |||
422 | static int wm8741_probe(struct snd_soc_codec *codec) | 421 | static int wm8741_probe(struct snd_soc_codec *codec) |
423 | { | 422 | { |
424 | struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); | 423 | struct wm8741_priv *wm8741 = snd_soc_codec_get_drvdata(codec); |
424 | u16 *reg_cache = codec->reg_cache; | ||
425 | int ret = 0; | 425 | int ret = 0; |
426 | 426 | ||
427 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type); | 427 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8741->control_type); |
@@ -437,10 +437,10 @@ static int wm8741_probe(struct snd_soc_codec *codec) | |||
437 | } | 437 | } |
438 | 438 | ||
439 | /* Change some default settings - latch VU */ | 439 | /* Change some default settings - latch VU */ |
440 | wm8741->reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL; | 440 | reg_cache[WM8741_DACLLSB_ATTENUATION] |= WM8741_UPDATELL; |
441 | wm8741->reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM; | 441 | reg_cache[WM8741_DACLMSB_ATTENUATION] |= WM8741_UPDATELM; |
442 | wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL; | 442 | reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERL; |
443 | wm8741->reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM; | 443 | reg_cache[WM8741_DACRLSB_ATTENUATION] |= WM8741_UPDATERM; |
444 | 444 | ||
445 | snd_soc_add_controls(codec, wm8741_snd_controls, | 445 | snd_soc_add_controls(codec, wm8741_snd_controls, |
446 | ARRAY_SIZE(wm8741_snd_controls)); | 446 | ARRAY_SIZE(wm8741_snd_controls)); |
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 8f679a13f2bc..87caae59e939 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c | |||
@@ -65,22 +65,22 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec, | |||
65 | * are using 2 wire for device control, so we cache them instead. | 65 | * are using 2 wire for device control, so we cache them instead. |
66 | */ | 66 | */ |
67 | static const u16 wm8753_reg[] = { | 67 | static const u16 wm8753_reg[] = { |
68 | 0x0008, 0x0000, 0x000a, 0x000a, | 68 | 0x0000, 0x0008, 0x0000, 0x000a, |
69 | 0x0033, 0x0000, 0x0007, 0x00ff, | 69 | 0x000a, 0x0033, 0x0000, 0x0007, |
70 | 0x00ff, 0x000f, 0x000f, 0x007b, | 70 | 0x00ff, 0x00ff, 0x000f, 0x000f, |
71 | 0x0000, 0x0032, 0x0000, 0x00c3, | 71 | 0x007b, 0x0000, 0x0032, 0x0000, |
72 | 0x00c3, 0x00c0, 0x0000, 0x0000, | 72 | 0x00c3, 0x00c3, 0x00c0, 0x0000, |
73 | 0x0000, 0x0000, 0x0000, 0x0000, | 73 | 0x0000, 0x0000, 0x0000, 0x0000, |
74 | 0x0000, 0x0000, 0x0000, 0x0000, | 74 | 0x0000, 0x0000, 0x0000, 0x0000, |
75 | 0x0000, 0x0000, 0x0000, 0x0055, | ||
76 | 0x0005, 0x0050, 0x0055, 0x0050, | ||
77 | 0x0055, 0x0050, 0x0055, 0x0079, | ||
78 | 0x0079, 0x0079, 0x0079, 0x0079, | ||
79 | 0x0000, 0x0000, 0x0000, 0x0000, | 75 | 0x0000, 0x0000, 0x0000, 0x0000, |
80 | 0x0097, 0x0097, 0x0000, 0x0004, | 76 | 0x0055, 0x0005, 0x0050, 0x0055, |
81 | 0x0000, 0x0083, 0x0024, 0x01ba, | 77 | 0x0050, 0x0055, 0x0050, 0x0055, |
82 | 0x0000, 0x0083, 0x0024, 0x01ba, | 78 | 0x0079, 0x0079, 0x0079, 0x0079, |
83 | 0x0000, 0x0000, 0x0000 | 79 | 0x0079, 0x0000, 0x0000, 0x0000, |
80 | 0x0000, 0x0097, 0x0097, 0x0000, | ||
81 | 0x0004, 0x0000, 0x0083, 0x0024, | ||
82 | 0x01ba, 0x0000, 0x0083, 0x0024, | ||
83 | 0x01ba, 0x0000, 0x0000, 0x0000 | ||
84 | }; | 84 | }; |
85 | 85 | ||
86 | /* codec private data */ | 86 | /* codec private data */ |
@@ -88,57 +88,10 @@ struct wm8753_priv { | |||
88 | enum snd_soc_control_type control_type; | 88 | enum snd_soc_control_type control_type; |
89 | unsigned int sysclk; | 89 | unsigned int sysclk; |
90 | unsigned int pcmclk; | 90 | unsigned int pcmclk; |
91 | u16 reg_cache[ARRAY_SIZE(wm8753_reg)]; | ||
92 | int dai_func; | 91 | int dai_func; |
93 | }; | 92 | }; |
94 | 93 | ||
95 | /* | 94 | #define wm8753_reset(c) snd_soc_write(c, WM8753_RESET, 0) |
96 | * read wm8753 register cache | ||
97 | */ | ||
98 | static inline unsigned int wm8753_read_reg_cache(struct snd_soc_codec *codec, | ||
99 | unsigned int reg) | ||
100 | { | ||
101 | u16 *cache = codec->reg_cache; | ||
102 | if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1)) | ||
103 | return -1; | ||
104 | return cache[reg - 1]; | ||
105 | } | ||
106 | |||
107 | /* | ||
108 | * write wm8753 register cache | ||
109 | */ | ||
110 | static inline void wm8753_write_reg_cache(struct snd_soc_codec *codec, | ||
111 | unsigned int reg, unsigned int value) | ||
112 | { | ||
113 | u16 *cache = codec->reg_cache; | ||
114 | if (reg < 1 || reg >= (ARRAY_SIZE(wm8753_reg) + 1)) | ||
115 | return; | ||
116 | cache[reg - 1] = value; | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * write to the WM8753 register space | ||
121 | */ | ||
122 | static int wm8753_write(struct snd_soc_codec *codec, unsigned int reg, | ||
123 | unsigned int value) | ||
124 | { | ||
125 | u8 data[2]; | ||
126 | |||
127 | /* data is | ||
128 | * D15..D9 WM8753 register offset | ||
129 | * D8...D0 register data | ||
130 | */ | ||
131 | data[0] = (reg << 1) | ((value >> 8) & 0x0001); | ||
132 | data[1] = value & 0x00ff; | ||
133 | |||
134 | wm8753_write_reg_cache(codec, reg, value); | ||
135 | if (codec->hw_write(codec->control_data, data, 2) == 2) | ||
136 | return 0; | ||
137 | else | ||
138 | return -EIO; | ||
139 | } | ||
140 | |||
141 | #define wm8753_reset(c) wm8753_write(c, WM8753_RESET, 0) | ||
142 | 95 | ||
143 | /* | 96 | /* |
144 | * WM8753 Controls | 97 | * WM8753 Controls |
@@ -218,7 +171,7 @@ static int wm8753_get_dai(struct snd_kcontrol *kcontrol, | |||
218 | struct snd_ctl_elem_value *ucontrol) | 171 | struct snd_ctl_elem_value *ucontrol) |
219 | { | 172 | { |
220 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 173 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
221 | int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL); | 174 | int mode = snd_soc_read(codec, WM8753_IOCTL); |
222 | 175 | ||
223 | ucontrol->value.integer.value[0] = (mode & 0xc) >> 2; | 176 | ucontrol->value.integer.value[0] = (mode & 0xc) >> 2; |
224 | return 0; | 177 | return 0; |
@@ -228,7 +181,7 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol, | |||
228 | struct snd_ctl_elem_value *ucontrol) | 181 | struct snd_ctl_elem_value *ucontrol) |
229 | { | 182 | { |
230 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 183 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
231 | int mode = wm8753_read_reg_cache(codec, WM8753_IOCTL); | 184 | int mode = snd_soc_read(codec, WM8753_IOCTL); |
232 | struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); | 185 | struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); |
233 | 186 | ||
234 | if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0]) | 187 | if (((mode & 0xc) >> 2) == ucontrol->value.integer.value[0]) |
@@ -738,17 +691,17 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | |||
738 | if (pll_id == WM8753_PLL1) { | 691 | if (pll_id == WM8753_PLL1) { |
739 | offset = 0; | 692 | offset = 0; |
740 | enable = 0x10; | 693 | enable = 0x10; |
741 | reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xffef; | 694 | reg = snd_soc_read(codec, WM8753_CLOCK) & 0xffef; |
742 | } else { | 695 | } else { |
743 | offset = 4; | 696 | offset = 4; |
744 | enable = 0x8; | 697 | enable = 0x8; |
745 | reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfff7; | 698 | reg = snd_soc_read(codec, WM8753_CLOCK) & 0xfff7; |
746 | } | 699 | } |
747 | 700 | ||
748 | if (!freq_in || !freq_out) { | 701 | if (!freq_in || !freq_out) { |
749 | /* disable PLL */ | 702 | /* disable PLL */ |
750 | wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0026); | 703 | snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0026); |
751 | wm8753_write(codec, WM8753_CLOCK, reg); | 704 | snd_soc_write(codec, WM8753_CLOCK, reg); |
752 | return 0; | 705 | return 0; |
753 | } else { | 706 | } else { |
754 | u16 value = 0; | 707 | u16 value = 0; |
@@ -759,20 +712,20 @@ static int wm8753_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, | |||
759 | /* set up N and K PLL divisor ratios */ | 712 | /* set up N and K PLL divisor ratios */ |
760 | /* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */ | 713 | /* bits 8:5 = PLL_N, bits 3:0 = PLL_K[21:18] */ |
761 | value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18); | 714 | value = (pll_div.n << 5) + ((pll_div.k & 0x3c0000) >> 18); |
762 | wm8753_write(codec, WM8753_PLL1CTL2 + offset, value); | 715 | snd_soc_write(codec, WM8753_PLL1CTL2 + offset, value); |
763 | 716 | ||
764 | /* bits 8:0 = PLL_K[17:9] */ | 717 | /* bits 8:0 = PLL_K[17:9] */ |
765 | value = (pll_div.k & 0x03fe00) >> 9; | 718 | value = (pll_div.k & 0x03fe00) >> 9; |
766 | wm8753_write(codec, WM8753_PLL1CTL3 + offset, value); | 719 | snd_soc_write(codec, WM8753_PLL1CTL3 + offset, value); |
767 | 720 | ||
768 | /* bits 8:0 = PLL_K[8:0] */ | 721 | /* bits 8:0 = PLL_K[8:0] */ |
769 | value = pll_div.k & 0x0001ff; | 722 | value = pll_div.k & 0x0001ff; |
770 | wm8753_write(codec, WM8753_PLL1CTL4 + offset, value); | 723 | snd_soc_write(codec, WM8753_PLL1CTL4 + offset, value); |
771 | 724 | ||
772 | /* set PLL as input and enable */ | 725 | /* set PLL as input and enable */ |
773 | wm8753_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 | | 726 | snd_soc_write(codec, WM8753_PLL1CTL1 + offset, 0x0027 | |
774 | (pll_div.div2 << 3)); | 727 | (pll_div.div2 << 3)); |
775 | wm8753_write(codec, WM8753_CLOCK, reg | enable); | 728 | snd_soc_write(codec, WM8753_CLOCK, reg | enable); |
776 | } | 729 | } |
777 | return 0; | 730 | return 0; |
778 | } | 731 | } |
@@ -879,7 +832,7 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
879 | unsigned int fmt) | 832 | unsigned int fmt) |
880 | { | 833 | { |
881 | struct snd_soc_codec *codec = codec_dai->codec; | 834 | struct snd_soc_codec *codec = codec_dai->codec; |
882 | u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01ec; | 835 | u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01ec; |
883 | 836 | ||
884 | /* interface format */ | 837 | /* interface format */ |
885 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 838 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
@@ -901,7 +854,7 @@ static int wm8753_vdac_adc_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
901 | return -EINVAL; | 854 | return -EINVAL; |
902 | } | 855 | } |
903 | 856 | ||
904 | wm8753_write(codec, WM8753_PCM, voice); | 857 | snd_soc_write(codec, WM8753_PCM, voice); |
905 | return 0; | 858 | return 0; |
906 | } | 859 | } |
907 | 860 | ||
@@ -922,8 +875,8 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream, | |||
922 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 875 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
923 | struct snd_soc_codec *codec = rtd->codec; | 876 | struct snd_soc_codec *codec = rtd->codec; |
924 | struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); | 877 | struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); |
925 | u16 voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x01f3; | 878 | u16 voice = snd_soc_read(codec, WM8753_PCM) & 0x01f3; |
926 | u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x017f; | 879 | u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x017f; |
927 | 880 | ||
928 | /* bit size */ | 881 | /* bit size */ |
929 | switch (params_format(params)) { | 882 | switch (params_format(params)) { |
@@ -943,9 +896,9 @@ static int wm8753_pcm_hw_params(struct snd_pcm_substream *substream, | |||
943 | /* sample rate */ | 896 | /* sample rate */ |
944 | if (params_rate(params) * 384 == wm8753->pcmclk) | 897 | if (params_rate(params) * 384 == wm8753->pcmclk) |
945 | srate |= 0x80; | 898 | srate |= 0x80; |
946 | wm8753_write(codec, WM8753_SRATE1, srate); | 899 | snd_soc_write(codec, WM8753_SRATE1, srate); |
947 | 900 | ||
948 | wm8753_write(codec, WM8753_PCM, voice); | 901 | snd_soc_write(codec, WM8753_PCM, voice); |
949 | return 0; | 902 | return 0; |
950 | } | 903 | } |
951 | 904 | ||
@@ -958,8 +911,8 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
958 | struct snd_soc_codec *codec = codec_dai->codec; | 911 | struct snd_soc_codec *codec = codec_dai->codec; |
959 | u16 voice, ioctl; | 912 | u16 voice, ioctl; |
960 | 913 | ||
961 | voice = wm8753_read_reg_cache(codec, WM8753_PCM) & 0x011f; | 914 | voice = snd_soc_read(codec, WM8753_PCM) & 0x011f; |
962 | ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x015d; | 915 | ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x015d; |
963 | 916 | ||
964 | /* set master/slave audio interface */ | 917 | /* set master/slave audio interface */ |
965 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 918 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
@@ -1013,8 +966,8 @@ static int wm8753_pcm_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
1013 | return -EINVAL; | 966 | return -EINVAL; |
1014 | } | 967 | } |
1015 | 968 | ||
1016 | wm8753_write(codec, WM8753_PCM, voice); | 969 | snd_soc_write(codec, WM8753_PCM, voice); |
1017 | wm8753_write(codec, WM8753_IOCTL, ioctl); | 970 | snd_soc_write(codec, WM8753_IOCTL, ioctl); |
1018 | return 0; | 971 | return 0; |
1019 | } | 972 | } |
1020 | 973 | ||
@@ -1026,16 +979,16 @@ static int wm8753_set_dai_clkdiv(struct snd_soc_dai *codec_dai, | |||
1026 | 979 | ||
1027 | switch (div_id) { | 980 | switch (div_id) { |
1028 | case WM8753_PCMDIV: | 981 | case WM8753_PCMDIV: |
1029 | reg = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0x003f; | 982 | reg = snd_soc_read(codec, WM8753_CLOCK) & 0x003f; |
1030 | wm8753_write(codec, WM8753_CLOCK, reg | div); | 983 | snd_soc_write(codec, WM8753_CLOCK, reg | div); |
1031 | break; | 984 | break; |
1032 | case WM8753_BCLKDIV: | 985 | case WM8753_BCLKDIV: |
1033 | reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x01c7; | 986 | reg = snd_soc_read(codec, WM8753_SRATE2) & 0x01c7; |
1034 | wm8753_write(codec, WM8753_SRATE2, reg | div); | 987 | snd_soc_write(codec, WM8753_SRATE2, reg | div); |
1035 | break; | 988 | break; |
1036 | case WM8753_VXCLKDIV: | 989 | case WM8753_VXCLKDIV: |
1037 | reg = wm8753_read_reg_cache(codec, WM8753_SRATE2) & 0x003f; | 990 | reg = snd_soc_read(codec, WM8753_SRATE2) & 0x003f; |
1038 | wm8753_write(codec, WM8753_SRATE2, reg | div); | 991 | snd_soc_write(codec, WM8753_SRATE2, reg | div); |
1039 | break; | 992 | break; |
1040 | default: | 993 | default: |
1041 | return -EINVAL; | 994 | return -EINVAL; |
@@ -1050,7 +1003,7 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
1050 | unsigned int fmt) | 1003 | unsigned int fmt) |
1051 | { | 1004 | { |
1052 | struct snd_soc_codec *codec = codec_dai->codec; | 1005 | struct snd_soc_codec *codec = codec_dai->codec; |
1053 | u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01e0; | 1006 | u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01e0; |
1054 | 1007 | ||
1055 | /* interface format */ | 1008 | /* interface format */ |
1056 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { | 1009 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
@@ -1072,7 +1025,7 @@ static int wm8753_hdac_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
1072 | return -EINVAL; | 1025 | return -EINVAL; |
1073 | } | 1026 | } |
1074 | 1027 | ||
1075 | wm8753_write(codec, WM8753_HIFI, hifi); | 1028 | snd_soc_write(codec, WM8753_HIFI, hifi); |
1076 | return 0; | 1029 | return 0; |
1077 | } | 1030 | } |
1078 | 1031 | ||
@@ -1085,8 +1038,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
1085 | struct snd_soc_codec *codec = codec_dai->codec; | 1038 | struct snd_soc_codec *codec = codec_dai->codec; |
1086 | u16 ioctl, hifi; | 1039 | u16 ioctl, hifi; |
1087 | 1040 | ||
1088 | hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x011f; | 1041 | hifi = snd_soc_read(codec, WM8753_HIFI) & 0x011f; |
1089 | ioctl = wm8753_read_reg_cache(codec, WM8753_IOCTL) & 0x00ae; | 1042 | ioctl = snd_soc_read(codec, WM8753_IOCTL) & 0x00ae; |
1090 | 1043 | ||
1091 | /* set master/slave audio interface */ | 1044 | /* set master/slave audio interface */ |
1092 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { | 1045 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
@@ -1140,8 +1093,8 @@ static int wm8753_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
1140 | return -EINVAL; | 1093 | return -EINVAL; |
1141 | } | 1094 | } |
1142 | 1095 | ||
1143 | wm8753_write(codec, WM8753_HIFI, hifi); | 1096 | snd_soc_write(codec, WM8753_HIFI, hifi); |
1144 | wm8753_write(codec, WM8753_IOCTL, ioctl); | 1097 | snd_soc_write(codec, WM8753_IOCTL, ioctl); |
1145 | return 0; | 1098 | return 0; |
1146 | } | 1099 | } |
1147 | 1100 | ||
@@ -1162,8 +1115,8 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream, | |||
1162 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 1115 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
1163 | struct snd_soc_codec *codec = rtd->codec; | 1116 | struct snd_soc_codec *codec = rtd->codec; |
1164 | struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); | 1117 | struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); |
1165 | u16 srate = wm8753_read_reg_cache(codec, WM8753_SRATE1) & 0x01c0; | 1118 | u16 srate = snd_soc_read(codec, WM8753_SRATE1) & 0x01c0; |
1166 | u16 hifi = wm8753_read_reg_cache(codec, WM8753_HIFI) & 0x01f3; | 1119 | u16 hifi = snd_soc_read(codec, WM8753_HIFI) & 0x01f3; |
1167 | int coeff; | 1120 | int coeff; |
1168 | 1121 | ||
1169 | /* is digital filter coefficient valid ? */ | 1122 | /* is digital filter coefficient valid ? */ |
@@ -1172,7 +1125,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream, | |||
1172 | printk(KERN_ERR "wm8753 invalid MCLK or rate\n"); | 1125 | printk(KERN_ERR "wm8753 invalid MCLK or rate\n"); |
1173 | return coeff; | 1126 | return coeff; |
1174 | } | 1127 | } |
1175 | wm8753_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) | | 1128 | snd_soc_write(codec, WM8753_SRATE1, srate | (coeff_div[coeff].sr << 1) | |
1176 | coeff_div[coeff].usb); | 1129 | coeff_div[coeff].usb); |
1177 | 1130 | ||
1178 | /* bit size */ | 1131 | /* bit size */ |
@@ -1190,7 +1143,7 @@ static int wm8753_i2s_hw_params(struct snd_pcm_substream *substream, | |||
1190 | break; | 1143 | break; |
1191 | } | 1144 | } |
1192 | 1145 | ||
1193 | wm8753_write(codec, WM8753_HIFI, hifi); | 1146 | snd_soc_write(codec, WM8753_HIFI, hifi); |
1194 | return 0; | 1147 | return 0; |
1195 | } | 1148 | } |
1196 | 1149 | ||
@@ -1201,8 +1154,8 @@ static int wm8753_mode1v_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
1201 | u16 clock; | 1154 | u16 clock; |
1202 | 1155 | ||
1203 | /* set clk source as pcmclk */ | 1156 | /* set clk source as pcmclk */ |
1204 | clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb; | 1157 | clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb; |
1205 | wm8753_write(codec, WM8753_CLOCK, clock); | 1158 | snd_soc_write(codec, WM8753_CLOCK, clock); |
1206 | 1159 | ||
1207 | if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) | 1160 | if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) |
1208 | return -EINVAL; | 1161 | return -EINVAL; |
@@ -1224,8 +1177,8 @@ static int wm8753_mode2_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
1224 | u16 clock; | 1177 | u16 clock; |
1225 | 1178 | ||
1226 | /* set clk source as pcmclk */ | 1179 | /* set clk source as pcmclk */ |
1227 | clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb; | 1180 | clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb; |
1228 | wm8753_write(codec, WM8753_CLOCK, clock); | 1181 | snd_soc_write(codec, WM8753_CLOCK, clock); |
1229 | 1182 | ||
1230 | if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) | 1183 | if (wm8753_vdac_adc_set_dai_fmt(codec_dai, fmt) < 0) |
1231 | return -EINVAL; | 1184 | return -EINVAL; |
@@ -1239,8 +1192,8 @@ static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
1239 | u16 clock; | 1192 | u16 clock; |
1240 | 1193 | ||
1241 | /* set clk source as mclk */ | 1194 | /* set clk source as mclk */ |
1242 | clock = wm8753_read_reg_cache(codec, WM8753_CLOCK) & 0xfffb; | 1195 | clock = snd_soc_read(codec, WM8753_CLOCK) & 0xfffb; |
1243 | wm8753_write(codec, WM8753_CLOCK, clock | 0x4); | 1196 | snd_soc_write(codec, WM8753_CLOCK, clock | 0x4); |
1244 | 1197 | ||
1245 | if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0) | 1198 | if (wm8753_hdac_set_dai_fmt(codec_dai, fmt) < 0) |
1246 | return -EINVAL; | 1199 | return -EINVAL; |
@@ -1252,19 +1205,19 @@ static int wm8753_mode3_4_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
1252 | static int wm8753_mute(struct snd_soc_dai *dai, int mute) | 1205 | static int wm8753_mute(struct snd_soc_dai *dai, int mute) |
1253 | { | 1206 | { |
1254 | struct snd_soc_codec *codec = dai->codec; | 1207 | struct snd_soc_codec *codec = dai->codec; |
1255 | u16 mute_reg = wm8753_read_reg_cache(codec, WM8753_DAC) & 0xfff7; | 1208 | u16 mute_reg = snd_soc_read(codec, WM8753_DAC) & 0xfff7; |
1256 | struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); | 1209 | struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); |
1257 | 1210 | ||
1258 | /* the digital mute covers the HiFi and Voice DAC's on the WM8753. | 1211 | /* the digital mute covers the HiFi and Voice DAC's on the WM8753. |
1259 | * make sure we check if they are not both active when we mute */ | 1212 | * make sure we check if they are not both active when we mute */ |
1260 | if (mute && wm8753->dai_func == 1) { | 1213 | if (mute && wm8753->dai_func == 1) { |
1261 | if (!codec->active) | 1214 | if (!codec->active) |
1262 | wm8753_write(codec, WM8753_DAC, mute_reg | 0x8); | 1215 | snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8); |
1263 | } else { | 1216 | } else { |
1264 | if (mute) | 1217 | if (mute) |
1265 | wm8753_write(codec, WM8753_DAC, mute_reg | 0x8); | 1218 | snd_soc_write(codec, WM8753_DAC, mute_reg | 0x8); |
1266 | else | 1219 | else |
1267 | wm8753_write(codec, WM8753_DAC, mute_reg); | 1220 | snd_soc_write(codec, WM8753_DAC, mute_reg); |
1268 | } | 1221 | } |
1269 | 1222 | ||
1270 | return 0; | 1223 | return 0; |
@@ -1273,23 +1226,23 @@ static int wm8753_mute(struct snd_soc_dai *dai, int mute) | |||
1273 | static int wm8753_set_bias_level(struct snd_soc_codec *codec, | 1226 | static int wm8753_set_bias_level(struct snd_soc_codec *codec, |
1274 | enum snd_soc_bias_level level) | 1227 | enum snd_soc_bias_level level) |
1275 | { | 1228 | { |
1276 | u16 pwr_reg = wm8753_read_reg_cache(codec, WM8753_PWR1) & 0xfe3e; | 1229 | u16 pwr_reg = snd_soc_read(codec, WM8753_PWR1) & 0xfe3e; |
1277 | 1230 | ||
1278 | switch (level) { | 1231 | switch (level) { |
1279 | case SND_SOC_BIAS_ON: | 1232 | case SND_SOC_BIAS_ON: |
1280 | /* set vmid to 50k and unmute dac */ | 1233 | /* set vmid to 50k and unmute dac */ |
1281 | wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x00c0); | 1234 | snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x00c0); |
1282 | break; | 1235 | break; |
1283 | case SND_SOC_BIAS_PREPARE: | 1236 | case SND_SOC_BIAS_PREPARE: |
1284 | /* set vmid to 5k for quick power up */ | 1237 | /* set vmid to 5k for quick power up */ |
1285 | wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x01c1); | 1238 | snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x01c1); |
1286 | break; | 1239 | break; |
1287 | case SND_SOC_BIAS_STANDBY: | 1240 | case SND_SOC_BIAS_STANDBY: |
1288 | /* mute dac and set vmid to 500k, enable VREF */ | 1241 | /* mute dac and set vmid to 500k, enable VREF */ |
1289 | wm8753_write(codec, WM8753_PWR1, pwr_reg | 0x0141); | 1242 | snd_soc_write(codec, WM8753_PWR1, pwr_reg | 0x0141); |
1290 | break; | 1243 | break; |
1291 | case SND_SOC_BIAS_OFF: | 1244 | case SND_SOC_BIAS_OFF: |
1292 | wm8753_write(codec, WM8753_PWR1, 0x0001); | 1245 | snd_soc_write(codec, WM8753_PWR1, 0x0001); |
1293 | break; | 1246 | break; |
1294 | } | 1247 | } |
1295 | codec->bias_level = level; | 1248 | codec->bias_level = level; |
@@ -1477,7 +1430,7 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec, | |||
1477 | else | 1430 | else |
1478 | dai->driver = &wm8753_all_dai[(wm8753->dai_func << 1) + 1]; | 1431 | dai->driver = &wm8753_all_dai[(wm8753->dai_func << 1) + 1]; |
1479 | } | 1432 | } |
1480 | wm8753_write(codec, WM8753_IOCTL, wm8753->dai_func); | 1433 | snd_soc_write(codec, WM8753_IOCTL, wm8753->dai_func); |
1481 | } | 1434 | } |
1482 | 1435 | ||
1483 | static void wm8753_work(struct work_struct *work) | 1436 | static void wm8753_work(struct work_struct *work) |
@@ -1495,22 +1448,19 @@ static int wm8753_suspend(struct snd_soc_codec *codec, pm_message_t state) | |||
1495 | 1448 | ||
1496 | static int wm8753_resume(struct snd_soc_codec *codec) | 1449 | static int wm8753_resume(struct snd_soc_codec *codec) |
1497 | { | 1450 | { |
1451 | u16 *reg_cache = codec->reg_cache; | ||
1498 | int i; | 1452 | int i; |
1499 | u8 data[2]; | ||
1500 | u16 *cache = codec->reg_cache; | ||
1501 | 1453 | ||
1502 | /* Sync reg_cache with the hardware */ | 1454 | /* Sync reg_cache with the hardware */ |
1503 | for (i = 0; i < ARRAY_SIZE(wm8753_reg); i++) { | 1455 | for (i = 1; i < ARRAY_SIZE(wm8753_reg); i++) { |
1504 | if (i + 1 == WM8753_RESET) | 1456 | if (i == WM8753_RESET) |
1505 | continue; | 1457 | continue; |
1506 | 1458 | ||
1507 | /* No point in writing hardware default values back */ | 1459 | /* No point in writing hardware default values back */ |
1508 | if (cache[i] == wm8753_reg[i]) | 1460 | if (reg_cache[i] == wm8753_reg[i]) |
1509 | continue; | 1461 | continue; |
1510 | 1462 | ||
1511 | data[0] = ((i + 1) << 1) | ((cache[i] >> 8) & 0x0001); | 1463 | snd_soc_write(codec, i, reg_cache[i]); |
1512 | data[1] = cache[i] & 0x00ff; | ||
1513 | codec->hw_write(codec->control_data, data, 2); | ||
1514 | } | 1464 | } |
1515 | 1465 | ||
1516 | wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1466 | wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
@@ -1548,7 +1498,7 @@ static int run_delayed_work(struct delayed_work *dwork) | |||
1548 | static int wm8753_probe(struct snd_soc_codec *codec) | 1498 | static int wm8753_probe(struct snd_soc_codec *codec) |
1549 | { | 1499 | { |
1550 | struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); | 1500 | struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); |
1551 | int ret = 0, reg; | 1501 | int ret; |
1552 | 1502 | ||
1553 | INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work); | 1503 | INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work); |
1554 | 1504 | ||
@@ -1573,26 +1523,16 @@ static int wm8753_probe(struct snd_soc_codec *codec) | |||
1573 | msecs_to_jiffies(caps_charge)); | 1523 | msecs_to_jiffies(caps_charge)); |
1574 | 1524 | ||
1575 | /* set the update bits */ | 1525 | /* set the update bits */ |
1576 | reg = wm8753_read_reg_cache(codec, WM8753_LDAC); | 1526 | snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100); |
1577 | wm8753_write(codec, WM8753_LDAC, reg | 0x0100); | 1527 | snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100); |
1578 | reg = wm8753_read_reg_cache(codec, WM8753_RDAC); | 1528 | snd_soc_update_bits(codec, WM8753_LDAC, 0x0100, 0x0100); |
1579 | wm8753_write(codec, WM8753_RDAC, reg | 0x0100); | 1529 | snd_soc_update_bits(codec, WM8753_RDAC, 0x0100, 0x0100); |
1580 | reg = wm8753_read_reg_cache(codec, WM8753_LADC); | 1530 | snd_soc_update_bits(codec, WM8753_LOUT1V, 0x0100, 0x0100); |
1581 | wm8753_write(codec, WM8753_LADC, reg | 0x0100); | 1531 | snd_soc_update_bits(codec, WM8753_ROUT1V, 0x0100, 0x0100); |
1582 | reg = wm8753_read_reg_cache(codec, WM8753_RADC); | 1532 | snd_soc_update_bits(codec, WM8753_LOUT2V, 0x0100, 0x0100); |
1583 | wm8753_write(codec, WM8753_RADC, reg | 0x0100); | 1533 | snd_soc_update_bits(codec, WM8753_ROUT2V, 0x0100, 0x0100); |
1584 | reg = wm8753_read_reg_cache(codec, WM8753_LOUT1V); | 1534 | snd_soc_update_bits(codec, WM8753_LINVOL, 0x0100, 0x0100); |
1585 | wm8753_write(codec, WM8753_LOUT1V, reg | 0x0100); | 1535 | snd_soc_update_bits(codec, WM8753_RINVOL, 0x0100, 0x0100); |
1586 | reg = wm8753_read_reg_cache(codec, WM8753_ROUT1V); | ||
1587 | wm8753_write(codec, WM8753_ROUT1V, reg | 0x0100); | ||
1588 | reg = wm8753_read_reg_cache(codec, WM8753_LOUT2V); | ||
1589 | wm8753_write(codec, WM8753_LOUT2V, reg | 0x0100); | ||
1590 | reg = wm8753_read_reg_cache(codec, WM8753_ROUT2V); | ||
1591 | wm8753_write(codec, WM8753_ROUT2V, reg | 0x0100); | ||
1592 | reg = wm8753_read_reg_cache(codec, WM8753_LINVOL); | ||
1593 | wm8753_write(codec, WM8753_LINVOL, reg | 0x0100); | ||
1594 | reg = wm8753_read_reg_cache(codec, WM8753_RINVOL); | ||
1595 | wm8753_write(codec, WM8753_RINVOL, reg | 0x0100); | ||
1596 | 1536 | ||
1597 | snd_soc_add_controls(codec, wm8753_snd_controls, | 1537 | snd_soc_add_controls(codec, wm8753_snd_controls, |
1598 | ARRAY_SIZE(wm8753_snd_controls)); | 1538 | ARRAY_SIZE(wm8753_snd_controls)); |
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index fca60a0b57b8..1ec12eff0620 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c | |||
@@ -50,8 +50,6 @@ static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = { | |||
50 | /* codec private data */ | 50 | /* codec private data */ |
51 | struct wm8904_priv { | 51 | struct wm8904_priv { |
52 | 52 | ||
53 | u16 reg_cache[WM8904_MAX_REGISTER + 1]; | ||
54 | |||
55 | enum wm8904_type devtype; | 53 | enum wm8904_type devtype; |
56 | void *control_data; | 54 | void *control_data; |
57 | 55 | ||
@@ -818,7 +816,8 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol, | |||
818 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 816 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
819 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); | 817 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
820 | 818 | ||
821 | return wm8904->deemph; | 819 | ucontrol->value.enumerated.item[0] = wm8904->deemph; |
820 | return 0; | ||
822 | } | 821 | } |
823 | 822 | ||
824 | static int wm8904_put_deemph(struct snd_kcontrol *kcontrol, | 823 | static int wm8904_put_deemph(struct snd_kcontrol *kcontrol, |
@@ -2093,7 +2092,7 @@ static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute) | |||
2093 | 2092 | ||
2094 | static void wm8904_sync_cache(struct snd_soc_codec *codec) | 2093 | static void wm8904_sync_cache(struct snd_soc_codec *codec) |
2095 | { | 2094 | { |
2096 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); | 2095 | u16 *reg_cache = codec->reg_cache; |
2097 | int i; | 2096 | int i; |
2098 | 2097 | ||
2099 | if (!codec->cache_sync) | 2098 | if (!codec->cache_sync) |
@@ -2104,14 +2103,14 @@ static void wm8904_sync_cache(struct snd_soc_codec *codec) | |||
2104 | /* Sync back cached values if they're different from the | 2103 | /* Sync back cached values if they're different from the |
2105 | * hardware default. | 2104 | * hardware default. |
2106 | */ | 2105 | */ |
2107 | for (i = 1; i < ARRAY_SIZE(wm8904->reg_cache); i++) { | 2106 | for (i = 1; i < codec->driver->reg_cache_size; i++) { |
2108 | if (!wm8904_access[i].writable) | 2107 | if (!wm8904_access[i].writable) |
2109 | continue; | 2108 | continue; |
2110 | 2109 | ||
2111 | if (wm8904->reg_cache[i] == wm8904_reg[i]) | 2110 | if (reg_cache[i] == wm8904_reg[i]) |
2112 | continue; | 2111 | continue; |
2113 | 2112 | ||
2114 | snd_soc_write(codec, i, wm8904->reg_cache[i]); | 2113 | snd_soc_write(codec, i, reg_cache[i]); |
2115 | } | 2114 | } |
2116 | 2115 | ||
2117 | codec->cache_sync = 0; | 2116 | codec->cache_sync = 0; |
@@ -2370,6 +2369,7 @@ static int wm8904_probe(struct snd_soc_codec *codec) | |||
2370 | { | 2369 | { |
2371 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); | 2370 | struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
2372 | struct wm8904_pdata *pdata = wm8904->pdata; | 2371 | struct wm8904_pdata *pdata = wm8904->pdata; |
2372 | u16 *reg_cache = codec->reg_cache; | ||
2373 | int ret, i; | 2373 | int ret, i; |
2374 | 2374 | ||
2375 | codec->cache_sync = 1; | 2375 | codec->cache_sync = 1; |
@@ -2436,19 +2436,19 @@ static int wm8904_probe(struct snd_soc_codec *codec) | |||
2436 | } | 2436 | } |
2437 | 2437 | ||
2438 | /* Change some default settings - latch VU and enable ZC */ | 2438 | /* Change some default settings - latch VU and enable ZC */ |
2439 | wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU; | 2439 | reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU; |
2440 | wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU; | 2440 | reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU; |
2441 | wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU; | 2441 | reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU; |
2442 | wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU; | 2442 | reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU; |
2443 | wm8904->reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU | | 2443 | reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU | |
2444 | WM8904_HPOUTLZC; | 2444 | WM8904_HPOUTLZC; |
2445 | wm8904->reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU | | 2445 | reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU | |
2446 | WM8904_HPOUTRZC; | 2446 | WM8904_HPOUTRZC; |
2447 | wm8904->reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU | | 2447 | reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU | |
2448 | WM8904_LINEOUTLZC; | 2448 | WM8904_LINEOUTLZC; |
2449 | wm8904->reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU | | 2449 | reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU | |
2450 | WM8904_LINEOUTRZC; | 2450 | WM8904_LINEOUTRZC; |
2451 | wm8904->reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE; | 2451 | reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE; |
2452 | 2452 | ||
2453 | /* Apply configuration from the platform data. */ | 2453 | /* Apply configuration from the platform data. */ |
2454 | if (wm8904->pdata) { | 2454 | if (wm8904->pdata) { |
@@ -2456,23 +2456,23 @@ static int wm8904_probe(struct snd_soc_codec *codec) | |||
2456 | if (!pdata->gpio_cfg[i]) | 2456 | if (!pdata->gpio_cfg[i]) |
2457 | continue; | 2457 | continue; |
2458 | 2458 | ||
2459 | wm8904->reg_cache[WM8904_GPIO_CONTROL_1 + i] | 2459 | reg_cache[WM8904_GPIO_CONTROL_1 + i] |
2460 | = pdata->gpio_cfg[i] & 0xffff; | 2460 | = pdata->gpio_cfg[i] & 0xffff; |
2461 | } | 2461 | } |
2462 | 2462 | ||
2463 | /* Zero is the default value for these anyway */ | 2463 | /* Zero is the default value for these anyway */ |
2464 | for (i = 0; i < WM8904_MIC_REGS; i++) | 2464 | for (i = 0; i < WM8904_MIC_REGS; i++) |
2465 | wm8904->reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i] | 2465 | reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i] |
2466 | = pdata->mic_cfg[i]; | 2466 | = pdata->mic_cfg[i]; |
2467 | } | 2467 | } |
2468 | 2468 | ||
2469 | /* Set Class W by default - this will be managed by the Class | 2469 | /* Set Class W by default - this will be managed by the Class |
2470 | * G widget at runtime where bypass paths are available. | 2470 | * G widget at runtime where bypass paths are available. |
2471 | */ | 2471 | */ |
2472 | wm8904->reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR; | 2472 | reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR; |
2473 | 2473 | ||
2474 | /* Use normal bias source */ | 2474 | /* Use normal bias source */ |
2475 | wm8904->reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL; | 2475 | reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL; |
2476 | 2476 | ||
2477 | wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 2477 | wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
2478 | 2478 | ||
diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 2cb16f895c46..23086e2c976a 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c | |||
@@ -768,6 +768,7 @@ static __devinit int wm8940_i2c_probe(struct i2c_client *i2c, | |||
768 | 768 | ||
769 | i2c_set_clientdata(i2c, wm8940); | 769 | i2c_set_clientdata(i2c, wm8940); |
770 | wm8940->control_data = i2c; | 770 | wm8940->control_data = i2c; |
771 | wm8940->control_type = SND_SOC_I2C; | ||
771 | 772 | ||
772 | ret = snd_soc_register_codec(&i2c->dev, | 773 | ret = snd_soc_register_codec(&i2c->dev, |
773 | &soc_codec_dev_wm8940, &wm8940_dai, 1); | 774 | &soc_codec_dev_wm8940, &wm8940_dai, 1); |
diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index f89ad6c9a80b..2ac35b0be86a 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c | |||
@@ -42,8 +42,6 @@ static const char *wm8955_supply_names[WM8955_NUM_SUPPLIES] = { | |||
42 | struct wm8955_priv { | 42 | struct wm8955_priv { |
43 | enum snd_soc_control_type control_type; | 43 | enum snd_soc_control_type control_type; |
44 | 44 | ||
45 | u16 reg_cache[WM8955_MAX_REGISTER + 1]; | ||
46 | |||
47 | unsigned int mclk_rate; | 45 | unsigned int mclk_rate; |
48 | 46 | ||
49 | int deemph; | 47 | int deemph; |
@@ -380,7 +378,8 @@ static int wm8955_get_deemph(struct snd_kcontrol *kcontrol, | |||
380 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 378 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
381 | struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); | 379 | struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); |
382 | 380 | ||
383 | return wm8955->deemph; | 381 | ucontrol->value.enumerated.item[0] = wm8955->deemph; |
382 | return 0; | ||
384 | } | 383 | } |
385 | 384 | ||
386 | static int wm8955_put_deemph(struct snd_kcontrol *kcontrol, | 385 | static int wm8955_put_deemph(struct snd_kcontrol *kcontrol, |
@@ -767,6 +766,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec, | |||
767 | enum snd_soc_bias_level level) | 766 | enum snd_soc_bias_level level) |
768 | { | 767 | { |
769 | struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); | 768 | struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); |
769 | u16 *reg_cache = codec->reg_cache; | ||
770 | int ret, i; | 770 | int ret, i; |
771 | 771 | ||
772 | switch (level) { | 772 | switch (level) { |
@@ -799,14 +799,14 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec, | |||
799 | /* Sync back cached values if they're | 799 | /* Sync back cached values if they're |
800 | * different from the hardware default. | 800 | * different from the hardware default. |
801 | */ | 801 | */ |
802 | for (i = 0; i < ARRAY_SIZE(wm8955->reg_cache); i++) { | 802 | for (i = 0; i < codec->driver->reg_cache_size; i++) { |
803 | if (i == WM8955_RESET) | 803 | if (i == WM8955_RESET) |
804 | continue; | 804 | continue; |
805 | 805 | ||
806 | if (wm8955->reg_cache[i] == wm8955_reg[i]) | 806 | if (reg_cache[i] == wm8955_reg[i]) |
807 | continue; | 807 | continue; |
808 | 808 | ||
809 | snd_soc_write(codec, i, wm8955->reg_cache[i]); | 809 | snd_soc_write(codec, i, reg_cache[i]); |
810 | } | 810 | } |
811 | 811 | ||
812 | /* Enable VREF and VMID */ | 812 | /* Enable VREF and VMID */ |
@@ -901,6 +901,7 @@ static int wm8955_probe(struct snd_soc_codec *codec) | |||
901 | { | 901 | { |
902 | struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); | 902 | struct wm8955_priv *wm8955 = snd_soc_codec_get_drvdata(codec); |
903 | struct wm8955_pdata *pdata = dev_get_platdata(codec->dev); | 903 | struct wm8955_pdata *pdata = dev_get_platdata(codec->dev); |
904 | u16 *reg_cache = codec->reg_cache; | ||
904 | int ret, i; | 905 | int ret, i; |
905 | 906 | ||
906 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8955->control_type); | 907 | ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8955->control_type); |
@@ -933,25 +934,25 @@ static int wm8955_probe(struct snd_soc_codec *codec) | |||
933 | } | 934 | } |
934 | 935 | ||
935 | /* Change some default settings - latch VU and enable ZC */ | 936 | /* Change some default settings - latch VU and enable ZC */ |
936 | wm8955->reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU; | 937 | reg_cache[WM8955_LEFT_DAC_VOLUME] |= WM8955_LDVU; |
937 | wm8955->reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU; | 938 | reg_cache[WM8955_RIGHT_DAC_VOLUME] |= WM8955_RDVU; |
938 | wm8955->reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC; | 939 | reg_cache[WM8955_LOUT1_VOLUME] |= WM8955_LO1VU | WM8955_LO1ZC; |
939 | wm8955->reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC; | 940 | reg_cache[WM8955_ROUT1_VOLUME] |= WM8955_RO1VU | WM8955_RO1ZC; |
940 | wm8955->reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC; | 941 | reg_cache[WM8955_LOUT2_VOLUME] |= WM8955_LO2VU | WM8955_LO2ZC; |
941 | wm8955->reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC; | 942 | reg_cache[WM8955_ROUT2_VOLUME] |= WM8955_RO2VU | WM8955_RO2ZC; |
942 | wm8955->reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC; | 943 | reg_cache[WM8955_MONOOUT_VOLUME] |= WM8955_MOZC; |
943 | 944 | ||
944 | /* Also enable adaptive bass boost by default */ | 945 | /* Also enable adaptive bass boost by default */ |
945 | wm8955->reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB; | 946 | reg_cache[WM8955_BASS_CONTROL] |= WM8955_BB; |
946 | 947 | ||
947 | /* Set platform data values */ | 948 | /* Set platform data values */ |
948 | if (pdata) { | 949 | if (pdata) { |
949 | if (pdata->out2_speaker) | 950 | if (pdata->out2_speaker) |
950 | wm8955->reg_cache[WM8955_ADDITIONAL_CONTROL_2] | 951 | reg_cache[WM8955_ADDITIONAL_CONTROL_2] |
951 | |= WM8955_ROUT2INV; | 952 | |= WM8955_ROUT2INV; |
952 | 953 | ||
953 | if (pdata->monoin_diff) | 954 | if (pdata->monoin_diff) |
954 | wm8955->reg_cache[WM8955_MONO_OUT_MIX_1] | 955 | reg_cache[WM8955_MONO_OUT_MIX_1] |
955 | |= WM8955_DMEN; | 956 | |= WM8955_DMEN; |
956 | } | 957 | } |
957 | 958 | ||
@@ -1002,6 +1003,7 @@ static __devinit int wm8955_i2c_probe(struct i2c_client *i2c, | |||
1002 | return -ENOMEM; | 1003 | return -ENOMEM; |
1003 | 1004 | ||
1004 | i2c_set_clientdata(i2c, wm8955); | 1005 | i2c_set_clientdata(i2c, wm8955); |
1006 | wm8955->control_type = SND_SOC_I2C; | ||
1005 | 1007 | ||
1006 | ret = snd_soc_register_codec(&i2c->dev, | 1008 | ret = snd_soc_register_codec(&i2c->dev, |
1007 | &soc_codec_dev_wm8955, &wm8955_dai, 1); | 1009 | &soc_codec_dev_wm8955, &wm8955_dai, 1); |
diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 8d5efb333c33..ff6ff2f529d2 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c | |||
@@ -138,7 +138,8 @@ static int wm8960_get_deemph(struct snd_kcontrol *kcontrol, | |||
138 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 138 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
139 | struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); | 139 | struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); |
140 | 140 | ||
141 | return wm8960->deemph; | 141 | ucontrol->value.enumerated.item[0] = wm8960->deemph; |
142 | return 0; | ||
142 | } | 143 | } |
143 | 144 | ||
144 | static int wm8960_put_deemph(struct snd_kcontrol *kcontrol, | 145 | static int wm8960_put_deemph(struct snd_kcontrol *kcontrol, |
@@ -1012,6 +1013,7 @@ static __devinit int wm8960_i2c_probe(struct i2c_client *i2c, | |||
1012 | return -ENOMEM; | 1013 | return -ENOMEM; |
1013 | 1014 | ||
1014 | i2c_set_clientdata(i2c, wm8960); | 1015 | i2c_set_clientdata(i2c, wm8960); |
1016 | wm8960->control_type = SND_SOC_I2C; | ||
1015 | wm8960->control_data = i2c; | 1017 | wm8960->control_data = i2c; |
1016 | 1018 | ||
1017 | ret = snd_soc_register_codec(&i2c->dev, | 1019 | ret = snd_soc_register_codec(&i2c->dev, |
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index e8092745a207..7c421cc837bd 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
@@ -52,8 +52,6 @@ static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = { | |||
52 | struct wm8962_priv { | 52 | struct wm8962_priv { |
53 | struct snd_soc_codec *codec; | 53 | struct snd_soc_codec *codec; |
54 | 54 | ||
55 | u16 reg_cache[WM8962_MAX_REGISTER + 1]; | ||
56 | |||
57 | int sysclk; | 55 | int sysclk; |
58 | int sysclk_rate; | 56 | int sysclk_rate; |
59 | 57 | ||
@@ -1991,8 +1989,7 @@ static int wm8962_put_hp_sw(struct snd_kcontrol *kcontrol, | |||
1991 | struct snd_ctl_elem_value *ucontrol) | 1989 | struct snd_ctl_elem_value *ucontrol) |
1992 | { | 1990 | { |
1993 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 1991 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
1994 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | 1992 | u16 *reg_cache = codec->reg_cache; |
1995 | u16 *reg_cache = wm8962->reg_cache; | ||
1996 | int ret; | 1993 | int ret; |
1997 | 1994 | ||
1998 | /* Apply the update (if any) */ | 1995 | /* Apply the update (if any) */ |
@@ -2020,8 +2017,7 @@ static int wm8962_put_spk_sw(struct snd_kcontrol *kcontrol, | |||
2020 | struct snd_ctl_elem_value *ucontrol) | 2017 | struct snd_ctl_elem_value *ucontrol) |
2021 | { | 2018 | { |
2022 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 2019 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
2023 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | 2020 | u16 *reg_cache = codec->reg_cache; |
2024 | u16 *reg_cache = wm8962->reg_cache; | ||
2025 | int ret; | 2021 | int ret; |
2026 | 2022 | ||
2027 | /* Apply the update (if any) */ | 2023 | /* Apply the update (if any) */ |
@@ -2329,8 +2325,7 @@ static int out_pga_event(struct snd_soc_dapm_widget *w, | |||
2329 | struct snd_kcontrol *kcontrol, int event) | 2325 | struct snd_kcontrol *kcontrol, int event) |
2330 | { | 2326 | { |
2331 | struct snd_soc_codec *codec = w->codec; | 2327 | struct snd_soc_codec *codec = w->codec; |
2332 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | 2328 | u16 *reg_cache = codec->reg_cache; |
2333 | u16 *reg_cache = wm8962->reg_cache; | ||
2334 | int reg; | 2329 | int reg; |
2335 | 2330 | ||
2336 | switch (w->shift) { | 2331 | switch (w->shift) { |
@@ -2719,7 +2714,7 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec) | |||
2719 | 2714 | ||
2720 | static void wm8962_sync_cache(struct snd_soc_codec *codec) | 2715 | static void wm8962_sync_cache(struct snd_soc_codec *codec) |
2721 | { | 2716 | { |
2722 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | 2717 | u16 *reg_cache = codec->reg_cache; |
2723 | int i; | 2718 | int i; |
2724 | 2719 | ||
2725 | if (!codec->cache_sync) | 2720 | if (!codec->cache_sync) |
@@ -2732,13 +2727,13 @@ static void wm8962_sync_cache(struct snd_soc_codec *codec) | |||
2732 | /* Sync back cached values if they're different from the | 2727 | /* Sync back cached values if they're different from the |
2733 | * hardware default. | 2728 | * hardware default. |
2734 | */ | 2729 | */ |
2735 | for (i = 1; i < ARRAY_SIZE(wm8962->reg_cache); i++) { | 2730 | for (i = 1; i < codec->driver->reg_cache_size; i++) { |
2736 | if (i == WM8962_SOFTWARE_RESET) | 2731 | if (i == WM8962_SOFTWARE_RESET) |
2737 | continue; | 2732 | continue; |
2738 | if (wm8962->reg_cache[i] == wm8962_reg[i]) | 2733 | if (reg_cache[i] == wm8962_reg[i]) |
2739 | continue; | 2734 | continue; |
2740 | 2735 | ||
2741 | snd_soc_write(codec, i, wm8962->reg_cache[i]); | 2736 | snd_soc_write(codec, i, reg_cache[i]); |
2742 | } | 2737 | } |
2743 | 2738 | ||
2744 | codec->cache_sync = 0; | 2739 | codec->cache_sync = 0; |
@@ -3339,7 +3334,7 @@ static irqreturn_t wm8962_irq(int irq, void *data) | |||
3339 | int mask; | 3334 | int mask; |
3340 | int active; | 3335 | int active; |
3341 | 3336 | ||
3342 | mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2); | 3337 | mask = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2_MASK); |
3343 | 3338 | ||
3344 | active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2); | 3339 | active = snd_soc_read(codec, WM8962_INTERRUPT_STATUS_2); |
3345 | active &= ~mask; | 3340 | active &= ~mask; |
@@ -3406,12 +3401,11 @@ EXPORT_SYMBOL_GPL(wm8962_mic_detect); | |||
3406 | #ifdef CONFIG_PM | 3401 | #ifdef CONFIG_PM |
3407 | static int wm8962_resume(struct snd_soc_codec *codec) | 3402 | static int wm8962_resume(struct snd_soc_codec *codec) |
3408 | { | 3403 | { |
3409 | struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | ||
3410 | u16 *reg_cache = codec->reg_cache; | 3404 | u16 *reg_cache = codec->reg_cache; |
3411 | int i; | 3405 | int i; |
3412 | 3406 | ||
3413 | /* Restore the registers */ | 3407 | /* Restore the registers */ |
3414 | for (i = 1; i < ARRAY_SIZE(wm8962->reg_cache); i++) { | 3408 | for (i = 1; i < codec->driver->reg_cache_size; i++) { |
3415 | switch (i) { | 3409 | switch (i) { |
3416 | case WM8962_SOFTWARE_RESET: | 3410 | case WM8962_SOFTWARE_RESET: |
3417 | continue; | 3411 | continue; |
@@ -3705,6 +3699,7 @@ static int wm8962_probe(struct snd_soc_codec *codec) | |||
3705 | struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); | 3699 | struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); |
3706 | struct i2c_client *i2c = container_of(codec->dev, struct i2c_client, | 3700 | struct i2c_client *i2c = container_of(codec->dev, struct i2c_client, |
3707 | dev); | 3701 | dev); |
3702 | u16 *reg_cache = codec->reg_cache; | ||
3708 | int i, trigger, irq_pol; | 3703 | int i, trigger, irq_pol; |
3709 | 3704 | ||
3710 | wm8962->codec = codec; | 3705 | wm8962->codec = codec; |
@@ -3804,7 +3799,7 @@ static int wm8962_probe(struct snd_soc_codec *codec) | |||
3804 | 3799 | ||
3805 | /* Put the speakers into mono mode? */ | 3800 | /* Put the speakers into mono mode? */ |
3806 | if (pdata->spk_mono) | 3801 | if (pdata->spk_mono) |
3807 | wm8962->reg_cache[WM8962_CLASS_D_CONTROL_2] | 3802 | reg_cache[WM8962_CLASS_D_CONTROL_2] |
3808 | |= WM8962_SPK_MONO; | 3803 | |= WM8962_SPK_MONO; |
3809 | 3804 | ||
3810 | /* Micbias setup, detection enable and detection | 3805 | /* Micbias setup, detection enable and detection |
@@ -3819,16 +3814,16 @@ static int wm8962_probe(struct snd_soc_codec *codec) | |||
3819 | } | 3814 | } |
3820 | 3815 | ||
3821 | /* Latch volume update bits */ | 3816 | /* Latch volume update bits */ |
3822 | wm8962->reg_cache[WM8962_LEFT_INPUT_VOLUME] |= WM8962_IN_VU; | 3817 | reg_cache[WM8962_LEFT_INPUT_VOLUME] |= WM8962_IN_VU; |
3823 | wm8962->reg_cache[WM8962_RIGHT_INPUT_VOLUME] |= WM8962_IN_VU; | 3818 | reg_cache[WM8962_RIGHT_INPUT_VOLUME] |= WM8962_IN_VU; |
3824 | wm8962->reg_cache[WM8962_LEFT_ADC_VOLUME] |= WM8962_ADC_VU; | 3819 | reg_cache[WM8962_LEFT_ADC_VOLUME] |= WM8962_ADC_VU; |
3825 | wm8962->reg_cache[WM8962_RIGHT_ADC_VOLUME] |= WM8962_ADC_VU; | 3820 | reg_cache[WM8962_RIGHT_ADC_VOLUME] |= WM8962_ADC_VU; |
3826 | wm8962->reg_cache[WM8962_LEFT_DAC_VOLUME] |= WM8962_DAC_VU; | 3821 | reg_cache[WM8962_LEFT_DAC_VOLUME] |= WM8962_DAC_VU; |
3827 | wm8962->reg_cache[WM8962_RIGHT_DAC_VOLUME] |= WM8962_DAC_VU; | 3822 | reg_cache[WM8962_RIGHT_DAC_VOLUME] |= WM8962_DAC_VU; |
3828 | wm8962->reg_cache[WM8962_SPKOUTL_VOLUME] |= WM8962_SPKOUT_VU; | 3823 | reg_cache[WM8962_SPKOUTL_VOLUME] |= WM8962_SPKOUT_VU; |
3829 | wm8962->reg_cache[WM8962_SPKOUTR_VOLUME] |= WM8962_SPKOUT_VU; | 3824 | reg_cache[WM8962_SPKOUTR_VOLUME] |= WM8962_SPKOUT_VU; |
3830 | wm8962->reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU; | 3825 | reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU; |
3831 | wm8962->reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU; | 3826 | reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU; |
3832 | 3827 | ||
3833 | wm8962_add_widgets(codec); | 3828 | wm8962_add_widgets(codec); |
3834 | 3829 | ||
diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index 63f6dbf5d070..9f18db6e167c 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c | |||
@@ -718,6 +718,7 @@ static __devinit int wm8971_i2c_probe(struct i2c_client *i2c, | |||
718 | if (wm8971 == NULL) | 718 | if (wm8971 == NULL) |
719 | return -ENOMEM; | 719 | return -ENOMEM; |
720 | 720 | ||
721 | wm8971->control_type = SND_SOC_I2C; | ||
721 | i2c_set_clientdata(i2c, wm8971); | 722 | i2c_set_clientdata(i2c, wm8971); |
722 | 723 | ||
723 | ret = snd_soc_register_codec(&i2c->dev, | 724 | ret = snd_soc_register_codec(&i2c->dev, |
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index ecc7c37180c7..a486670966bd 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c | |||
@@ -1335,6 +1335,7 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c, | |||
1335 | return -ENOMEM; | 1335 | return -ENOMEM; |
1336 | 1336 | ||
1337 | i2c_set_clientdata(i2c, wm9081); | 1337 | i2c_set_clientdata(i2c, wm9081); |
1338 | wm9081->control_type = SND_SOC_I2C; | ||
1338 | wm9081->control_data = i2c; | 1339 | wm9081->control_data = i2c; |
1339 | 1340 | ||
1340 | ret = snd_soc_register_codec(&i2c->dev, | 1341 | ret = snd_soc_register_codec(&i2c->dev, |
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index 99c046ba46bb..6e5f64f627cb 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c | |||
@@ -141,7 +141,6 @@ static const u16 wm9090_reg_defaults[] = { | |||
141 | /* This struct is used to save the context */ | 141 | /* This struct is used to save the context */ |
142 | struct wm9090_priv { | 142 | struct wm9090_priv { |
143 | struct mutex mutex; | 143 | struct mutex mutex; |
144 | u16 reg_cache[WM9090_MAX_REGISTER + 1]; | ||
145 | struct wm9090_platform_data pdata; | 144 | struct wm9090_platform_data pdata; |
146 | void *control_data; | 145 | void *control_data; |
147 | }; | 146 | }; |
@@ -552,6 +551,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec, | |||
552 | static int wm9090_probe(struct snd_soc_codec *codec) | 551 | static int wm9090_probe(struct snd_soc_codec *codec) |
553 | { | 552 | { |
554 | struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec); | 553 | struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec); |
554 | u16 *reg_cache = codec->reg_cache; | ||
555 | int ret; | 555 | int ret; |
556 | 556 | ||
557 | codec->control_data = wm9090->control_data; | 557 | codec->control_data = wm9090->control_data; |
@@ -576,22 +576,22 @@ static int wm9090_probe(struct snd_soc_codec *codec) | |||
576 | /* Configure some defaults; they will be written out when we | 576 | /* Configure some defaults; they will be written out when we |
577 | * bring the bias up. | 577 | * bring the bias up. |
578 | */ | 578 | */ |
579 | wm9090->reg_cache[WM9090_IN1_LINE_INPUT_A_VOLUME] |= WM9090_IN1_VU | 579 | reg_cache[WM9090_IN1_LINE_INPUT_A_VOLUME] |= WM9090_IN1_VU |
580 | | WM9090_IN1A_ZC; | 580 | | WM9090_IN1A_ZC; |
581 | wm9090->reg_cache[WM9090_IN1_LINE_INPUT_B_VOLUME] |= WM9090_IN1_VU | 581 | reg_cache[WM9090_IN1_LINE_INPUT_B_VOLUME] |= WM9090_IN1_VU |
582 | | WM9090_IN1B_ZC; | 582 | | WM9090_IN1B_ZC; |
583 | wm9090->reg_cache[WM9090_IN2_LINE_INPUT_A_VOLUME] |= WM9090_IN2_VU | 583 | reg_cache[WM9090_IN2_LINE_INPUT_A_VOLUME] |= WM9090_IN2_VU |
584 | | WM9090_IN2A_ZC; | 584 | | WM9090_IN2A_ZC; |
585 | wm9090->reg_cache[WM9090_IN2_LINE_INPUT_B_VOLUME] |= WM9090_IN2_VU | 585 | reg_cache[WM9090_IN2_LINE_INPUT_B_VOLUME] |= WM9090_IN2_VU |
586 | | WM9090_IN2B_ZC; | 586 | | WM9090_IN2B_ZC; |
587 | wm9090->reg_cache[WM9090_SPEAKER_VOLUME_LEFT] |= | 587 | reg_cache[WM9090_SPEAKER_VOLUME_LEFT] |= |
588 | WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC; | 588 | WM9090_SPKOUT_VU | WM9090_SPKOUTL_ZC; |
589 | wm9090->reg_cache[WM9090_LEFT_OUTPUT_VOLUME] |= | 589 | reg_cache[WM9090_LEFT_OUTPUT_VOLUME] |= |
590 | WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC; | 590 | WM9090_HPOUT1_VU | WM9090_HPOUT1L_ZC; |
591 | wm9090->reg_cache[WM9090_RIGHT_OUTPUT_VOLUME] |= | 591 | reg_cache[WM9090_RIGHT_OUTPUT_VOLUME] |= |
592 | WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC; | 592 | WM9090_HPOUT1_VU | WM9090_HPOUT1R_ZC; |
593 | 593 | ||
594 | wm9090->reg_cache[WM9090_CLOCKING_1] |= WM9090_TOCLK_ENA; | 594 | reg_cache[WM9090_CLOCKING_1] |= WM9090_TOCLK_ENA; |
595 | 595 | ||
596 | wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 596 | wm9090_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
597 | 597 | ||
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 19ca782ac970..0e24092722c3 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c | |||
@@ -293,7 +293,7 @@ SOC_DOUBLE_R("Speaker Switch", | |||
293 | SOC_DOUBLE_R("Speaker ZC Switch", | 293 | SOC_DOUBLE_R("Speaker ZC Switch", |
294 | WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT, | 294 | WM8993_SPEAKER_VOLUME_LEFT, WM8993_SPEAKER_VOLUME_RIGHT, |
295 | 7, 1, 0), | 295 | 7, 1, 0), |
296 | SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 0, 3, 7, 0, | 296 | SOC_DOUBLE_TLV("Speaker Boost Volume", WM8993_SPKOUT_BOOST, 3, 0, 7, 0, |
297 | spkboost_tlv), | 297 | spkboost_tlv), |
298 | SOC_ENUM("Speaker Reference", speaker_ref), | 298 | SOC_ENUM("Speaker Reference", speaker_ref), |
299 | SOC_ENUM("Speaker Mode", speaker_mode), | 299 | SOC_ENUM("Speaker Mode", speaker_mode), |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 441285ade024..85b7d548f167 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -1619,12 +1619,14 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1619 | #ifdef CONFIG_SND_SOC_AC97_BUS | 1619 | #ifdef CONFIG_SND_SOC_AC97_BUS |
1620 | /* register any AC97 codecs */ | 1620 | /* register any AC97 codecs */ |
1621 | for (i = 0; i < card->num_rtd; i++) { | 1621 | for (i = 0; i < card->num_rtd; i++) { |
1622 | ret = soc_register_ac97_dai_link(&card->rtd[i]); | 1622 | ret = soc_register_ac97_dai_link(&card->rtd[i]); |
1623 | if (ret < 0) { | 1623 | if (ret < 0) { |
1624 | printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name); | 1624 | printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name); |
1625 | goto probe_dai_err; | 1625 | while (--i >= 0) |
1626 | } | 1626 | soc_unregister_ac97_dai_link(&card->rtd[i]); |
1627 | goto probe_dai_err; | ||
1627 | } | 1628 | } |
1629 | } | ||
1628 | #endif | 1630 | #endif |
1629 | 1631 | ||
1630 | card->instantiated = 1; | 1632 | card->instantiated = 1; |
@@ -3072,7 +3074,9 @@ int snd_soc_register_dais(struct device *dev, | |||
3072 | pr_debug("Registered DAI '%s'\n", dai->name); | 3074 | pr_debug("Registered DAI '%s'\n", dai->name); |
3073 | } | 3075 | } |
3074 | 3076 | ||
3077 | mutex_lock(&client_mutex); | ||
3075 | snd_soc_instantiate_cards(); | 3078 | snd_soc_instantiate_cards(); |
3079 | mutex_unlock(&client_mutex); | ||
3076 | return 0; | 3080 | return 0; |
3077 | 3081 | ||
3078 | err: | 3082 | err: |
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 75ed6491222d..c721502833bc 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -944,6 +944,9 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) | |||
944 | case SND_SOC_DAPM_STREAM_RESUME: | 944 | case SND_SOC_DAPM_STREAM_RESUME: |
945 | sys_power = 1; | 945 | sys_power = 1; |
946 | break; | 946 | break; |
947 | case SND_SOC_DAPM_STREAM_STOP: | ||
948 | sys_power = !!codec->active; | ||
949 | break; | ||
947 | case SND_SOC_DAPM_STREAM_SUSPEND: | 950 | case SND_SOC_DAPM_STREAM_SUSPEND: |
948 | sys_power = 0; | 951 | sys_power = 0; |
949 | break; | 952 | break; |
diff --git a/tools/perf/builtin-buildid-list.c b/tools/perf/builtin-buildid-list.c index 44a47e13bd67..c49837de7d3f 100644 --- a/tools/perf/builtin-buildid-list.c +++ b/tools/perf/builtin-buildid-list.c | |||
@@ -36,7 +36,6 @@ static const struct option options[] = { | |||
36 | 36 | ||
37 | static int __cmd_buildid_list(void) | 37 | static int __cmd_buildid_list(void) |
38 | { | 38 | { |
39 | int err = -1; | ||
40 | struct perf_session *session; | 39 | struct perf_session *session; |
41 | 40 | ||
42 | session = perf_session__new(input_name, O_RDONLY, force, false); | 41 | session = perf_session__new(input_name, O_RDONLY, force, false); |
@@ -49,7 +48,7 @@ static int __cmd_buildid_list(void) | |||
49 | perf_session__fprintf_dsos_buildid(session, stdout, with_hits); | 48 | perf_session__fprintf_dsos_buildid(session, stdout, with_hits); |
50 | 49 | ||
51 | perf_session__delete(session); | 50 | perf_session__delete(session); |
52 | return err; | 51 | return 0; |
53 | } | 52 | } |
54 | 53 | ||
55 | int cmd_buildid_list(int argc, const char **argv, const char *prefix __used) | 54 | int cmd_buildid_list(int argc, const char **argv, const char *prefix __used) |
diff --git a/tools/perf/builtin-probe.c b/tools/perf/builtin-probe.c index 2e000c068cc5..add163c9f0e7 100644 --- a/tools/perf/builtin-probe.c +++ b/tools/perf/builtin-probe.c | |||
@@ -249,6 +249,11 @@ int cmd_probe(int argc, const char **argv, const char *prefix __used) | |||
249 | !params.show_lines)) | 249 | !params.show_lines)) |
250 | usage_with_options(probe_usage, options); | 250 | usage_with_options(probe_usage, options); |
251 | 251 | ||
252 | /* | ||
253 | * Only consider the user's kernel image path if given. | ||
254 | */ | ||
255 | symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL); | ||
256 | |||
252 | if (params.list_events) { | 257 | if (params.list_events) { |
253 | if (params.mod_events) { | 258 | if (params.mod_events) { |
254 | pr_err(" Error: Don't use --list with --add/--del.\n"); | 259 | pr_err(" Error: Don't use --list with --add/--del.\n"); |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index e2c2de201eec..564491fa18b2 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -197,7 +197,7 @@ static void sig_atexit(void) | |||
197 | if (child_pid > 0) | 197 | if (child_pid > 0) |
198 | kill(child_pid, SIGTERM); | 198 | kill(child_pid, SIGTERM); |
199 | 199 | ||
200 | if (signr == -1) | 200 | if (signr == -1 || signr == SIGUSR1) |
201 | return; | 201 | return; |
202 | 202 | ||
203 | signal(signr, SIG_DFL); | 203 | signal(signr, SIG_DFL); |
@@ -515,6 +515,7 @@ static int __cmd_record(int argc, const char **argv) | |||
515 | atexit(sig_atexit); | 515 | atexit(sig_atexit); |
516 | signal(SIGCHLD, sig_handler); | 516 | signal(SIGCHLD, sig_handler); |
517 | signal(SIGINT, sig_handler); | 517 | signal(SIGINT, sig_handler); |
518 | signal(SIGUSR1, sig_handler); | ||
518 | 519 | ||
519 | if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) { | 520 | if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) { |
520 | perror("failed to create pipes"); | 521 | perror("failed to create pipes"); |
@@ -606,6 +607,7 @@ static int __cmd_record(int argc, const char **argv) | |||
606 | execvp(argv[0], (char **)argv); | 607 | execvp(argv[0], (char **)argv); |
607 | 608 | ||
608 | perror(argv[0]); | 609 | perror(argv[0]); |
610 | kill(getppid(), SIGUSR1); | ||
609 | exit(-1); | 611 | exit(-1); |
610 | } | 612 | } |
611 | 613 | ||
@@ -762,7 +764,7 @@ static int __cmd_record(int argc, const char **argv) | |||
762 | } | 764 | } |
763 | } | 765 | } |
764 | 766 | ||
765 | if (quiet) | 767 | if (quiet || signr == SIGUSR1) |
766 | return 0; | 768 | return 0; |
767 | 769 | ||
768 | fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking); | 770 | fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking); |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index d7e67b167ea3..7cba0551a565 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -265,15 +265,16 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, | |||
265 | const char *name, bool is_kallsyms) | 265 | const char *name, bool is_kallsyms) |
266 | { | 266 | { |
267 | const size_t size = PATH_MAX; | 267 | const size_t size = PATH_MAX; |
268 | char *filename = malloc(size), | 268 | char *realname = realpath(name, NULL), |
269 | *filename = malloc(size), | ||
269 | *linkname = malloc(size), *targetname; | 270 | *linkname = malloc(size), *targetname; |
270 | int len, err = -1; | 271 | int len, err = -1; |
271 | 272 | ||
272 | if (filename == NULL || linkname == NULL) | 273 | if (realname == NULL || filename == NULL || linkname == NULL) |
273 | goto out_free; | 274 | goto out_free; |
274 | 275 | ||
275 | len = snprintf(filename, size, "%s%s%s", | 276 | len = snprintf(filename, size, "%s%s%s", |
276 | debugdir, is_kallsyms ? "/" : "", name); | 277 | debugdir, is_kallsyms ? "/" : "", realname); |
277 | if (mkdir_p(filename, 0755)) | 278 | if (mkdir_p(filename, 0755)) |
278 | goto out_free; | 279 | goto out_free; |
279 | 280 | ||
@@ -283,7 +284,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, | |||
283 | if (is_kallsyms) { | 284 | if (is_kallsyms) { |
284 | if (copyfile("/proc/kallsyms", filename)) | 285 | if (copyfile("/proc/kallsyms", filename)) |
285 | goto out_free; | 286 | goto out_free; |
286 | } else if (link(name, filename) && copyfile(name, filename)) | 287 | } else if (link(realname, filename) && copyfile(name, filename)) |
287 | goto out_free; | 288 | goto out_free; |
288 | } | 289 | } |
289 | 290 | ||
@@ -300,6 +301,7 @@ int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, | |||
300 | if (symlink(targetname, linkname) == 0) | 301 | if (symlink(targetname, linkname) == 0) |
301 | err = 0; | 302 | err = 0; |
302 | out_free: | 303 | out_free: |
304 | free(realname); | ||
303 | free(filename); | 305 | free(filename); |
304 | free(linkname); | 306 | free(linkname); |
305 | return err; | 307 | return err; |
@@ -946,11 +948,16 @@ perf_header__find_attr(u64 id, struct perf_header *header) | |||
946 | 948 | ||
947 | /* | 949 | /* |
948 | * We set id to -1 if the data file doesn't contain sample | 950 | * We set id to -1 if the data file doesn't contain sample |
949 | * ids. Check for this and avoid walking through the entire | 951 | * ids. This can happen when the data file contains one type |
950 | * list of ids which may be large. | 952 | * of event and in that case, the header can still store the |
953 | * event attribute information. Check for this and avoid | ||
954 | * walking through the entire list of ids which may be large. | ||
951 | */ | 955 | */ |
952 | if (id == -1ULL) | 956 | if (id == -1ULL) { |
957 | if (header->attrs > 0) | ||
958 | return &header->attr[0]->attr; | ||
953 | return NULL; | 959 | return NULL; |
960 | } | ||
954 | 961 | ||
955 | for (i = 0; i < header->attrs; i++) { | 962 | for (i = 0; i < header->attrs; i++) { |
956 | struct perf_header_attr *attr = header->attr[i]; | 963 | struct perf_header_attr *attr = header->attr[i]; |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index 2022e8740994..76bcc35cf9b1 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -356,7 +356,7 @@ static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask, | |||
356 | 356 | ||
357 | static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain, | 357 | static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain, |
358 | int depth, int depth_mask, int period, | 358 | int depth, int depth_mask, int period, |
359 | u64 total_samples, int hits, | 359 | u64 total_samples, u64 hits, |
360 | int left_margin) | 360 | int left_margin) |
361 | { | 361 | { |
362 | int i; | 362 | int i; |
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c index 3b6a5297bf16..61191c6cbe7a 100644 --- a/tools/perf/util/probe-event.c +++ b/tools/perf/util/probe-event.c | |||
@@ -114,6 +114,8 @@ static struct symbol *__find_kernel_function_by_name(const char *name, | |||
114 | const char *kernel_get_module_path(const char *module) | 114 | const char *kernel_get_module_path(const char *module) |
115 | { | 115 | { |
116 | struct dso *dso; | 116 | struct dso *dso; |
117 | struct map *map; | ||
118 | const char *vmlinux_name; | ||
117 | 119 | ||
118 | if (module) { | 120 | if (module) { |
119 | list_for_each_entry(dso, &machine.kernel_dsos, node) { | 121 | list_for_each_entry(dso, &machine.kernel_dsos, node) { |
@@ -123,10 +125,17 @@ const char *kernel_get_module_path(const char *module) | |||
123 | } | 125 | } |
124 | pr_debug("Failed to find module %s.\n", module); | 126 | pr_debug("Failed to find module %s.\n", module); |
125 | return NULL; | 127 | return NULL; |
128 | } | ||
129 | |||
130 | map = machine.vmlinux_maps[MAP__FUNCTION]; | ||
131 | dso = map->dso; | ||
132 | |||
133 | vmlinux_name = symbol_conf.vmlinux_name; | ||
134 | if (vmlinux_name) { | ||
135 | if (dso__load_vmlinux(dso, map, vmlinux_name, NULL) <= 0) | ||
136 | return NULL; | ||
126 | } else { | 137 | } else { |
127 | dso = machine.vmlinux_maps[MAP__FUNCTION]->dso; | 138 | if (dso__load_vmlinux_path(dso, map, NULL) <= 0) { |
128 | if (dso__load_vmlinux_path(dso, | ||
129 | machine.vmlinux_maps[MAP__FUNCTION], NULL) < 0) { | ||
130 | pr_debug("Failed to load kernel map.\n"); | 139 | pr_debug("Failed to load kernel map.\n"); |
131 | return NULL; | 140 | return NULL; |
132 | } | 141 | } |
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c index 3991d73d1cff..ddf4d4556321 100644 --- a/tools/perf/util/probe-finder.c +++ b/tools/perf/util/probe-finder.c | |||
@@ -117,28 +117,6 @@ static void line_list__free(struct list_head *head) | |||
117 | } | 117 | } |
118 | 118 | ||
119 | /* Dwarf FL wrappers */ | 119 | /* Dwarf FL wrappers */ |
120 | |||
121 | static int __linux_kernel_find_elf(Dwfl_Module *mod, | ||
122 | void **userdata, | ||
123 | const char *module_name, | ||
124 | Dwarf_Addr base, | ||
125 | char **file_name, Elf **elfp) | ||
126 | { | ||
127 | int fd; | ||
128 | const char *path = kernel_get_module_path(module_name); | ||
129 | |||
130 | if (path) { | ||
131 | fd = open(path, O_RDONLY); | ||
132 | if (fd >= 0) { | ||
133 | *file_name = strdup(path); | ||
134 | return fd; | ||
135 | } | ||
136 | } | ||
137 | /* If failed, try to call standard method */ | ||
138 | return dwfl_linux_kernel_find_elf(mod, userdata, module_name, base, | ||
139 | file_name, elfp); | ||
140 | } | ||
141 | |||
142 | static char *debuginfo_path; /* Currently dummy */ | 120 | static char *debuginfo_path; /* Currently dummy */ |
143 | 121 | ||
144 | static const Dwfl_Callbacks offline_callbacks = { | 122 | static const Dwfl_Callbacks offline_callbacks = { |
@@ -151,14 +129,6 @@ static const Dwfl_Callbacks offline_callbacks = { | |||
151 | .find_elf = dwfl_build_id_find_elf, | 129 | .find_elf = dwfl_build_id_find_elf, |
152 | }; | 130 | }; |
153 | 131 | ||
154 | static const Dwfl_Callbacks kernel_callbacks = { | ||
155 | .find_debuginfo = dwfl_standard_find_debuginfo, | ||
156 | .debuginfo_path = &debuginfo_path, | ||
157 | |||
158 | .find_elf = __linux_kernel_find_elf, | ||
159 | .section_address = dwfl_linux_kernel_module_section_address, | ||
160 | }; | ||
161 | |||
162 | /* Get a Dwarf from offline image */ | 132 | /* Get a Dwarf from offline image */ |
163 | static Dwarf *dwfl_init_offline_dwarf(int fd, Dwfl **dwflp, Dwarf_Addr *bias) | 133 | static Dwarf *dwfl_init_offline_dwarf(int fd, Dwfl **dwflp, Dwarf_Addr *bias) |
164 | { | 134 | { |
@@ -185,6 +155,38 @@ error: | |||
185 | return dbg; | 155 | return dbg; |
186 | } | 156 | } |
187 | 157 | ||
158 | #if _ELFUTILS_PREREQ(0, 148) | ||
159 | /* This method is buggy if elfutils is older than 0.148 */ | ||
160 | static int __linux_kernel_find_elf(Dwfl_Module *mod, | ||
161 | void **userdata, | ||
162 | const char *module_name, | ||
163 | Dwarf_Addr base, | ||
164 | char **file_name, Elf **elfp) | ||
165 | { | ||
166 | int fd; | ||
167 | const char *path = kernel_get_module_path(module_name); | ||
168 | |||
169 | pr_debug2("Use file %s for %s\n", path, module_name); | ||
170 | if (path) { | ||
171 | fd = open(path, O_RDONLY); | ||
172 | if (fd >= 0) { | ||
173 | *file_name = strdup(path); | ||
174 | return fd; | ||
175 | } | ||
176 | } | ||
177 | /* If failed, try to call standard method */ | ||
178 | return dwfl_linux_kernel_find_elf(mod, userdata, module_name, base, | ||
179 | file_name, elfp); | ||
180 | } | ||
181 | |||
182 | static const Dwfl_Callbacks kernel_callbacks = { | ||
183 | .find_debuginfo = dwfl_standard_find_debuginfo, | ||
184 | .debuginfo_path = &debuginfo_path, | ||
185 | |||
186 | .find_elf = __linux_kernel_find_elf, | ||
187 | .section_address = dwfl_linux_kernel_module_section_address, | ||
188 | }; | ||
189 | |||
188 | /* Get a Dwarf from live kernel image */ | 190 | /* Get a Dwarf from live kernel image */ |
189 | static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr, Dwfl **dwflp, | 191 | static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr, Dwfl **dwflp, |
190 | Dwarf_Addr *bias) | 192 | Dwarf_Addr *bias) |
@@ -205,11 +207,34 @@ static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr, Dwfl **dwflp, | |||
205 | dbg = dwfl_addrdwarf(*dwflp, addr, bias); | 207 | dbg = dwfl_addrdwarf(*dwflp, addr, bias); |
206 | /* Here, check whether we could get a real dwarf */ | 208 | /* Here, check whether we could get a real dwarf */ |
207 | if (!dbg) { | 209 | if (!dbg) { |
210 | pr_debug("Failed to find kernel dwarf at %lx\n", | ||
211 | (unsigned long)addr); | ||
208 | dwfl_end(*dwflp); | 212 | dwfl_end(*dwflp); |
209 | *dwflp = NULL; | 213 | *dwflp = NULL; |
210 | } | 214 | } |
211 | return dbg; | 215 | return dbg; |
212 | } | 216 | } |
217 | #else | ||
218 | /* With older elfutils, this just support kernel module... */ | ||
219 | static Dwarf *dwfl_init_live_kernel_dwarf(Dwarf_Addr addr __used, Dwfl **dwflp, | ||
220 | Dwarf_Addr *bias) | ||
221 | { | ||
222 | int fd; | ||
223 | const char *path = kernel_get_module_path("kernel"); | ||
224 | |||
225 | if (!path) { | ||
226 | pr_err("Failed to find vmlinux path\n"); | ||
227 | return NULL; | ||
228 | } | ||
229 | |||
230 | pr_debug2("Use file %s for debuginfo\n", path); | ||
231 | fd = open(path, O_RDONLY); | ||
232 | if (fd < 0) | ||
233 | return NULL; | ||
234 | |||
235 | return dwfl_init_offline_dwarf(fd, dwflp, bias); | ||
236 | } | ||
237 | #endif | ||
213 | 238 | ||
214 | /* Dwarf wrappers */ | 239 | /* Dwarf wrappers */ |
215 | 240 | ||
diff --git a/tools/perf/util/string.c b/tools/perf/util/string.c index 0409fc7c0058..8fc0bd3a3a4a 100644 --- a/tools/perf/util/string.c +++ b/tools/perf/util/string.c | |||
@@ -259,7 +259,7 @@ static bool __match_glob(const char *str, const char *pat, bool ignore_space) | |||
259 | if (!*pat) /* Tail wild card matches all */ | 259 | if (!*pat) /* Tail wild card matches all */ |
260 | return true; | 260 | return true; |
261 | while (*str) | 261 | while (*str) |
262 | if (strglobmatch(str++, pat)) | 262 | if (__match_glob(str++, pat, ignore_space)) |
263 | return true; | 263 | return true; |
264 | } | 264 | } |
265 | return !*str && !*pat; | 265 | return !*str && !*pat; |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 0500895a45af..439ab947daf4 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -532,7 +532,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, | |||
532 | struct machine *machine = kmaps->machine; | 532 | struct machine *machine = kmaps->machine; |
533 | struct map *curr_map = map; | 533 | struct map *curr_map = map; |
534 | struct symbol *pos; | 534 | struct symbol *pos; |
535 | int count = 0; | 535 | int count = 0, moved = 0; |
536 | struct rb_root *root = &self->symbols[map->type]; | 536 | struct rb_root *root = &self->symbols[map->type]; |
537 | struct rb_node *next = rb_first(root); | 537 | struct rb_node *next = rb_first(root); |
538 | int kernel_range = 0; | 538 | int kernel_range = 0; |
@@ -590,6 +590,11 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, | |||
590 | char dso_name[PATH_MAX]; | 590 | char dso_name[PATH_MAX]; |
591 | struct dso *dso; | 591 | struct dso *dso; |
592 | 592 | ||
593 | if (count == 0) { | ||
594 | curr_map = map; | ||
595 | goto filter_symbol; | ||
596 | } | ||
597 | |||
593 | if (self->kernel == DSO_TYPE_GUEST_KERNEL) | 598 | if (self->kernel == DSO_TYPE_GUEST_KERNEL) |
594 | snprintf(dso_name, sizeof(dso_name), | 599 | snprintf(dso_name, sizeof(dso_name), |
595 | "[guest.kernel].%d", | 600 | "[guest.kernel].%d", |
@@ -615,7 +620,7 @@ static int dso__split_kallsyms(struct dso *self, struct map *map, | |||
615 | map_groups__insert(kmaps, curr_map); | 620 | map_groups__insert(kmaps, curr_map); |
616 | ++kernel_range; | 621 | ++kernel_range; |
617 | } | 622 | } |
618 | 623 | filter_symbol: | |
619 | if (filter && filter(curr_map, pos)) { | 624 | if (filter && filter(curr_map, pos)) { |
620 | discard_symbol: rb_erase(&pos->rb_node, root); | 625 | discard_symbol: rb_erase(&pos->rb_node, root); |
621 | symbol__delete(pos); | 626 | symbol__delete(pos); |
@@ -623,8 +628,9 @@ discard_symbol: rb_erase(&pos->rb_node, root); | |||
623 | if (curr_map != map) { | 628 | if (curr_map != map) { |
624 | rb_erase(&pos->rb_node, root); | 629 | rb_erase(&pos->rb_node, root); |
625 | symbols__insert(&curr_map->dso->symbols[curr_map->type], pos); | 630 | symbols__insert(&curr_map->dso->symbols[curr_map->type], pos); |
626 | } | 631 | ++moved; |
627 | count++; | 632 | } else |
633 | ++count; | ||
628 | } | 634 | } |
629 | } | 635 | } |
630 | 636 | ||
@@ -634,7 +640,7 @@ discard_symbol: rb_erase(&pos->rb_node, root); | |||
634 | dso__set_loaded(curr_map->dso, curr_map->type); | 640 | dso__set_loaded(curr_map->dso, curr_map->type); |
635 | } | 641 | } |
636 | 642 | ||
637 | return count; | 643 | return count + moved; |
638 | } | 644 | } |
639 | 645 | ||
640 | int dso__load_kallsyms(struct dso *self, const char *filename, | 646 | int dso__load_kallsyms(struct dso *self, const char *filename, |
@@ -1774,8 +1780,8 @@ out_failure: | |||
1774 | return -1; | 1780 | return -1; |
1775 | } | 1781 | } |
1776 | 1782 | ||
1777 | static int dso__load_vmlinux(struct dso *self, struct map *map, | 1783 | int dso__load_vmlinux(struct dso *self, struct map *map, |
1778 | const char *vmlinux, symbol_filter_t filter) | 1784 | const char *vmlinux, symbol_filter_t filter) |
1779 | { | 1785 | { |
1780 | int err = -1, fd; | 1786 | int err = -1, fd; |
1781 | 1787 | ||
@@ -2125,14 +2131,55 @@ static struct dso *machine__create_kernel(struct machine *self) | |||
2125 | return kernel; | 2131 | return kernel; |
2126 | } | 2132 | } |
2127 | 2133 | ||
2134 | struct process_args { | ||
2135 | u64 start; | ||
2136 | }; | ||
2137 | |||
2138 | static int symbol__in_kernel(void *arg, const char *name, | ||
2139 | char type __used, u64 start) | ||
2140 | { | ||
2141 | struct process_args *args = arg; | ||
2142 | |||
2143 | if (strchr(name, '[')) | ||
2144 | return 0; | ||
2145 | |||
2146 | args->start = start; | ||
2147 | return 1; | ||
2148 | } | ||
2149 | |||
2150 | /* Figure out the start address of kernel map from /proc/kallsyms */ | ||
2151 | static u64 machine__get_kernel_start_addr(struct machine *machine) | ||
2152 | { | ||
2153 | const char *filename; | ||
2154 | char path[PATH_MAX]; | ||
2155 | struct process_args args; | ||
2156 | |||
2157 | if (machine__is_host(machine)) { | ||
2158 | filename = "/proc/kallsyms"; | ||
2159 | } else { | ||
2160 | if (machine__is_default_guest(machine)) | ||
2161 | filename = (char *)symbol_conf.default_guest_kallsyms; | ||
2162 | else { | ||
2163 | sprintf(path, "%s/proc/kallsyms", machine->root_dir); | ||
2164 | filename = path; | ||
2165 | } | ||
2166 | } | ||
2167 | |||
2168 | if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0) | ||
2169 | return 0; | ||
2170 | |||
2171 | return args.start; | ||
2172 | } | ||
2173 | |||
2128 | int __machine__create_kernel_maps(struct machine *self, struct dso *kernel) | 2174 | int __machine__create_kernel_maps(struct machine *self, struct dso *kernel) |
2129 | { | 2175 | { |
2130 | enum map_type type; | 2176 | enum map_type type; |
2177 | u64 start = machine__get_kernel_start_addr(self); | ||
2131 | 2178 | ||
2132 | for (type = 0; type < MAP__NR_TYPES; ++type) { | 2179 | for (type = 0; type < MAP__NR_TYPES; ++type) { |
2133 | struct kmap *kmap; | 2180 | struct kmap *kmap; |
2134 | 2181 | ||
2135 | self->vmlinux_maps[type] = map__new2(0, kernel, type); | 2182 | self->vmlinux_maps[type] = map__new2(start, kernel, type); |
2136 | if (self->vmlinux_maps[type] == NULL) | 2183 | if (self->vmlinux_maps[type] == NULL) |
2137 | return -1; | 2184 | return -1; |
2138 | 2185 | ||
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 038f2201ee09..6c6eafdb932d 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -166,6 +166,8 @@ void dso__sort_by_name(struct dso *self, enum map_type type); | |||
166 | struct dso *__dsos__findnew(struct list_head *head, const char *name); | 166 | struct dso *__dsos__findnew(struct list_head *head, const char *name); |
167 | 167 | ||
168 | int dso__load(struct dso *self, struct map *map, symbol_filter_t filter); | 168 | int dso__load(struct dso *self, struct map *map, symbol_filter_t filter); |
169 | int dso__load_vmlinux(struct dso *self, struct map *map, | ||
170 | const char *vmlinux, symbol_filter_t filter); | ||
169 | int dso__load_vmlinux_path(struct dso *self, struct map *map, | 171 | int dso__load_vmlinux_path(struct dso *self, struct map *map, |
170 | symbol_filter_t filter); | 172 | symbol_filter_t filter); |
171 | int dso__load_kallsyms(struct dso *self, const char *filename, struct map *map, | 173 | int dso__load_kallsyms(struct dso *self, const char *filename, struct map *map, |