diff options
457 files changed, 5482 insertions, 3763 deletions
diff --git a/Documentation/Changes b/Documentation/Changes index 5f4828a034e3..b17580885273 100644 --- a/Documentation/Changes +++ b/Documentation/Changes | |||
@@ -2,13 +2,7 @@ Intro | |||
2 | ===== | 2 | ===== |
3 | 3 | ||
4 | This document is designed to provide a list of the minimum levels of | 4 | This document is designed to provide a list of the minimum levels of |
5 | software necessary to run the 2.6 kernels, as well as provide brief | 5 | software necessary to run the 3.0 kernels. |
6 | instructions regarding any other "Gotchas" users may encounter when | ||
7 | trying life on the Bleeding Edge. If upgrading from a pre-2.4.x | ||
8 | kernel, please consult the Changes file included with 2.4.x kernels for | ||
9 | additional information; most of that information will not be repeated | ||
10 | here. Basically, this document assumes that your system is already | ||
11 | functional and running at least 2.4.x kernels. | ||
12 | 6 | ||
13 | This document is originally based on my "Changes" file for 2.0.x kernels | 7 | This document is originally based on my "Changes" file for 2.0.x kernels |
14 | and therefore owes credit to the same people as that file (Jared Mauch, | 8 | and therefore owes credit to the same people as that file (Jared Mauch, |
@@ -22,11 +16,10 @@ Upgrade to at *least* these software revisions before thinking you've | |||
22 | encountered a bug! If you're unsure what version you're currently | 16 | encountered a bug! If you're unsure what version you're currently |
23 | running, the suggested command should tell you. | 17 | running, the suggested command should tell you. |
24 | 18 | ||
25 | Again, keep in mind that this list assumes you are already | 19 | Again, keep in mind that this list assumes you are already functionally |
26 | functionally running a Linux 2.4 kernel. Also, not all tools are | 20 | running a Linux kernel. Also, not all tools are necessary on all |
27 | necessary on all systems; obviously, if you don't have any ISDN | 21 | systems; obviously, if you don't have any ISDN hardware, for example, |
28 | hardware, for example, you probably needn't concern yourself with | 22 | you probably needn't concern yourself with isdn4k-utils. |
29 | isdn4k-utils. | ||
30 | 23 | ||
31 | o Gnu C 3.2 # gcc --version | 24 | o Gnu C 3.2 # gcc --version |
32 | o Gnu make 3.80 # make --version | 25 | o Gnu make 3.80 # make --version |
@@ -114,12 +107,12 @@ Ksymoops | |||
114 | 107 | ||
115 | If the unthinkable happens and your kernel oopses, you may need the | 108 | If the unthinkable happens and your kernel oopses, you may need the |
116 | ksymoops tool to decode it, but in most cases you don't. | 109 | ksymoops tool to decode it, but in most cases you don't. |
117 | In the 2.6 kernel it is generally preferred to build the kernel with | 110 | It is generally preferred to build the kernel with CONFIG_KALLSYMS so |
118 | CONFIG_KALLSYMS so that it produces readable dumps that can be used as-is | 111 | that it produces readable dumps that can be used as-is (this also |
119 | (this also produces better output than ksymoops). | 112 | produces better output than ksymoops). If for some reason your kernel |
120 | If for some reason your kernel is not build with CONFIG_KALLSYMS and | 113 | is not build with CONFIG_KALLSYMS and you have no way to rebuild and |
121 | you have no way to rebuild and reproduce the Oops with that option, then | 114 | reproduce the Oops with that option, then you can still decode that Oops |
122 | you can still decode that Oops with ksymoops. | 115 | with ksymoops. |
123 | 116 | ||
124 | Module-Init-Tools | 117 | Module-Init-Tools |
125 | ----------------- | 118 | ----------------- |
@@ -261,8 +254,8 @@ needs to be recompiled or (preferably) upgraded. | |||
261 | NFS-utils | 254 | NFS-utils |
262 | --------- | 255 | --------- |
263 | 256 | ||
264 | In 2.4 and earlier kernels, the nfs server needed to know about any | 257 | In ancient (2.4 and earlier) kernels, the nfs server needed to know |
265 | client that expected to be able to access files via NFS. This | 258 | about any client that expected to be able to access files via NFS. This |
266 | information would be given to the kernel by "mountd" when the client | 259 | information would be given to the kernel by "mountd" when the client |
267 | mounted the filesystem, or by "exportfs" at system startup. exportfs | 260 | mounted the filesystem, or by "exportfs" at system startup. exportfs |
268 | would take information about active clients from /var/lib/nfs/rmtab. | 261 | would take information about active clients from /var/lib/nfs/rmtab. |
@@ -272,11 +265,11 @@ which is not always easy, particularly when trying to implement | |||
272 | fail-over. Even when the system is working well, rmtab suffers from | 265 | fail-over. Even when the system is working well, rmtab suffers from |
273 | getting lots of old entries that never get removed. | 266 | getting lots of old entries that never get removed. |
274 | 267 | ||
275 | With 2.6 we have the option of having the kernel tell mountd when it | 268 | With modern kernels we have the option of having the kernel tell mountd |
276 | gets a request from an unknown host, and mountd can give appropriate | 269 | when it gets a request from an unknown host, and mountd can give |
277 | export information to the kernel. This removes the dependency on | 270 | appropriate export information to the kernel. This removes the |
278 | rmtab and means that the kernel only needs to know about currently | 271 | dependency on rmtab and means that the kernel only needs to know about |
279 | active clients. | 272 | currently active clients. |
280 | 273 | ||
281 | To enable this new functionality, you need to: | 274 | To enable this new functionality, you need to: |
282 | 275 | ||
diff --git a/Documentation/CodingStyle b/Documentation/CodingStyle index 58b0bf917834..fa6e25b94a54 100644 --- a/Documentation/CodingStyle +++ b/Documentation/CodingStyle | |||
@@ -680,8 +680,8 @@ ones already enabled by DEBUG. | |||
680 | Chapter 14: Allocating memory | 680 | Chapter 14: Allocating memory |
681 | 681 | ||
682 | The kernel provides the following general purpose memory allocators: | 682 | The kernel provides the following general purpose memory allocators: |
683 | kmalloc(), kzalloc(), kcalloc(), and vmalloc(). Please refer to the API | 683 | kmalloc(), kzalloc(), kcalloc(), vmalloc(), and vzalloc(). Please refer to |
684 | documentation for further information about them. | 684 | the API documentation for further information about them. |
685 | 685 | ||
686 | The preferred form for passing a size of a struct is the following: | 686 | The preferred form for passing a size of a struct is the following: |
687 | 687 | ||
diff --git a/Documentation/arm/Booting b/Documentation/arm/Booting index 4e686a2ed91e..a341d87d276e 100644 --- a/Documentation/arm/Booting +++ b/Documentation/arm/Booting | |||
@@ -164,3 +164,8 @@ In either case, the following conditions must be met: | |||
164 | - The boot loader is expected to call the kernel image by jumping | 164 | - The boot loader is expected to call the kernel image by jumping |
165 | directly to the first instruction of the kernel image. | 165 | directly to the first instruction of the kernel image. |
166 | 166 | ||
167 | On CPUs supporting the ARM instruction set, the entry must be | ||
168 | made in ARM state, even for a Thumb-2 kernel. | ||
169 | |||
170 | On CPUs supporting only the Thumb instruction set such as | ||
171 | Cortex-M class CPUs, the entry must be made in Thumb state. | ||
diff --git a/Documentation/arm/SH-Mobile/zboot-rom-sdhi.txt b/Documentation/arm/SH-Mobile/zboot-rom-sdhi.txt new file mode 100644 index 000000000000..441959846e1a --- /dev/null +++ b/Documentation/arm/SH-Mobile/zboot-rom-sdhi.txt | |||
@@ -0,0 +1,42 @@ | |||
1 | ROM-able zImage boot from eSD | ||
2 | ----------------------------- | ||
3 | |||
4 | An ROM-able zImage compiled with ZBOOT_ROM_SDHI may be written to eSD and | ||
5 | SuperH Mobile ARM will to boot directly from the SDHI hardware block. | ||
6 | |||
7 | This is achieved by the mask ROM loading the first portion of the image into | ||
8 | MERAM and then jumping to it. This portion contains loader code which | ||
9 | copies the entire image to SDRAM and jumps to it. From there the zImage | ||
10 | boot code proceeds as normal, uncompressing the image into its final | ||
11 | location and then jumping to it. | ||
12 | |||
13 | This code has been tested on an mackerel board using the developer 1A eSD | ||
14 | boot mode which is configured using the following jumper settings. | ||
15 | |||
16 | 8 7 6 5 4 3 2 1 | ||
17 | x|x|x|x| |x|x| | ||
18 | S4 -+-+-+-+-+-+-+- | ||
19 | | | | |x| | |x on | ||
20 | |||
21 | The eSD card needs to be present in SDHI slot 1 (CN7). | ||
22 | As such S1 and S33 also need to be configured as per | ||
23 | the notes in arch/arm/mach-shmobile/board-mackerel.c. | ||
24 | |||
25 | A partial zImage must be written to physical partition #1 (boot) | ||
26 | of the eSD at sector 0 in vrl4 format. A utility vrl4 is supplied to | ||
27 | accomplish this. | ||
28 | |||
29 | e.g. | ||
30 | vrl4 < zImage | dd of=/dev/sdX bs=512 count=17 | ||
31 | |||
32 | A full copy of _the same_ zImage should be written to physical partition #1 | ||
33 | (boot) of the eSD at sector 0. This should _not_ be in vrl4 format. | ||
34 | |||
35 | vrl4 < zImage | dd of=/dev/sdX bs=512 | ||
36 | |||
37 | Note: The commands above assume that the physical partition has been | ||
38 | switched. No such facility currently exists in the Linux Kernel. | ||
39 | |||
40 | Physical partitions are described in the eSD specification. At the time of | ||
41 | writing they are not the same as partitions that are typically configured | ||
42 | using fdisk and visible through /proc/partitions | ||
diff --git a/Documentation/cgroups/blkio-controller.txt b/Documentation/cgroups/blkio-controller.txt index cd45c8ea7463..84f0a15fc210 100644 --- a/Documentation/cgroups/blkio-controller.txt +++ b/Documentation/cgroups/blkio-controller.txt | |||
@@ -77,7 +77,7 @@ Throttling/Upper Limit policy | |||
77 | - Specify a bandwidth rate on particular device for root group. The format | 77 | - Specify a bandwidth rate on particular device for root group. The format |
78 | for policy is "<major>:<minor> <byes_per_second>". | 78 | for policy is "<major>:<minor> <byes_per_second>". |
79 | 79 | ||
80 | echo "8:16 1048576" > /sys/fs/cgroup/blkio/blkio.read_bps_device | 80 | echo "8:16 1048576" > /sys/fs/cgroup/blkio/blkio.throttle.read_bps_device |
81 | 81 | ||
82 | Above will put a limit of 1MB/second on reads happening for root group | 82 | Above will put a limit of 1MB/second on reads happening for root group |
83 | on device having major/minor number 8:16. | 83 | on device having major/minor number 8:16. |
@@ -90,7 +90,7 @@ Throttling/Upper Limit policy | |||
90 | 1024+0 records out | 90 | 1024+0 records out |
91 | 4194304 bytes (4.2 MB) copied, 4.0001 s, 1.0 MB/s | 91 | 4194304 bytes (4.2 MB) copied, 4.0001 s, 1.0 MB/s |
92 | 92 | ||
93 | Limits for writes can be put using blkio.write_bps_device file. | 93 | Limits for writes can be put using blkio.throttle.write_bps_device file. |
94 | 94 | ||
95 | Hierarchical Cgroups | 95 | Hierarchical Cgroups |
96 | ==================== | 96 | ==================== |
@@ -286,28 +286,28 @@ Throttling/Upper limit policy files | |||
286 | specified in bytes per second. Rules are per deivce. Following is | 286 | specified in bytes per second. Rules are per deivce. Following is |
287 | the format. | 287 | the format. |
288 | 288 | ||
289 | echo "<major>:<minor> <rate_bytes_per_second>" > /cgrp/blkio.read_bps_device | 289 | echo "<major>:<minor> <rate_bytes_per_second>" > /cgrp/blkio.throttle.read_bps_device |
290 | 290 | ||
291 | - blkio.throttle.write_bps_device | 291 | - blkio.throttle.write_bps_device |
292 | - Specifies upper limit on WRITE rate to the device. IO rate is | 292 | - Specifies upper limit on WRITE rate to the device. IO rate is |
293 | specified in bytes per second. Rules are per deivce. Following is | 293 | specified in bytes per second. Rules are per deivce. Following is |
294 | the format. | 294 | the format. |
295 | 295 | ||
296 | echo "<major>:<minor> <rate_bytes_per_second>" > /cgrp/blkio.write_bps_device | 296 | echo "<major>:<minor> <rate_bytes_per_second>" > /cgrp/blkio.throttle.write_bps_device |
297 | 297 | ||
298 | - blkio.throttle.read_iops_device | 298 | - blkio.throttle.read_iops_device |
299 | - Specifies upper limit on READ rate from the device. IO rate is | 299 | - Specifies upper limit on READ rate from the device. IO rate is |
300 | specified in IO per second. Rules are per deivce. Following is | 300 | specified in IO per second. Rules are per deivce. Following is |
301 | the format. | 301 | the format. |
302 | 302 | ||
303 | echo "<major>:<minor> <rate_io_per_second>" > /cgrp/blkio.read_iops_device | 303 | echo "<major>:<minor> <rate_io_per_second>" > /cgrp/blkio.throttle.read_iops_device |
304 | 304 | ||
305 | - blkio.throttle.write_iops_device | 305 | - blkio.throttle.write_iops_device |
306 | - Specifies upper limit on WRITE rate to the device. IO rate is | 306 | - Specifies upper limit on WRITE rate to the device. IO rate is |
307 | specified in io per second. Rules are per deivce. Following is | 307 | specified in io per second. Rules are per deivce. Following is |
308 | the format. | 308 | the format. |
309 | 309 | ||
310 | echo "<major>:<minor> <rate_io_per_second>" > /cgrp/blkio.write_iops_device | 310 | echo "<major>:<minor> <rate_io_per_second>" > /cgrp/blkio.throttle.write_iops_device |
311 | 311 | ||
312 | Note: If both BW and IOPS rules are specified for a device, then IO is | 312 | Note: If both BW and IOPS rules are specified for a device, then IO is |
313 | subjectd to both the constraints. | 313 | subjectd to both the constraints. |
diff --git a/Documentation/devicetree/bindings/arm/pmu.txt b/Documentation/devicetree/bindings/arm/pmu.txt new file mode 100644 index 000000000000..1c044eb320cc --- /dev/null +++ b/Documentation/devicetree/bindings/arm/pmu.txt | |||
@@ -0,0 +1,21 @@ | |||
1 | * ARM Performance Monitor Units | ||
2 | |||
3 | ARM cores often have a PMU for counting cpu and cache events like cache misses | ||
4 | and hits. The interface to the PMU is part of the ARM ARM. The ARM PMU | ||
5 | representation in the device tree should be done as under:- | ||
6 | |||
7 | Required properties: | ||
8 | |||
9 | - compatible : should be one of | ||
10 | "arm,cortex-a9-pmu" | ||
11 | "arm,cortex-a8-pmu" | ||
12 | "arm,arm1176-pmu" | ||
13 | "arm,arm1136-pmu" | ||
14 | - interrupts : 1 combined interrupt or 1 per core. | ||
15 | |||
16 | Example: | ||
17 | |||
18 | pmu { | ||
19 | compatible = "arm,cortex-a9-pmu"; | ||
20 | interrupts = <100 101>; | ||
21 | }; | ||
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 72e238465b0b..b1c921c27519 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -583,3 +583,25 @@ Why: Superseded by the UVCIOC_CTRL_QUERY ioctl. | |||
583 | Who: Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 583 | Who: Laurent Pinchart <laurent.pinchart@ideasonboard.com> |
584 | 584 | ||
585 | ---------------------------- | 585 | ---------------------------- |
586 | |||
587 | What: For VIDIOC_S_FREQUENCY the type field must match the device node's type. | ||
588 | If not, return -EINVAL. | ||
589 | When: 3.2 | ||
590 | Why: It makes no sense to switch the tuner to radio mode by calling | ||
591 | VIDIOC_S_FREQUENCY on a video node, or to switch the tuner to tv mode by | ||
592 | calling VIDIOC_S_FREQUENCY on a radio node. This is the first step of a | ||
593 | move to more consistent handling of tv and radio tuners. | ||
594 | Who: Hans Verkuil <hans.verkuil@cisco.com> | ||
595 | |||
596 | ---------------------------- | ||
597 | |||
598 | What: Opening a radio device node will no longer automatically switch the | ||
599 | tuner mode from tv to radio. | ||
600 | When: 3.3 | ||
601 | Why: Just opening a V4L device should not change the state of the hardware | ||
602 | like that. It's very unexpected and against the V4L spec. Instead, you | ||
603 | switch to radio mode by calling VIDIOC_S_FREQUENCY. This is the second | ||
604 | and last step of the move to consistent handling of tv and radio tuners. | ||
605 | Who: Hans Verkuil <hans.verkuil@cisco.com> | ||
606 | |||
607 | ---------------------------- | ||
diff --git a/Documentation/filesystems/caching/netfs-api.txt b/Documentation/filesystems/caching/netfs-api.txt index a167ab876c35..7cc6bf2871eb 100644 --- a/Documentation/filesystems/caching/netfs-api.txt +++ b/Documentation/filesystems/caching/netfs-api.txt | |||
@@ -673,6 +673,22 @@ storage request to complete, or it may attempt to cancel the storage request - | |||
673 | in which case the page will not be stored in the cache this time. | 673 | in which case the page will not be stored in the cache this time. |
674 | 674 | ||
675 | 675 | ||
676 | BULK INODE PAGE UNCACHE | ||
677 | ----------------------- | ||
678 | |||
679 | A convenience routine is provided to perform an uncache on all the pages | ||
680 | attached to an inode. This assumes that the pages on the inode correspond on a | ||
681 | 1:1 basis with the pages in the cache. | ||
682 | |||
683 | void fscache_uncache_all_inode_pages(struct fscache_cookie *cookie, | ||
684 | struct inode *inode); | ||
685 | |||
686 | This takes the netfs cookie that the pages were cached with and the inode that | ||
687 | the pages are attached to. This function will wait for pages to finish being | ||
688 | written to the cache and for the cache to finish with the page generally. No | ||
689 | error is returned. | ||
690 | |||
691 | |||
676 | ========================== | 692 | ========================== |
677 | INDEX AND DATA FILE UPDATE | 693 | INDEX AND DATA FILE UPDATE |
678 | ========================== | 694 | ========================== |
diff --git a/Documentation/filesystems/nilfs2.txt b/Documentation/filesystems/nilfs2.txt index d5c0cef38a71..873a2ab2e9f8 100644 --- a/Documentation/filesystems/nilfs2.txt +++ b/Documentation/filesystems/nilfs2.txt | |||
@@ -40,7 +40,6 @@ Features which NILFS2 does not support yet: | |||
40 | - POSIX ACLs | 40 | - POSIX ACLs |
41 | - quotas | 41 | - quotas |
42 | - fsck | 42 | - fsck |
43 | - resize | ||
44 | - defragmentation | 43 | - defragmentation |
45 | 44 | ||
46 | Mount options | 45 | Mount options |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index fd248a318211..aa47be71df4c 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -2015,6 +2015,8 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
2015 | the default. | 2015 | the default. |
2016 | off: Turn ECRC off | 2016 | off: Turn ECRC off |
2017 | on: Turn ECRC on. | 2017 | on: Turn ECRC on. |
2018 | realloc reallocate PCI resources if allocations done by BIOS | ||
2019 | are erroneous. | ||
2018 | 2020 | ||
2019 | pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power | 2021 | pcie_aspm= [PCIE] Forcibly enable or disable PCIe Active State Power |
2020 | Management. | 2022 | Management. |
diff --git a/Documentation/laptops/thinkpad-acpi.txt b/Documentation/laptops/thinkpad-acpi.txt index 1565eefd6fd5..61815483efa3 100644 --- a/Documentation/laptops/thinkpad-acpi.txt +++ b/Documentation/laptops/thinkpad-acpi.txt | |||
@@ -534,6 +534,8 @@ Events that are never propagated by the driver: | |||
534 | 0x2404 System is waking up from hibernation to undock | 534 | 0x2404 System is waking up from hibernation to undock |
535 | 0x2405 System is waking up from hibernation to eject bay | 535 | 0x2405 System is waking up from hibernation to eject bay |
536 | 0x5010 Brightness level changed/control event | 536 | 0x5010 Brightness level changed/control event |
537 | 0x6000 KEYBOARD: Numlock key pressed | ||
538 | 0x6005 KEYBOARD: Fn key pressed (TO BE VERIFIED) | ||
537 | 539 | ||
538 | Events that are propagated by the driver to userspace: | 540 | Events that are propagated by the driver to userspace: |
539 | 541 | ||
@@ -545,6 +547,8 @@ Events that are propagated by the driver to userspace: | |||
545 | 0x3006 Bay hotplug request (hint to power up SATA link when | 547 | 0x3006 Bay hotplug request (hint to power up SATA link when |
546 | the optical drive tray is ejected) | 548 | the optical drive tray is ejected) |
547 | 0x4003 Undocked (see 0x2x04), can sleep again | 549 | 0x4003 Undocked (see 0x2x04), can sleep again |
550 | 0x4010 Docked into hotplug port replicator (non-ACPI dock) | ||
551 | 0x4011 Undocked from hotplug port replicator (non-ACPI dock) | ||
548 | 0x500B Tablet pen inserted into its storage bay | 552 | 0x500B Tablet pen inserted into its storage bay |
549 | 0x500C Tablet pen removed from its storage bay | 553 | 0x500C Tablet pen removed from its storage bay |
550 | 0x6011 ALARM: battery is too hot | 554 | 0x6011 ALARM: battery is too hot |
@@ -552,6 +556,7 @@ Events that are propagated by the driver to userspace: | |||
552 | 0x6021 ALARM: a sensor is too hot | 556 | 0x6021 ALARM: a sensor is too hot |
553 | 0x6022 ALARM: a sensor is extremely hot | 557 | 0x6022 ALARM: a sensor is extremely hot |
554 | 0x6030 System thermal table changed | 558 | 0x6030 System thermal table changed |
559 | 0x6040 Nvidia Optimus/AC adapter related (TO BE VERIFIED) | ||
555 | 560 | ||
556 | Battery nearly empty alarms are a last resort attempt to get the | 561 | Battery nearly empty alarms are a last resort attempt to get the |
557 | operating system to hibernate or shutdown cleanly (0x2313), or shutdown | 562 | operating system to hibernate or shutdown cleanly (0x2313), or shutdown |
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index d3d653a5f9b9..bfe924217f24 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt | |||
@@ -346,7 +346,7 @@ tcp_orphan_retries - INTEGER | |||
346 | when RTO retransmissions remain unacknowledged. | 346 | when RTO retransmissions remain unacknowledged. |
347 | See tcp_retries2 for more details. | 347 | See tcp_retries2 for more details. |
348 | 348 | ||
349 | The default value is 7. | 349 | The default value is 8. |
350 | If your machine is a loaded WEB server, | 350 | If your machine is a loaded WEB server, |
351 | you should think about lowering this value, such sockets | 351 | you should think about lowering this value, such sockets |
352 | may consume significant resources. Cf. tcp_max_orphans. | 352 | may consume significant resources. Cf. tcp_max_orphans. |
diff --git a/Documentation/spinlocks.txt b/Documentation/spinlocks.txt index 2e3c64b1a6a5..9dbe885ecd8d 100644 --- a/Documentation/spinlocks.txt +++ b/Documentation/spinlocks.txt | |||
@@ -13,18 +13,8 @@ static DEFINE_SPINLOCK(xxx_lock); | |||
13 | The above is always safe. It will disable interrupts _locally_, but the | 13 | The above is always safe. It will disable interrupts _locally_, but the |
14 | spinlock itself will guarantee the global lock, so it will guarantee that | 14 | spinlock itself will guarantee the global lock, so it will guarantee that |
15 | there is only one thread-of-control within the region(s) protected by that | 15 | there is only one thread-of-control within the region(s) protected by that |
16 | lock. This works well even under UP. The above sequence under UP | 16 | lock. This works well even under UP also, so the code does _not_ need to |
17 | essentially is just the same as doing | 17 | worry about UP vs SMP issues: the spinlocks work correctly under both. |
18 | |||
19 | unsigned long flags; | ||
20 | |||
21 | save_flags(flags); cli(); | ||
22 | ... critical section ... | ||
23 | restore_flags(flags); | ||
24 | |||
25 | so the code does _not_ need to worry about UP vs SMP issues: the spinlocks | ||
26 | work correctly under both (and spinlocks are actually more efficient on | ||
27 | architectures that allow doing the "save_flags + cli" in one operation). | ||
28 | 18 | ||
29 | NOTE! Implications of spin_locks for memory are further described in: | 19 | NOTE! Implications of spin_locks for memory are further described in: |
30 | 20 | ||
@@ -36,27 +26,7 @@ The above is usually pretty simple (you usually need and want only one | |||
36 | spinlock for most things - using more than one spinlock can make things a | 26 | spinlock for most things - using more than one spinlock can make things a |
37 | lot more complex and even slower and is usually worth it only for | 27 | lot more complex and even slower and is usually worth it only for |
38 | sequences that you _know_ need to be split up: avoid it at all cost if you | 28 | sequences that you _know_ need to be split up: avoid it at all cost if you |
39 | aren't sure). HOWEVER, it _does_ mean that if you have some code that does | 29 | aren't sure). |
40 | |||
41 | cli(); | ||
42 | .. critical section .. | ||
43 | sti(); | ||
44 | |||
45 | and another sequence that does | ||
46 | |||
47 | spin_lock_irqsave(flags); | ||
48 | .. critical section .. | ||
49 | spin_unlock_irqrestore(flags); | ||
50 | |||
51 | then they are NOT mutually exclusive, and the critical regions can happen | ||
52 | at the same time on two different CPU's. That's fine per se, but the | ||
53 | critical regions had better be critical for different things (ie they | ||
54 | can't stomp on each other). | ||
55 | |||
56 | The above is a problem mainly if you end up mixing code - for example the | ||
57 | routines in ll_rw_block() tend to use cli/sti to protect the atomicity of | ||
58 | their actions, and if a driver uses spinlocks instead then you should | ||
59 | think about issues like the above. | ||
60 | 30 | ||
61 | This is really the only really hard part about spinlocks: once you start | 31 | This is really the only really hard part about spinlocks: once you start |
62 | using spinlocks they tend to expand to areas you might not have noticed | 32 | using spinlocks they tend to expand to areas you might not have noticed |
@@ -120,11 +90,10 @@ Lesson 3: spinlocks revisited. | |||
120 | 90 | ||
121 | The single spin-lock primitives above are by no means the only ones. They | 91 | The single spin-lock primitives above are by no means the only ones. They |
122 | are the most safe ones, and the ones that work under all circumstances, | 92 | are the most safe ones, and the ones that work under all circumstances, |
123 | but partly _because_ they are safe they are also fairly slow. They are | 93 | but partly _because_ they are safe they are also fairly slow. They are slower |
124 | much faster than a generic global cli/sti pair, but slower than they'd | 94 | than they'd need to be, because they do have to disable interrupts |
125 | need to be, because they do have to disable interrupts (which is just a | 95 | (which is just a single instruction on a x86, but it's an expensive one - |
126 | single instruction on a x86, but it's an expensive one - and on other | 96 | and on other architectures it can be worse). |
127 | architectures it can be worse). | ||
128 | 97 | ||
129 | If you have a case where you have to protect a data structure across | 98 | If you have a case where you have to protect a data structure across |
130 | several CPU's and you want to use spinlocks you can potentially use | 99 | several CPU's and you want to use spinlocks you can potentially use |
diff --git a/Documentation/x86/boot.txt b/Documentation/x86/boot.txt index 9b7221a86df2..7c3a8801b7ce 100644 --- a/Documentation/x86/boot.txt +++ b/Documentation/x86/boot.txt | |||
@@ -674,7 +674,7 @@ Protocol: 2.10+ | |||
674 | 674 | ||
675 | Field name: init_size | 675 | Field name: init_size |
676 | Type: read | 676 | Type: read |
677 | Offset/size: 0x25c/4 | 677 | Offset/size: 0x260/4 |
678 | 678 | ||
679 | This field indicates the amount of linear contiguous memory starting | 679 | This field indicates the amount of linear contiguous memory starting |
680 | at the kernel runtime start address that the kernel needs before it | 680 | at the kernel runtime start address that the kernel needs before it |
diff --git a/MAINTAINERS b/MAINTAINERS index ae563fad2271..187282da9213 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -594,6 +594,16 @@ S: Maintained | |||
594 | F: arch/arm/lib/floppydma.S | 594 | F: arch/arm/lib/floppydma.S |
595 | F: arch/arm/include/asm/floppy.h | 595 | F: arch/arm/include/asm/floppy.h |
596 | 596 | ||
597 | ARM PMU PROFILING AND DEBUGGING | ||
598 | M: Will Deacon <will.deacon@arm.com> | ||
599 | S: Maintained | ||
600 | F: arch/arm/kernel/perf_event* | ||
601 | F: arch/arm/oprofile/common.c | ||
602 | F: arch/arm/kernel/pmu.c | ||
603 | F: arch/arm/include/asm/pmu.h | ||
604 | F: arch/arm/kernel/hw_breakpoint.c | ||
605 | F: arch/arm/include/asm/hw_breakpoint.h | ||
606 | |||
597 | ARM PORT | 607 | ARM PORT |
598 | M: Russell King <linux@arm.linux.org.uk> | 608 | M: Russell King <linux@arm.linux.org.uk> |
599 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 609 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
@@ -2197,7 +2207,7 @@ F: drivers/acpi/dock.c | |||
2197 | DOCUMENTATION | 2207 | DOCUMENTATION |
2198 | M: Randy Dunlap <rdunlap@xenotime.net> | 2208 | M: Randy Dunlap <rdunlap@xenotime.net> |
2199 | L: linux-doc@vger.kernel.org | 2209 | L: linux-doc@vger.kernel.org |
2200 | T: quilt oss.oracle.com/~rdunlap/kernel-doc-patches/current/ | 2210 | T: quilt http://userweb.kernel.org/~rdunlap/kernel-doc-patches/current/ |
2201 | S: Maintained | 2211 | S: Maintained |
2202 | F: Documentation/ | 2212 | F: Documentation/ |
2203 | 2213 | ||
@@ -4982,7 +4992,7 @@ F: drivers/power/power_supply* | |||
4982 | 4992 | ||
4983 | PNP SUPPORT | 4993 | PNP SUPPORT |
4984 | M: Adam Belay <abelay@mit.edu> | 4994 | M: Adam Belay <abelay@mit.edu> |
4985 | M: Bjorn Helgaas <bjorn.helgaas@hp.com> | 4995 | M: Bjorn Helgaas <bhelgaas@google.com> |
4986 | S: Maintained | 4996 | S: Maintained |
4987 | F: drivers/pnp/ | 4997 | F: drivers/pnp/ |
4988 | 4998 | ||
@@ -6733,6 +6743,7 @@ F: fs/fat/ | |||
6733 | VIDEOBUF2 FRAMEWORK | 6743 | VIDEOBUF2 FRAMEWORK |
6734 | M: Pawel Osciak <pawel@osciak.com> | 6744 | M: Pawel Osciak <pawel@osciak.com> |
6735 | M: Marek Szyprowski <m.szyprowski@samsung.com> | 6745 | M: Marek Szyprowski <m.szyprowski@samsung.com> |
6746 | M: Kyungmin Park <kyungmin.park@samsung.com> | ||
6736 | L: linux-media@vger.kernel.org | 6747 | L: linux-media@vger.kernel.org |
6737 | S: Maintained | 6748 | S: Maintained |
6738 | F: drivers/media/video/videobuf2-* | 6749 | F: drivers/media/video/videobuf2-* |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 3 | 1 | VERSION = 3 |
2 | PATCHLEVEL = 0 | 2 | PATCHLEVEL = 0 |
3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 0 |
4 | EXTRAVERSION = -rc6 | 4 | EXTRAVERSION = -rc7 |
5 | NAME = Sneaky Weasel | 5 | NAME = Sneaky Weasel |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 9adc278a22ab..84fda2bebd7a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -37,6 +37,9 @@ config ARM | |||
37 | Europe. There is an ARM Linux project with a web page at | 37 | Europe. There is an ARM Linux project with a web page at |
38 | <http://www.arm.linux.org.uk/>. | 38 | <http://www.arm.linux.org.uk/>. |
39 | 39 | ||
40 | config ARM_HAS_SG_CHAIN | ||
41 | bool | ||
42 | |||
40 | config HAVE_PWM | 43 | config HAVE_PWM |
41 | bool | 44 | bool |
42 | 45 | ||
@@ -1346,7 +1349,6 @@ config SMP_ON_UP | |||
1346 | 1349 | ||
1347 | config HAVE_ARM_SCU | 1350 | config HAVE_ARM_SCU |
1348 | bool | 1351 | bool |
1349 | depends on SMP | ||
1350 | help | 1352 | help |
1351 | This option enables support for the ARM system coherency unit | 1353 | This option enables support for the ARM system coherency unit |
1352 | 1354 | ||
@@ -1715,17 +1717,34 @@ config ZBOOT_ROM | |||
1715 | Say Y here if you intend to execute your compressed kernel image | 1717 | Say Y here if you intend to execute your compressed kernel image |
1716 | (zImage) directly from ROM or flash. If unsure, say N. | 1718 | (zImage) directly from ROM or flash. If unsure, say N. |
1717 | 1719 | ||
1720 | choice | ||
1721 | prompt "Include SD/MMC loader in zImage (EXPERIMENTAL)" | ||
1722 | depends on ZBOOT_ROM && ARCH_SH7372 && EXPERIMENTAL | ||
1723 | default ZBOOT_ROM_NONE | ||
1724 | help | ||
1725 | Include experimental SD/MMC loading code in the ROM-able zImage. | ||
1726 | With this enabled it is possible to write the the ROM-able zImage | ||
1727 | kernel image to an MMC or SD card and boot the kernel straight | ||
1728 | from the reset vector. At reset the processor Mask ROM will load | ||
1729 | the first part of the the ROM-able zImage which in turn loads the | ||
1730 | rest the kernel image to RAM. | ||
1731 | |||
1732 | config ZBOOT_ROM_NONE | ||
1733 | bool "No SD/MMC loader in zImage (EXPERIMENTAL)" | ||
1734 | help | ||
1735 | Do not load image from SD or MMC | ||
1736 | |||
1718 | config ZBOOT_ROM_MMCIF | 1737 | config ZBOOT_ROM_MMCIF |
1719 | bool "Include MMCIF loader in zImage (EXPERIMENTAL)" | 1738 | bool "Include MMCIF loader in zImage (EXPERIMENTAL)" |
1720 | depends on ZBOOT_ROM && ARCH_SH7372 && EXPERIMENTAL | ||
1721 | help | 1739 | help |
1722 | Say Y here to include experimental MMCIF loading code in the | 1740 | Load image from MMCIF hardware block. |
1723 | ROM-able zImage. With this enabled it is possible to write the | 1741 | |
1724 | the ROM-able zImage kernel image to an MMC card and boot the | 1742 | config ZBOOT_ROM_SH_MOBILE_SDHI |
1725 | kernel straight from the reset vector. At reset the processor | 1743 | bool "Include SuperH Mobile SDHI loader in zImage (EXPERIMENTAL)" |
1726 | Mask ROM will load the first part of the the ROM-able zImage | 1744 | help |
1727 | which in turn loads the rest the kernel image to RAM using the | 1745 | Load image from SDHI hardware block |
1728 | MMCIF hardware block. | 1746 | |
1747 | endchoice | ||
1729 | 1748 | ||
1730 | config CMDLINE | 1749 | config CMDLINE |
1731 | string "Default kernel command string" | 1750 | string "Default kernel command string" |
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 23aad0722303..0c74a6fab952 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile | |||
@@ -6,13 +6,19 @@ | |||
6 | 6 | ||
7 | OBJS = | 7 | OBJS = |
8 | 8 | ||
9 | # Ensure that mmcif loader code appears early in the image | 9 | # Ensure that MMCIF loader code appears early in the image |
10 | # to minimise that number of bocks that have to be read in | 10 | # to minimise that number of bocks that have to be read in |
11 | # order to load it. | 11 | # order to load it. |
12 | ifeq ($(CONFIG_ZBOOT_ROM_MMCIF),y) | 12 | ifeq ($(CONFIG_ZBOOT_ROM_MMCIF),y) |
13 | ifeq ($(CONFIG_ARCH_SH7372),y) | ||
14 | OBJS += mmcif-sh7372.o | 13 | OBJS += mmcif-sh7372.o |
15 | endif | 14 | endif |
15 | |||
16 | # Ensure that SDHI loader code appears early in the image | ||
17 | # to minimise that number of bocks that have to be read in | ||
18 | # order to load it. | ||
19 | ifeq ($(CONFIG_ZBOOT_ROM_SH_MOBILE_SDHI),y) | ||
20 | OBJS += sdhi-shmobile.o | ||
21 | OBJS += sdhi-sh7372.o | ||
16 | endif | 22 | endif |
17 | 23 | ||
18 | AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET) | 24 | AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET) |
diff --git a/arch/arm/boot/compressed/head-shmobile.S b/arch/arm/boot/compressed/head-shmobile.S index c943d2e7da9d..fe3719b516fd 100644 --- a/arch/arm/boot/compressed/head-shmobile.S +++ b/arch/arm/boot/compressed/head-shmobile.S | |||
@@ -25,14 +25,14 @@ | |||
25 | /* load board-specific initialization code */ | 25 | /* load board-specific initialization code */ |
26 | #include <mach/zboot.h> | 26 | #include <mach/zboot.h> |
27 | 27 | ||
28 | #ifdef CONFIG_ZBOOT_ROM_MMCIF | 28 | #if defined(CONFIG_ZBOOT_ROM_MMCIF) || defined(CONFIG_ZBOOT_ROM_SH_MOBILE_SDHI) |
29 | /* Load image from MMC */ | 29 | /* Load image from MMC/SD */ |
30 | adr sp, __tmp_stack + 128 | 30 | adr sp, __tmp_stack + 256 |
31 | ldr r0, __image_start | 31 | ldr r0, __image_start |
32 | ldr r1, __image_end | 32 | ldr r1, __image_end |
33 | subs r1, r1, r0 | 33 | subs r1, r1, r0 |
34 | ldr r0, __load_base | 34 | ldr r0, __load_base |
35 | bl mmcif_loader | 35 | bl mmc_loader |
36 | 36 | ||
37 | /* Jump to loaded code */ | 37 | /* Jump to loaded code */ |
38 | ldr r0, __loaded | 38 | ldr r0, __loaded |
@@ -51,9 +51,9 @@ __loaded: | |||
51 | .long __continue | 51 | .long __continue |
52 | .align | 52 | .align |
53 | __tmp_stack: | 53 | __tmp_stack: |
54 | .space 128 | 54 | .space 256 |
55 | __continue: | 55 | __continue: |
56 | #endif /* CONFIG_ZBOOT_ROM_MMCIF */ | 56 | #endif /* CONFIG_ZBOOT_ROM_MMC || CONFIG_ZBOOT_ROM_SH_MOBILE_SDHI */ |
57 | 57 | ||
58 | b 1f | 58 | b 1f |
59 | __atags:@ tag #1 | 59 | __atags:@ tag #1 |
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index 940b20178107..e95a5989602a 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S | |||
@@ -353,7 +353,8 @@ not_relocated: mov r0, #0 | |||
353 | mov r0, #0 @ must be zero | 353 | mov r0, #0 @ must be zero |
354 | mov r1, r7 @ restore architecture number | 354 | mov r1, r7 @ restore architecture number |
355 | mov r2, r8 @ restore atags pointer | 355 | mov r2, r8 @ restore atags pointer |
356 | mov pc, r4 @ call kernel | 356 | ARM( mov pc, r4 ) @ call kernel |
357 | THUMB( bx r4 ) @ entry point is always ARM | ||
357 | 358 | ||
358 | .align 2 | 359 | .align 2 |
359 | .type LC0, #object | 360 | .type LC0, #object |
diff --git a/arch/arm/boot/compressed/mmcif-sh7372.c b/arch/arm/boot/compressed/mmcif-sh7372.c index 7453c8337b83..b6f61d9a5a1b 100644 --- a/arch/arm/boot/compressed/mmcif-sh7372.c +++ b/arch/arm/boot/compressed/mmcif-sh7372.c | |||
@@ -40,7 +40,7 @@ | |||
40 | * to an MMC card | 40 | * to an MMC card |
41 | * # dd if=vrl4.out of=/dev/sdx bs=512 seek=1 | 41 | * # dd if=vrl4.out of=/dev/sdx bs=512 seek=1 |
42 | */ | 42 | */ |
43 | asmlinkage void mmcif_loader(unsigned char *buf, unsigned long len) | 43 | asmlinkage void mmc_loader(unsigned char *buf, unsigned long len) |
44 | { | 44 | { |
45 | mmc_init_progress(); | 45 | mmc_init_progress(); |
46 | mmc_update_progress(MMC_PROGRESS_ENTER); | 46 | mmc_update_progress(MMC_PROGRESS_ENTER); |
diff --git a/arch/arm/boot/compressed/sdhi-sh7372.c b/arch/arm/boot/compressed/sdhi-sh7372.c new file mode 100644 index 000000000000..d403a8b24d7f --- /dev/null +++ b/arch/arm/boot/compressed/sdhi-sh7372.c | |||
@@ -0,0 +1,95 @@ | |||
1 | /* | ||
2 | * SuperH Mobile SDHI | ||
3 | * | ||
4 | * Copyright (C) 2010 Magnus Damm | ||
5 | * Copyright (C) 2010 Kuninori Morimoto | ||
6 | * Copyright (C) 2010 Simon Horman | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General Public | ||
9 | * License. See the file "COPYING" in the main directory of this archive | ||
10 | * for more details. | ||
11 | * | ||
12 | * Parts inspired by u-boot | ||
13 | */ | ||
14 | |||
15 | #include <linux/io.h> | ||
16 | #include <mach/mmc.h> | ||
17 | #include <linux/mmc/boot.h> | ||
18 | #include <linux/mmc/tmio.h> | ||
19 | |||
20 | #include "sdhi-shmobile.h" | ||
21 | |||
22 | #define PORT179CR 0xe60520b3 | ||
23 | #define PORT180CR 0xe60520b4 | ||
24 | #define PORT181CR 0xe60520b5 | ||
25 | #define PORT182CR 0xe60520b6 | ||
26 | #define PORT183CR 0xe60520b7 | ||
27 | #define PORT184CR 0xe60520b8 | ||
28 | |||
29 | #define SMSTPCR3 0xe615013c | ||
30 | |||
31 | #define CR_INPUT_ENABLE 0x10 | ||
32 | #define CR_FUNCTION1 0x01 | ||
33 | |||
34 | #define SDHI1_BASE (void __iomem *)0xe6860000 | ||
35 | #define SDHI_BASE SDHI1_BASE | ||
36 | |||
37 | /* SuperH Mobile SDHI loader | ||
38 | * | ||
39 | * loads the zImage from an SD card starting from block 0 | ||
40 | * on physical partition 1 | ||
41 | * | ||
42 | * The image must be start with a vrl4 header and | ||
43 | * the zImage must start at offset 512 of the image. That is, | ||
44 | * at block 1 (=byte 512) of physical partition 1 | ||
45 | * | ||
46 | * Use the following line to write the vrl4 formated zImage | ||
47 | * to an SD card | ||
48 | * # dd if=vrl4.out of=/dev/sdx bs=512 | ||
49 | */ | ||
50 | asmlinkage void mmc_loader(unsigned short *buf, unsigned long len) | ||
51 | { | ||
52 | int high_capacity; | ||
53 | |||
54 | mmc_init_progress(); | ||
55 | |||
56 | mmc_update_progress(MMC_PROGRESS_ENTER); | ||
57 | /* Initialise SDHI1 */ | ||
58 | /* PORT184CR: GPIO_FN_SDHICMD1 Control */ | ||
59 | __raw_writeb(CR_FUNCTION1, PORT184CR); | ||
60 | /* PORT179CR: GPIO_FN_SDHICLK1 Control */ | ||
61 | __raw_writeb(CR_INPUT_ENABLE|CR_FUNCTION1, PORT179CR); | ||
62 | /* PORT181CR: GPIO_FN_SDHID1_3 Control */ | ||
63 | __raw_writeb(CR_FUNCTION1, PORT183CR); | ||
64 | /* PORT182CR: GPIO_FN_SDHID1_2 Control */ | ||
65 | __raw_writeb(CR_FUNCTION1, PORT182CR); | ||
66 | /* PORT183CR: GPIO_FN_SDHID1_1 Control */ | ||
67 | __raw_writeb(CR_FUNCTION1, PORT181CR); | ||
68 | /* PORT180CR: GPIO_FN_SDHID1_0 Control */ | ||
69 | __raw_writeb(CR_FUNCTION1, PORT180CR); | ||
70 | |||
71 | /* Enable clock to SDHI1 hardware block */ | ||
72 | __raw_writel(__raw_readl(SMSTPCR3) & ~(1 << 13), SMSTPCR3); | ||
73 | |||
74 | /* setup SDHI hardware */ | ||
75 | mmc_update_progress(MMC_PROGRESS_INIT); | ||
76 | high_capacity = sdhi_boot_init(SDHI_BASE); | ||
77 | if (high_capacity < 0) | ||
78 | goto err; | ||
79 | |||
80 | mmc_update_progress(MMC_PROGRESS_LOAD); | ||
81 | /* load kernel */ | ||
82 | if (sdhi_boot_do_read(SDHI_BASE, high_capacity, | ||
83 | 0, /* Kernel is at block 1 */ | ||
84 | (len + TMIO_BBS - 1) / TMIO_BBS, buf)) | ||
85 | goto err; | ||
86 | |||
87 | /* Disable clock to SDHI1 hardware block */ | ||
88 | __raw_writel(__raw_readl(SMSTPCR3) & (1 << 13), SMSTPCR3); | ||
89 | |||
90 | mmc_update_progress(MMC_PROGRESS_DONE); | ||
91 | |||
92 | return; | ||
93 | err: | ||
94 | for(;;); | ||
95 | } | ||
diff --git a/arch/arm/boot/compressed/sdhi-shmobile.c b/arch/arm/boot/compressed/sdhi-shmobile.c new file mode 100644 index 000000000000..bd3d46980955 --- /dev/null +++ b/arch/arm/boot/compressed/sdhi-shmobile.c | |||
@@ -0,0 +1,449 @@ | |||
1 | /* | ||
2 | * SuperH Mobile SDHI | ||
3 | * | ||
4 | * Copyright (C) 2010 Magnus Damm | ||
5 | * Copyright (C) 2010 Kuninori Morimoto | ||
6 | * Copyright (C) 2010 Simon Horman | ||
7 | * | ||
8 | * This file is subject to the terms and conditions of the GNU General Public | ||
9 | * License. See the file "COPYING" in the main directory of this archive | ||
10 | * for more details. | ||
11 | * | ||
12 | * Parts inspired by u-boot | ||
13 | */ | ||
14 | |||
15 | #include <linux/io.h> | ||
16 | #include <linux/mmc/host.h> | ||
17 | #include <linux/mmc/core.h> | ||
18 | #include <linux/mmc/mmc.h> | ||
19 | #include <linux/mmc/sd.h> | ||
20 | #include <linux/mmc/tmio.h> | ||
21 | #include <mach/sdhi.h> | ||
22 | |||
23 | #define OCR_FASTBOOT (1<<29) | ||
24 | #define OCR_HCS (1<<30) | ||
25 | #define OCR_BUSY (1<<31) | ||
26 | |||
27 | #define RESP_CMD12 0x00000030 | ||
28 | |||
29 | static inline u16 sd_ctrl_read16(void __iomem *base, int addr) | ||
30 | { | ||
31 | return __raw_readw(base + addr); | ||
32 | } | ||
33 | |||
34 | static inline u32 sd_ctrl_read32(void __iomem *base, int addr) | ||
35 | { | ||
36 | return __raw_readw(base + addr) | | ||
37 | __raw_readw(base + addr + 2) << 16; | ||
38 | } | ||
39 | |||
40 | static inline void sd_ctrl_write16(void __iomem *base, int addr, u16 val) | ||
41 | { | ||
42 | __raw_writew(val, base + addr); | ||
43 | } | ||
44 | |||
45 | static inline void sd_ctrl_write32(void __iomem *base, int addr, u32 val) | ||
46 | { | ||
47 | __raw_writew(val, base + addr); | ||
48 | __raw_writew(val >> 16, base + addr + 2); | ||
49 | } | ||
50 | |||
51 | #define ALL_ERROR (TMIO_STAT_CMD_IDX_ERR | TMIO_STAT_CRCFAIL | \ | ||
52 | TMIO_STAT_STOPBIT_ERR | TMIO_STAT_DATATIMEOUT | \ | ||
53 | TMIO_STAT_RXOVERFLOW | TMIO_STAT_TXUNDERRUN | \ | ||
54 | TMIO_STAT_CMDTIMEOUT | TMIO_STAT_ILL_ACCESS | \ | ||
55 | TMIO_STAT_ILL_FUNC) | ||
56 | |||
57 | static int sdhi_intr(void __iomem *base) | ||
58 | { | ||
59 | unsigned long state = sd_ctrl_read32(base, CTL_STATUS); | ||
60 | |||
61 | if (state & ALL_ERROR) { | ||
62 | sd_ctrl_write32(base, CTL_STATUS, ~ALL_ERROR); | ||
63 | sd_ctrl_write32(base, CTL_IRQ_MASK, | ||
64 | ALL_ERROR | | ||
65 | sd_ctrl_read32(base, CTL_IRQ_MASK)); | ||
66 | return -EINVAL; | ||
67 | } | ||
68 | if (state & TMIO_STAT_CMDRESPEND) { | ||
69 | sd_ctrl_write32(base, CTL_STATUS, ~TMIO_STAT_CMDRESPEND); | ||
70 | sd_ctrl_write32(base, CTL_IRQ_MASK, | ||
71 | TMIO_STAT_CMDRESPEND | | ||
72 | sd_ctrl_read32(base, CTL_IRQ_MASK)); | ||
73 | return 0; | ||
74 | } | ||
75 | if (state & TMIO_STAT_RXRDY) { | ||
76 | sd_ctrl_write32(base, CTL_STATUS, ~TMIO_STAT_RXRDY); | ||
77 | sd_ctrl_write32(base, CTL_IRQ_MASK, | ||
78 | TMIO_STAT_RXRDY | TMIO_STAT_TXUNDERRUN | | ||
79 | sd_ctrl_read32(base, CTL_IRQ_MASK)); | ||
80 | return 0; | ||
81 | } | ||
82 | if (state & TMIO_STAT_DATAEND) { | ||
83 | sd_ctrl_write32(base, CTL_STATUS, ~TMIO_STAT_DATAEND); | ||
84 | sd_ctrl_write32(base, CTL_IRQ_MASK, | ||
85 | TMIO_STAT_DATAEND | | ||
86 | sd_ctrl_read32(base, CTL_IRQ_MASK)); | ||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | return -EAGAIN; | ||
91 | } | ||
92 | |||
93 | static int sdhi_boot_wait_resp_end(void __iomem *base) | ||
94 | { | ||
95 | int err = -EAGAIN, timeout = 10000000; | ||
96 | |||
97 | while (timeout--) { | ||
98 | err = sdhi_intr(base); | ||
99 | if (err != -EAGAIN) | ||
100 | break; | ||
101 | udelay(1); | ||
102 | } | ||
103 | |||
104 | return err; | ||
105 | } | ||
106 | |||
107 | /* SDHI_CLK_CTRL */ | ||
108 | #define CLK_MMC_ENABLE (1 << 8) | ||
109 | #define CLK_MMC_INIT (1 << 6) /* clk / 256 */ | ||
110 | |||
111 | static void sdhi_boot_mmc_clk_stop(void __iomem *base) | ||
112 | { | ||
113 | sd_ctrl_write16(base, CTL_CLK_AND_WAIT_CTL, 0x0000); | ||
114 | msleep(10); | ||
115 | sd_ctrl_write16(base, CTL_SD_CARD_CLK_CTL, ~CLK_MMC_ENABLE & | ||
116 | sd_ctrl_read16(base, CTL_SD_CARD_CLK_CTL)); | ||
117 | msleep(10); | ||
118 | } | ||
119 | |||
120 | static void sdhi_boot_mmc_clk_start(void __iomem *base) | ||
121 | { | ||
122 | sd_ctrl_write16(base, CTL_SD_CARD_CLK_CTL, CLK_MMC_ENABLE | | ||
123 | sd_ctrl_read16(base, CTL_SD_CARD_CLK_CTL)); | ||
124 | msleep(10); | ||
125 | sd_ctrl_write16(base, CTL_CLK_AND_WAIT_CTL, CLK_MMC_ENABLE); | ||
126 | msleep(10); | ||
127 | } | ||
128 | |||
129 | static void sdhi_boot_reset(void __iomem *base) | ||
130 | { | ||
131 | sd_ctrl_write16(base, CTL_RESET_SD, 0x0000); | ||
132 | msleep(10); | ||
133 | sd_ctrl_write16(base, CTL_RESET_SD, 0x0001); | ||
134 | msleep(10); | ||
135 | } | ||
136 | |||
137 | /* Set MMC clock / power. | ||
138 | * Note: This controller uses a simple divider scheme therefore it cannot | ||
139 | * run a MMC card at full speed (20MHz). The max clock is 24MHz on SD, but as | ||
140 | * MMC wont run that fast, it has to be clocked at 12MHz which is the next | ||
141 | * slowest setting. | ||
142 | */ | ||
143 | static int sdhi_boot_mmc_set_ios(void __iomem *base, struct mmc_ios *ios) | ||
144 | { | ||
145 | if (sd_ctrl_read32(base, CTL_STATUS) & TMIO_STAT_CMD_BUSY) | ||
146 | return -EBUSY; | ||
147 | |||
148 | if (ios->clock) | ||
149 | sd_ctrl_write16(base, CTL_SD_CARD_CLK_CTL, | ||
150 | ios->clock | CLK_MMC_ENABLE); | ||
151 | |||
152 | /* Power sequence - OFF -> ON -> UP */ | ||
153 | switch (ios->power_mode) { | ||
154 | case MMC_POWER_OFF: /* power down SD bus */ | ||
155 | sdhi_boot_mmc_clk_stop(base); | ||
156 | break; | ||
157 | case MMC_POWER_ON: /* power up SD bus */ | ||
158 | break; | ||
159 | case MMC_POWER_UP: /* start bus clock */ | ||
160 | sdhi_boot_mmc_clk_start(base); | ||
161 | break; | ||
162 | } | ||
163 | |||
164 | switch (ios->bus_width) { | ||
165 | case MMC_BUS_WIDTH_1: | ||
166 | sd_ctrl_write16(base, CTL_SD_MEM_CARD_OPT, 0x80e0); | ||
167 | break; | ||
168 | case MMC_BUS_WIDTH_4: | ||
169 | sd_ctrl_write16(base, CTL_SD_MEM_CARD_OPT, 0x00e0); | ||
170 | break; | ||
171 | } | ||
172 | |||
173 | /* Let things settle. delay taken from winCE driver */ | ||
174 | udelay(140); | ||
175 | |||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | /* These are the bitmasks the tmio chip requires to implement the MMC response | ||
180 | * types. Note that R1 and R6 are the same in this scheme. */ | ||
181 | #define RESP_NONE 0x0300 | ||
182 | #define RESP_R1 0x0400 | ||
183 | #define RESP_R1B 0x0500 | ||
184 | #define RESP_R2 0x0600 | ||
185 | #define RESP_R3 0x0700 | ||
186 | #define DATA_PRESENT 0x0800 | ||
187 | #define TRANSFER_READ 0x1000 | ||
188 | |||
189 | static int sdhi_boot_request(void __iomem *base, struct mmc_command *cmd) | ||
190 | { | ||
191 | int err, c = cmd->opcode; | ||
192 | |||
193 | switch (mmc_resp_type(cmd)) { | ||
194 | case MMC_RSP_NONE: c |= RESP_NONE; break; | ||
195 | case MMC_RSP_R1: c |= RESP_R1; break; | ||
196 | case MMC_RSP_R1B: c |= RESP_R1B; break; | ||
197 | case MMC_RSP_R2: c |= RESP_R2; break; | ||
198 | case MMC_RSP_R3: c |= RESP_R3; break; | ||
199 | default: | ||
200 | return -EINVAL; | ||
201 | } | ||
202 | |||
203 | /* No interrupts so this may not be cleared */ | ||
204 | sd_ctrl_write32(base, CTL_STATUS, ~TMIO_STAT_CMDRESPEND); | ||
205 | |||
206 | sd_ctrl_write32(base, CTL_IRQ_MASK, TMIO_STAT_CMDRESPEND | | ||
207 | sd_ctrl_read32(base, CTL_IRQ_MASK)); | ||
208 | sd_ctrl_write32(base, CTL_ARG_REG, cmd->arg); | ||
209 | sd_ctrl_write16(base, CTL_SD_CMD, c); | ||
210 | |||
211 | |||
212 | sd_ctrl_write32(base, CTL_IRQ_MASK, | ||
213 | ~(TMIO_STAT_CMDRESPEND | ALL_ERROR) & | ||
214 | sd_ctrl_read32(base, CTL_IRQ_MASK)); | ||
215 | |||
216 | err = sdhi_boot_wait_resp_end(base); | ||
217 | if (err) | ||
218 | return err; | ||
219 | |||
220 | cmd->resp[0] = sd_ctrl_read32(base, CTL_RESPONSE); | ||
221 | |||
222 | return 0; | ||
223 | } | ||
224 | |||
225 | static int sdhi_boot_do_read_single(void __iomem *base, int high_capacity, | ||
226 | unsigned long block, unsigned short *buf) | ||
227 | { | ||
228 | int err, i; | ||
229 | |||
230 | /* CMD17 - Read */ | ||
231 | { | ||
232 | struct mmc_command cmd; | ||
233 | |||
234 | cmd.opcode = MMC_READ_SINGLE_BLOCK | \ | ||
235 | TRANSFER_READ | DATA_PRESENT; | ||
236 | if (high_capacity) | ||
237 | cmd.arg = block; | ||
238 | else | ||
239 | cmd.arg = block * TMIO_BBS; | ||
240 | cmd.flags = MMC_RSP_R1; | ||
241 | err = sdhi_boot_request(base, &cmd); | ||
242 | if (err) | ||
243 | return err; | ||
244 | } | ||
245 | |||
246 | sd_ctrl_write32(base, CTL_IRQ_MASK, | ||
247 | ~(TMIO_STAT_DATAEND | TMIO_STAT_RXRDY | | ||
248 | TMIO_STAT_TXUNDERRUN) & | ||
249 | sd_ctrl_read32(base, CTL_IRQ_MASK)); | ||
250 | err = sdhi_boot_wait_resp_end(base); | ||
251 | if (err) | ||
252 | return err; | ||
253 | |||
254 | sd_ctrl_write16(base, CTL_SD_XFER_LEN, TMIO_BBS); | ||
255 | for (i = 0; i < TMIO_BBS / sizeof(*buf); i++) | ||
256 | *buf++ = sd_ctrl_read16(base, RESP_CMD12); | ||
257 | |||
258 | err = sdhi_boot_wait_resp_end(base); | ||
259 | if (err) | ||
260 | return err; | ||
261 | |||
262 | return 0; | ||
263 | } | ||
264 | |||
265 | int sdhi_boot_do_read(void __iomem *base, int high_capacity, | ||
266 | unsigned long offset, unsigned short count, | ||
267 | unsigned short *buf) | ||
268 | { | ||
269 | unsigned long i; | ||
270 | int err = 0; | ||
271 | |||
272 | for (i = 0; i < count; i++) { | ||
273 | err = sdhi_boot_do_read_single(base, high_capacity, offset + i, | ||
274 | buf + (i * TMIO_BBS / | ||
275 | sizeof(*buf))); | ||
276 | if (err) | ||
277 | return err; | ||
278 | } | ||
279 | |||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | #define VOLTAGES (MMC_VDD_32_33 | MMC_VDD_33_34) | ||
284 | |||
285 | int sdhi_boot_init(void __iomem *base) | ||
286 | { | ||
287 | bool sd_v2 = false, sd_v1_0 = false; | ||
288 | unsigned short cid; | ||
289 | int err, high_capacity = 0; | ||
290 | |||
291 | sdhi_boot_mmc_clk_stop(base); | ||
292 | sdhi_boot_reset(base); | ||
293 | |||
294 | /* mmc0: clock 400000Hz busmode 1 powermode 2 cs 0 Vdd 21 width 0 timing 0 */ | ||
295 | { | ||
296 | struct mmc_ios ios; | ||
297 | ios.power_mode = MMC_POWER_ON; | ||
298 | ios.bus_width = MMC_BUS_WIDTH_1; | ||
299 | ios.clock = CLK_MMC_INIT; | ||
300 | err = sdhi_boot_mmc_set_ios(base, &ios); | ||
301 | if (err) | ||
302 | return err; | ||
303 | } | ||
304 | |||
305 | /* CMD0 */ | ||
306 | { | ||
307 | struct mmc_command cmd; | ||
308 | msleep(1); | ||
309 | cmd.opcode = MMC_GO_IDLE_STATE; | ||
310 | cmd.arg = 0; | ||
311 | cmd.flags = MMC_RSP_NONE; | ||
312 | err = sdhi_boot_request(base, &cmd); | ||
313 | if (err) | ||
314 | return err; | ||
315 | msleep(2); | ||
316 | } | ||
317 | |||
318 | /* CMD8 - Test for SD version 2 */ | ||
319 | { | ||
320 | struct mmc_command cmd; | ||
321 | cmd.opcode = SD_SEND_IF_COND; | ||
322 | cmd.arg = (VOLTAGES != 0) << 8 | 0xaa; | ||
323 | cmd.flags = MMC_RSP_R1; | ||
324 | err = sdhi_boot_request(base, &cmd); /* Ignore error */ | ||
325 | if ((cmd.resp[0] & 0xff) == 0xaa) | ||
326 | sd_v2 = true; | ||
327 | } | ||
328 | |||
329 | /* CMD55 - Get OCR (SD) */ | ||
330 | { | ||
331 | int timeout = 1000; | ||
332 | struct mmc_command cmd; | ||
333 | |||
334 | cmd.arg = 0; | ||
335 | |||
336 | do { | ||
337 | cmd.opcode = MMC_APP_CMD; | ||
338 | cmd.flags = MMC_RSP_R1; | ||
339 | cmd.arg = 0; | ||
340 | err = sdhi_boot_request(base, &cmd); | ||
341 | if (err) | ||
342 | break; | ||
343 | |||
344 | cmd.opcode = SD_APP_OP_COND; | ||
345 | cmd.flags = MMC_RSP_R3; | ||
346 | cmd.arg = (VOLTAGES & 0xff8000); | ||
347 | if (sd_v2) | ||
348 | cmd.arg |= OCR_HCS; | ||
349 | cmd.arg |= OCR_FASTBOOT; | ||
350 | err = sdhi_boot_request(base, &cmd); | ||
351 | if (err) | ||
352 | break; | ||
353 | |||
354 | msleep(1); | ||
355 | } while((!(cmd.resp[0] & OCR_BUSY)) && --timeout); | ||
356 | |||
357 | if (!err && timeout) { | ||
358 | if (!sd_v2) | ||
359 | sd_v1_0 = true; | ||
360 | high_capacity = (cmd.resp[0] & OCR_HCS) == OCR_HCS; | ||
361 | } | ||
362 | } | ||
363 | |||
364 | /* CMD1 - Get OCR (MMC) */ | ||
365 | if (!sd_v2 && !sd_v1_0) { | ||
366 | int timeout = 1000; | ||
367 | struct mmc_command cmd; | ||
368 | |||
369 | do { | ||
370 | cmd.opcode = MMC_SEND_OP_COND; | ||
371 | cmd.arg = VOLTAGES | OCR_HCS; | ||
372 | cmd.flags = MMC_RSP_R3; | ||
373 | err = sdhi_boot_request(base, &cmd); | ||
374 | if (err) | ||
375 | return err; | ||
376 | |||
377 | msleep(1); | ||
378 | } while((!(cmd.resp[0] & OCR_BUSY)) && --timeout); | ||
379 | |||
380 | if (!timeout) | ||
381 | return -EAGAIN; | ||
382 | |||
383 | high_capacity = (cmd.resp[0] & OCR_HCS) == OCR_HCS; | ||
384 | } | ||
385 | |||
386 | /* CMD2 - Get CID */ | ||
387 | { | ||
388 | struct mmc_command cmd; | ||
389 | cmd.opcode = MMC_ALL_SEND_CID; | ||
390 | cmd.arg = 0; | ||
391 | cmd.flags = MMC_RSP_R2; | ||
392 | err = sdhi_boot_request(base, &cmd); | ||
393 | if (err) | ||
394 | return err; | ||
395 | } | ||
396 | |||
397 | /* CMD3 | ||
398 | * MMC: Set the relative address | ||
399 | * SD: Get the relative address | ||
400 | * Also puts the card into the standby state | ||
401 | */ | ||
402 | { | ||
403 | struct mmc_command cmd; | ||
404 | cmd.opcode = MMC_SET_RELATIVE_ADDR; | ||
405 | cmd.arg = 0; | ||
406 | cmd.flags = MMC_RSP_R1; | ||
407 | err = sdhi_boot_request(base, &cmd); | ||
408 | if (err) | ||
409 | return err; | ||
410 | cid = cmd.resp[0] >> 16; | ||
411 | } | ||
412 | |||
413 | /* CMD9 - Get CSD */ | ||
414 | { | ||
415 | struct mmc_command cmd; | ||
416 | cmd.opcode = MMC_SEND_CSD; | ||
417 | cmd.arg = cid << 16; | ||
418 | cmd.flags = MMC_RSP_R2; | ||
419 | err = sdhi_boot_request(base, &cmd); | ||
420 | if (err) | ||
421 | return err; | ||
422 | } | ||
423 | |||
424 | /* CMD7 - Select the card */ | ||
425 | { | ||
426 | struct mmc_command cmd; | ||
427 | cmd.opcode = MMC_SELECT_CARD; | ||
428 | //cmd.arg = rca << 16; | ||
429 | cmd.arg = cid << 16; | ||
430 | //cmd.flags = MMC_RSP_R1B; | ||
431 | cmd.flags = MMC_RSP_R1; | ||
432 | err = sdhi_boot_request(base, &cmd); | ||
433 | if (err) | ||
434 | return err; | ||
435 | } | ||
436 | |||
437 | /* CMD16 - Set the block size */ | ||
438 | { | ||
439 | struct mmc_command cmd; | ||
440 | cmd.opcode = MMC_SET_BLOCKLEN; | ||
441 | cmd.arg = TMIO_BBS; | ||
442 | cmd.flags = MMC_RSP_R1; | ||
443 | err = sdhi_boot_request(base, &cmd); | ||
444 | if (err) | ||
445 | return err; | ||
446 | } | ||
447 | |||
448 | return high_capacity; | ||
449 | } | ||
diff --git a/arch/arm/boot/compressed/sdhi-shmobile.h b/arch/arm/boot/compressed/sdhi-shmobile.h new file mode 100644 index 000000000000..92eaa09f985e --- /dev/null +++ b/arch/arm/boot/compressed/sdhi-shmobile.h | |||
@@ -0,0 +1,11 @@ | |||
1 | #ifndef SDHI_MOBILE_H | ||
2 | #define SDHI_MOBILE_H | ||
3 | |||
4 | #include <linux/compiler.h> | ||
5 | |||
6 | int sdhi_boot_do_read(void __iomem *base, int high_capacity, | ||
7 | unsigned long offset, unsigned short count, | ||
8 | unsigned short *buf); | ||
9 | int sdhi_boot_init(void __iomem *base); | ||
10 | |||
11 | #endif | ||
diff --git a/arch/arm/boot/compressed/vmlinux.lds.in b/arch/arm/boot/compressed/vmlinux.lds.in index ea80abe78844..4e728834a1b9 100644 --- a/arch/arm/boot/compressed/vmlinux.lds.in +++ b/arch/arm/boot/compressed/vmlinux.lds.in | |||
@@ -33,20 +33,24 @@ SECTIONS | |||
33 | *(.text.*) | 33 | *(.text.*) |
34 | *(.fixup) | 34 | *(.fixup) |
35 | *(.gnu.warning) | 35 | *(.gnu.warning) |
36 | *(.glue_7t) | ||
37 | *(.glue_7) | ||
38 | } | ||
39 | .rodata : { | ||
36 | *(.rodata) | 40 | *(.rodata) |
37 | *(.rodata.*) | 41 | *(.rodata.*) |
38 | *(.glue_7) | 42 | } |
39 | *(.glue_7t) | 43 | .piggydata : { |
40 | *(.piggydata) | 44 | *(.piggydata) |
41 | . = ALIGN(4); | ||
42 | } | 45 | } |
43 | 46 | ||
47 | . = ALIGN(4); | ||
44 | _etext = .; | 48 | _etext = .; |
45 | 49 | ||
50 | .got.plt : { *(.got.plt) } | ||
46 | _got_start = .; | 51 | _got_start = .; |
47 | .got : { *(.got) } | 52 | .got : { *(.got) } |
48 | _got_end = .; | 53 | _got_end = .; |
49 | .got.plt : { *(.got.plt) } | ||
50 | _edata = .; | 54 | _edata = .; |
51 | 55 | ||
52 | . = BSS_START; | 56 | . = BSS_START; |
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c index e5681636626f..595ecd290ebf 100644 --- a/arch/arm/common/dmabounce.c +++ b/arch/arm/common/dmabounce.c | |||
@@ -79,6 +79,8 @@ struct dmabounce_device_info { | |||
79 | struct dmabounce_pool large; | 79 | struct dmabounce_pool large; |
80 | 80 | ||
81 | rwlock_t lock; | 81 | rwlock_t lock; |
82 | |||
83 | int (*needs_bounce)(struct device *, dma_addr_t, size_t); | ||
82 | }; | 84 | }; |
83 | 85 | ||
84 | #ifdef STATS | 86 | #ifdef STATS |
@@ -210,114 +212,91 @@ static struct safe_buffer *find_safe_buffer_dev(struct device *dev, | |||
210 | if (!dev || !dev->archdata.dmabounce) | 212 | if (!dev || !dev->archdata.dmabounce) |
211 | return NULL; | 213 | return NULL; |
212 | if (dma_mapping_error(dev, dma_addr)) { | 214 | if (dma_mapping_error(dev, dma_addr)) { |
213 | if (dev) | 215 | dev_err(dev, "Trying to %s invalid mapping\n", where); |
214 | dev_err(dev, "Trying to %s invalid mapping\n", where); | ||
215 | else | ||
216 | pr_err("unknown device: Trying to %s invalid mapping\n", where); | ||
217 | return NULL; | 216 | return NULL; |
218 | } | 217 | } |
219 | return find_safe_buffer(dev->archdata.dmabounce, dma_addr); | 218 | return find_safe_buffer(dev->archdata.dmabounce, dma_addr); |
220 | } | 219 | } |
221 | 220 | ||
222 | static inline dma_addr_t map_single(struct device *dev, void *ptr, size_t size, | 221 | static int needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) |
223 | enum dma_data_direction dir) | ||
224 | { | 222 | { |
225 | struct dmabounce_device_info *device_info = dev->archdata.dmabounce; | 223 | if (!dev || !dev->archdata.dmabounce) |
226 | dma_addr_t dma_addr; | 224 | return 0; |
227 | int needs_bounce = 0; | ||
228 | |||
229 | if (device_info) | ||
230 | DO_STATS ( device_info->map_op_count++ ); | ||
231 | |||
232 | dma_addr = virt_to_dma(dev, ptr); | ||
233 | 225 | ||
234 | if (dev->dma_mask) { | 226 | if (dev->dma_mask) { |
235 | unsigned long mask = *dev->dma_mask; | 227 | unsigned long limit, mask = *dev->dma_mask; |
236 | unsigned long limit; | ||
237 | 228 | ||
238 | limit = (mask + 1) & ~mask; | 229 | limit = (mask + 1) & ~mask; |
239 | if (limit && size > limit) { | 230 | if (limit && size > limit) { |
240 | dev_err(dev, "DMA mapping too big (requested %#x " | 231 | dev_err(dev, "DMA mapping too big (requested %#x " |
241 | "mask %#Lx)\n", size, *dev->dma_mask); | 232 | "mask %#Lx)\n", size, *dev->dma_mask); |
242 | return ~0; | 233 | return -E2BIG; |
243 | } | 234 | } |
244 | 235 | ||
245 | /* | 236 | /* Figure out if we need to bounce from the DMA mask. */ |
246 | * Figure out if we need to bounce from the DMA mask. | 237 | if ((dma_addr | (dma_addr + size - 1)) & ~mask) |
247 | */ | 238 | return 1; |
248 | needs_bounce = (dma_addr | (dma_addr + size - 1)) & ~mask; | ||
249 | } | 239 | } |
250 | 240 | ||
251 | if (device_info && (needs_bounce || dma_needs_bounce(dev, dma_addr, size))) { | 241 | return !!dev->archdata.dmabounce->needs_bounce(dev, dma_addr, size); |
252 | struct safe_buffer *buf; | 242 | } |
253 | 243 | ||
254 | buf = alloc_safe_buffer(device_info, ptr, size, dir); | 244 | static inline dma_addr_t map_single(struct device *dev, void *ptr, size_t size, |
255 | if (buf == 0) { | 245 | enum dma_data_direction dir) |
256 | dev_err(dev, "%s: unable to map unsafe buffer %p!\n", | 246 | { |
257 | __func__, ptr); | 247 | struct dmabounce_device_info *device_info = dev->archdata.dmabounce; |
258 | return 0; | 248 | struct safe_buffer *buf; |
259 | } | ||
260 | 249 | ||
261 | dev_dbg(dev, | 250 | if (device_info) |
262 | "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n", | 251 | DO_STATS ( device_info->map_op_count++ ); |
263 | __func__, buf->ptr, virt_to_dma(dev, buf->ptr), | ||
264 | buf->safe, buf->safe_dma_addr); | ||
265 | 252 | ||
266 | if ((dir == DMA_TO_DEVICE) || | 253 | buf = alloc_safe_buffer(device_info, ptr, size, dir); |
267 | (dir == DMA_BIDIRECTIONAL)) { | 254 | if (buf == NULL) { |
268 | dev_dbg(dev, "%s: copy unsafe %p to safe %p, size %d\n", | 255 | dev_err(dev, "%s: unable to map unsafe buffer %p!\n", |
269 | __func__, ptr, buf->safe, size); | 256 | __func__, ptr); |
270 | memcpy(buf->safe, ptr, size); | 257 | return ~0; |
271 | } | 258 | } |
272 | ptr = buf->safe; | ||
273 | 259 | ||
274 | dma_addr = buf->safe_dma_addr; | 260 | dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n", |
275 | } else { | 261 | __func__, buf->ptr, virt_to_dma(dev, buf->ptr), |
276 | /* | 262 | buf->safe, buf->safe_dma_addr); |
277 | * We don't need to sync the DMA buffer since | 263 | |
278 | * it was allocated via the coherent allocators. | 264 | if (dir == DMA_TO_DEVICE || dir == DMA_BIDIRECTIONAL) { |
279 | */ | 265 | dev_dbg(dev, "%s: copy unsafe %p to safe %p, size %d\n", |
280 | __dma_single_cpu_to_dev(ptr, size, dir); | 266 | __func__, ptr, buf->safe, size); |
267 | memcpy(buf->safe, ptr, size); | ||
281 | } | 268 | } |
282 | 269 | ||
283 | return dma_addr; | 270 | return buf->safe_dma_addr; |
284 | } | 271 | } |
285 | 272 | ||
286 | static inline void unmap_single(struct device *dev, dma_addr_t dma_addr, | 273 | static inline void unmap_single(struct device *dev, struct safe_buffer *buf, |
287 | size_t size, enum dma_data_direction dir) | 274 | size_t size, enum dma_data_direction dir) |
288 | { | 275 | { |
289 | struct safe_buffer *buf = find_safe_buffer_dev(dev, dma_addr, "unmap"); | 276 | BUG_ON(buf->size != size); |
290 | 277 | BUG_ON(buf->direction != dir); | |
291 | if (buf) { | ||
292 | BUG_ON(buf->size != size); | ||
293 | BUG_ON(buf->direction != dir); | ||
294 | 278 | ||
295 | dev_dbg(dev, | 279 | dev_dbg(dev, "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n", |
296 | "%s: unsafe buffer %p (dma=%#x) mapped to %p (dma=%#x)\n", | 280 | __func__, buf->ptr, virt_to_dma(dev, buf->ptr), |
297 | __func__, buf->ptr, virt_to_dma(dev, buf->ptr), | 281 | buf->safe, buf->safe_dma_addr); |
298 | buf->safe, buf->safe_dma_addr); | ||
299 | 282 | ||
300 | DO_STATS(dev->archdata.dmabounce->bounce_count++); | 283 | DO_STATS(dev->archdata.dmabounce->bounce_count++); |
301 | 284 | ||
302 | if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) { | 285 | if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) { |
303 | void *ptr = buf->ptr; | 286 | void *ptr = buf->ptr; |
304 | 287 | ||
305 | dev_dbg(dev, | 288 | dev_dbg(dev, "%s: copy back safe %p to unsafe %p size %d\n", |
306 | "%s: copy back safe %p to unsafe %p size %d\n", | 289 | __func__, buf->safe, ptr, size); |
307 | __func__, buf->safe, ptr, size); | 290 | memcpy(ptr, buf->safe, size); |
308 | memcpy(ptr, buf->safe, size); | ||
309 | 291 | ||
310 | /* | 292 | /* |
311 | * Since we may have written to a page cache page, | 293 | * Since we may have written to a page cache page, |
312 | * we need to ensure that the data will be coherent | 294 | * we need to ensure that the data will be coherent |
313 | * with user mappings. | 295 | * with user mappings. |
314 | */ | 296 | */ |
315 | __cpuc_flush_dcache_area(ptr, size); | 297 | __cpuc_flush_dcache_area(ptr, size); |
316 | } | ||
317 | free_safe_buffer(dev->archdata.dmabounce, buf); | ||
318 | } else { | ||
319 | __dma_single_dev_to_cpu(dma_to_virt(dev, dma_addr), size, dir); | ||
320 | } | 298 | } |
299 | free_safe_buffer(dev->archdata.dmabounce, buf); | ||
321 | } | 300 | } |
322 | 301 | ||
323 | /* ************************************************** */ | 302 | /* ************************************************** */ |
@@ -328,45 +307,28 @@ static inline void unmap_single(struct device *dev, dma_addr_t dma_addr, | |||
328 | * substitute the safe buffer for the unsafe one. | 307 | * substitute the safe buffer for the unsafe one. |
329 | * (basically move the buffer from an unsafe area to a safe one) | 308 | * (basically move the buffer from an unsafe area to a safe one) |
330 | */ | 309 | */ |
331 | dma_addr_t __dma_map_single(struct device *dev, void *ptr, size_t size, | ||
332 | enum dma_data_direction dir) | ||
333 | { | ||
334 | dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", | ||
335 | __func__, ptr, size, dir); | ||
336 | |||
337 | BUG_ON(!valid_dma_direction(dir)); | ||
338 | |||
339 | return map_single(dev, ptr, size, dir); | ||
340 | } | ||
341 | EXPORT_SYMBOL(__dma_map_single); | ||
342 | |||
343 | /* | ||
344 | * see if a mapped address was really a "safe" buffer and if so, copy | ||
345 | * the data from the safe buffer back to the unsafe buffer and free up | ||
346 | * the safe buffer. (basically return things back to the way they | ||
347 | * should be) | ||
348 | */ | ||
349 | void __dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, | ||
350 | enum dma_data_direction dir) | ||
351 | { | ||
352 | dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", | ||
353 | __func__, (void *) dma_addr, size, dir); | ||
354 | |||
355 | unmap_single(dev, dma_addr, size, dir); | ||
356 | } | ||
357 | EXPORT_SYMBOL(__dma_unmap_single); | ||
358 | |||
359 | dma_addr_t __dma_map_page(struct device *dev, struct page *page, | 310 | dma_addr_t __dma_map_page(struct device *dev, struct page *page, |
360 | unsigned long offset, size_t size, enum dma_data_direction dir) | 311 | unsigned long offset, size_t size, enum dma_data_direction dir) |
361 | { | 312 | { |
313 | dma_addr_t dma_addr; | ||
314 | int ret; | ||
315 | |||
362 | dev_dbg(dev, "%s(page=%p,off=%#lx,size=%zx,dir=%x)\n", | 316 | dev_dbg(dev, "%s(page=%p,off=%#lx,size=%zx,dir=%x)\n", |
363 | __func__, page, offset, size, dir); | 317 | __func__, page, offset, size, dir); |
364 | 318 | ||
365 | BUG_ON(!valid_dma_direction(dir)); | 319 | dma_addr = pfn_to_dma(dev, page_to_pfn(page)) + offset; |
320 | |||
321 | ret = needs_bounce(dev, dma_addr, size); | ||
322 | if (ret < 0) | ||
323 | return ~0; | ||
324 | |||
325 | if (ret == 0) { | ||
326 | __dma_page_cpu_to_dev(page, offset, size, dir); | ||
327 | return dma_addr; | ||
328 | } | ||
366 | 329 | ||
367 | if (PageHighMem(page)) { | 330 | if (PageHighMem(page)) { |
368 | dev_err(dev, "DMA buffer bouncing of HIGHMEM pages " | 331 | dev_err(dev, "DMA buffer bouncing of HIGHMEM pages is not supported\n"); |
369 | "is not supported\n"); | ||
370 | return ~0; | 332 | return ~0; |
371 | } | 333 | } |
372 | 334 | ||
@@ -383,10 +345,19 @@ EXPORT_SYMBOL(__dma_map_page); | |||
383 | void __dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, | 345 | void __dma_unmap_page(struct device *dev, dma_addr_t dma_addr, size_t size, |
384 | enum dma_data_direction dir) | 346 | enum dma_data_direction dir) |
385 | { | 347 | { |
386 | dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", | 348 | struct safe_buffer *buf; |
387 | __func__, (void *) dma_addr, size, dir); | 349 | |
350 | dev_dbg(dev, "%s(dma=%#x,size=%d,dir=%x)\n", | ||
351 | __func__, dma_addr, size, dir); | ||
352 | |||
353 | buf = find_safe_buffer_dev(dev, dma_addr, __func__); | ||
354 | if (!buf) { | ||
355 | __dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, dma_addr)), | ||
356 | dma_addr & ~PAGE_MASK, size, dir); | ||
357 | return; | ||
358 | } | ||
388 | 359 | ||
389 | unmap_single(dev, dma_addr, size, dir); | 360 | unmap_single(dev, buf, size, dir); |
390 | } | 361 | } |
391 | EXPORT_SYMBOL(__dma_unmap_page); | 362 | EXPORT_SYMBOL(__dma_unmap_page); |
392 | 363 | ||
@@ -461,7 +432,8 @@ static int dmabounce_init_pool(struct dmabounce_pool *pool, struct device *dev, | |||
461 | } | 432 | } |
462 | 433 | ||
463 | int dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size, | 434 | int dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size, |
464 | unsigned long large_buffer_size) | 435 | unsigned long large_buffer_size, |
436 | int (*needs_bounce_fn)(struct device *, dma_addr_t, size_t)) | ||
465 | { | 437 | { |
466 | struct dmabounce_device_info *device_info; | 438 | struct dmabounce_device_info *device_info; |
467 | int ret; | 439 | int ret; |
@@ -497,6 +469,7 @@ int dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size, | |||
497 | device_info->dev = dev; | 469 | device_info->dev = dev; |
498 | INIT_LIST_HEAD(&device_info->safe_buffers); | 470 | INIT_LIST_HEAD(&device_info->safe_buffers); |
499 | rwlock_init(&device_info->lock); | 471 | rwlock_init(&device_info->lock); |
472 | device_info->needs_bounce = needs_bounce_fn; | ||
500 | 473 | ||
501 | #ifdef STATS | 474 | #ifdef STATS |
502 | device_info->total_allocs = 0; | 475 | device_info->total_allocs = 0; |
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c index 4ddd0a6ac7ff..7bdd91766d65 100644 --- a/arch/arm/common/gic.c +++ b/arch/arm/common/gic.c | |||
@@ -179,22 +179,21 @@ static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, | |||
179 | { | 179 | { |
180 | void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3); | 180 | void __iomem *reg = gic_dist_base(d) + GIC_DIST_TARGET + (gic_irq(d) & ~3); |
181 | unsigned int shift = (d->irq % 4) * 8; | 181 | unsigned int shift = (d->irq % 4) * 8; |
182 | unsigned int cpu = cpumask_first(mask_val); | 182 | unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask); |
183 | u32 val, mask, bit; | 183 | u32 val, mask, bit; |
184 | 184 | ||
185 | if (cpu >= 8) | 185 | if (cpu >= 8 || cpu >= nr_cpu_ids) |
186 | return -EINVAL; | 186 | return -EINVAL; |
187 | 187 | ||
188 | mask = 0xff << shift; | 188 | mask = 0xff << shift; |
189 | bit = 1 << (cpu + shift); | 189 | bit = 1 << (cpu + shift); |
190 | 190 | ||
191 | spin_lock(&irq_controller_lock); | 191 | spin_lock(&irq_controller_lock); |
192 | d->node = cpu; | ||
193 | val = readl_relaxed(reg) & ~mask; | 192 | val = readl_relaxed(reg) & ~mask; |
194 | writel_relaxed(val | bit, reg); | 193 | writel_relaxed(val | bit, reg); |
195 | spin_unlock(&irq_controller_lock); | 194 | spin_unlock(&irq_controller_lock); |
196 | 195 | ||
197 | return 0; | 196 | return IRQ_SET_MASK_OK; |
198 | } | 197 | } |
199 | #endif | 198 | #endif |
200 | 199 | ||
diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c index 7a21927c52e1..14ad62e16dd1 100644 --- a/arch/arm/common/it8152.c +++ b/arch/arm/common/it8152.c | |||
@@ -243,6 +243,12 @@ static struct resource it8152_mem = { | |||
243 | * ITE8152 chip can address up to 64MByte, so all the devices | 243 | * ITE8152 chip can address up to 64MByte, so all the devices |
244 | * connected to ITE8152 (PCI and USB) should have limited DMA window | 244 | * connected to ITE8152 (PCI and USB) should have limited DMA window |
245 | */ | 245 | */ |
246 | static int it8152_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) | ||
247 | { | ||
248 | dev_dbg(dev, "%s: dma_addr %08x, size %08x\n", | ||
249 | __func__, dma_addr, size); | ||
250 | return (dma_addr + size - PHYS_OFFSET) >= SZ_64M; | ||
251 | } | ||
246 | 252 | ||
247 | /* | 253 | /* |
248 | * Setup DMA mask to 64MB on devices connected to ITE8152. Ignore all | 254 | * Setup DMA mask to 64MB on devices connected to ITE8152. Ignore all |
@@ -254,7 +260,7 @@ static int it8152_pci_platform_notify(struct device *dev) | |||
254 | if (dev->dma_mask) | 260 | if (dev->dma_mask) |
255 | *dev->dma_mask = (SZ_64M - 1) | PHYS_OFFSET; | 261 | *dev->dma_mask = (SZ_64M - 1) | PHYS_OFFSET; |
256 | dev->coherent_dma_mask = (SZ_64M - 1) | PHYS_OFFSET; | 262 | dev->coherent_dma_mask = (SZ_64M - 1) | PHYS_OFFSET; |
257 | dmabounce_register_dev(dev, 2048, 4096); | 263 | dmabounce_register_dev(dev, 2048, 4096, it8152_needs_bounce); |
258 | } | 264 | } |
259 | return 0; | 265 | return 0; |
260 | } | 266 | } |
@@ -267,14 +273,6 @@ static int it8152_pci_platform_notify_remove(struct device *dev) | |||
267 | return 0; | 273 | return 0; |
268 | } | 274 | } |
269 | 275 | ||
270 | int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) | ||
271 | { | ||
272 | dev_dbg(dev, "%s: dma_addr %08x, size %08x\n", | ||
273 | __func__, dma_addr, size); | ||
274 | return (dev->bus == &pci_bus_type) && | ||
275 | ((dma_addr + size - PHYS_OFFSET) >= SZ_64M); | ||
276 | } | ||
277 | |||
278 | int dma_set_coherent_mask(struct device *dev, u64 mask) | 276 | int dma_set_coherent_mask(struct device *dev, u64 mask) |
279 | { | 277 | { |
280 | if (mask >= PHYS_OFFSET + SZ_64M - 1) | 278 | if (mask >= PHYS_OFFSET + SZ_64M - 1) |
diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c index 9c49a46a2b7a..0569de6acfba 100644 --- a/arch/arm/common/sa1111.c +++ b/arch/arm/common/sa1111.c | |||
@@ -579,7 +579,36 @@ sa1111_configure_smc(struct sa1111 *sachip, int sdram, unsigned int drac, | |||
579 | 579 | ||
580 | sachip->dev->coherent_dma_mask &= sa1111_dma_mask[drac >> 2]; | 580 | sachip->dev->coherent_dma_mask &= sa1111_dma_mask[drac >> 2]; |
581 | } | 581 | } |
582 | #endif | ||
582 | 583 | ||
584 | #ifdef CONFIG_DMABOUNCE | ||
585 | /* | ||
586 | * According to the "Intel StrongARM SA-1111 Microprocessor Companion | ||
587 | * Chip Specification Update" (June 2000), erratum #7, there is a | ||
588 | * significant bug in the SA1111 SDRAM shared memory controller. If | ||
589 | * an access to a region of memory above 1MB relative to the bank base, | ||
590 | * it is important that address bit 10 _NOT_ be asserted. Depending | ||
591 | * on the configuration of the RAM, bit 10 may correspond to one | ||
592 | * of several different (processor-relative) address bits. | ||
593 | * | ||
594 | * This routine only identifies whether or not a given DMA address | ||
595 | * is susceptible to the bug. | ||
596 | * | ||
597 | * This should only get called for sa1111_device types due to the | ||
598 | * way we configure our device dma_masks. | ||
599 | */ | ||
600 | static int sa1111_needs_bounce(struct device *dev, dma_addr_t addr, size_t size) | ||
601 | { | ||
602 | /* | ||
603 | * Section 4.6 of the "Intel StrongARM SA-1111 Development Module | ||
604 | * User's Guide" mentions that jumpers R51 and R52 control the | ||
605 | * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or | ||
606 | * SDRAM bank 1 on Neponset). The default configuration selects | ||
607 | * Assabet, so any address in bank 1 is necessarily invalid. | ||
608 | */ | ||
609 | return (machine_is_assabet() || machine_is_pfs168()) && | ||
610 | (addr >= 0xc8000000 || (addr + size) >= 0xc8000000); | ||
611 | } | ||
583 | #endif | 612 | #endif |
584 | 613 | ||
585 | static void sa1111_dev_release(struct device *_dev) | 614 | static void sa1111_dev_release(struct device *_dev) |
@@ -644,7 +673,8 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent, | |||
644 | dev->dev.dma_mask = &dev->dma_mask; | 673 | dev->dev.dma_mask = &dev->dma_mask; |
645 | 674 | ||
646 | if (dev->dma_mask != 0xffffffffUL) { | 675 | if (dev->dma_mask != 0xffffffffUL) { |
647 | ret = dmabounce_register_dev(&dev->dev, 1024, 4096); | 676 | ret = dmabounce_register_dev(&dev->dev, 1024, 4096, |
677 | sa1111_needs_bounce); | ||
648 | if (ret) { | 678 | if (ret) { |
649 | dev_err(&dev->dev, "SA1111: Failed to register" | 679 | dev_err(&dev->dev, "SA1111: Failed to register" |
650 | " with dmabounce\n"); | 680 | " with dmabounce\n"); |
@@ -818,34 +848,6 @@ static void __sa1111_remove(struct sa1111 *sachip) | |||
818 | kfree(sachip); | 848 | kfree(sachip); |
819 | } | 849 | } |
820 | 850 | ||
821 | /* | ||
822 | * According to the "Intel StrongARM SA-1111 Microprocessor Companion | ||
823 | * Chip Specification Update" (June 2000), erratum #7, there is a | ||
824 | * significant bug in the SA1111 SDRAM shared memory controller. If | ||
825 | * an access to a region of memory above 1MB relative to the bank base, | ||
826 | * it is important that address bit 10 _NOT_ be asserted. Depending | ||
827 | * on the configuration of the RAM, bit 10 may correspond to one | ||
828 | * of several different (processor-relative) address bits. | ||
829 | * | ||
830 | * This routine only identifies whether or not a given DMA address | ||
831 | * is susceptible to the bug. | ||
832 | * | ||
833 | * This should only get called for sa1111_device types due to the | ||
834 | * way we configure our device dma_masks. | ||
835 | */ | ||
836 | int dma_needs_bounce(struct device *dev, dma_addr_t addr, size_t size) | ||
837 | { | ||
838 | /* | ||
839 | * Section 4.6 of the "Intel StrongARM SA-1111 Development Module | ||
840 | * User's Guide" mentions that jumpers R51 and R52 control the | ||
841 | * target of SA-1111 DMA (either SDRAM bank 0 on Assabet, or | ||
842 | * SDRAM bank 1 on Neponset). The default configuration selects | ||
843 | * Assabet, so any address in bank 1 is necessarily invalid. | ||
844 | */ | ||
845 | return ((machine_is_assabet() || machine_is_pfs168()) && | ||
846 | (addr >= 0xc8000000 || (addr + size) >= 0xc8000000)); | ||
847 | } | ||
848 | |||
849 | struct sa1111_save_data { | 851 | struct sa1111_save_data { |
850 | unsigned int skcr; | 852 | unsigned int skcr; |
851 | unsigned int skpcr; | 853 | unsigned int skpcr; |
diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h index b4892a06442c..f4280593dfa3 100644 --- a/arch/arm/include/asm/bitops.h +++ b/arch/arm/include/asm/bitops.h | |||
@@ -26,8 +26,8 @@ | |||
26 | #include <linux/compiler.h> | 26 | #include <linux/compiler.h> |
27 | #include <asm/system.h> | 27 | #include <asm/system.h> |
28 | 28 | ||
29 | #define smp_mb__before_clear_bit() mb() | 29 | #define smp_mb__before_clear_bit() smp_mb() |
30 | #define smp_mb__after_clear_bit() mb() | 30 | #define smp_mb__after_clear_bit() smp_mb() |
31 | 31 | ||
32 | /* | 32 | /* |
33 | * These functions are the basis of our bit ops. | 33 | * These functions are the basis of our bit ops. |
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h index 4fff837363ed..7a21d0bf7134 100644 --- a/arch/arm/include/asm/dma-mapping.h +++ b/arch/arm/include/asm/dma-mapping.h | |||
@@ -115,39 +115,8 @@ static inline void __dma_page_dev_to_cpu(struct page *page, unsigned long off, | |||
115 | ___dma_page_dev_to_cpu(page, off, size, dir); | 115 | ___dma_page_dev_to_cpu(page, off, size, dir); |
116 | } | 116 | } |
117 | 117 | ||
118 | /* | 118 | extern int dma_supported(struct device *, u64); |
119 | * Return whether the given device DMA address mask can be supported | 119 | extern int dma_set_mask(struct device *, u64); |
120 | * properly. For example, if your device can only drive the low 24-bits | ||
121 | * during bus mastering, then you would pass 0x00ffffff as the mask | ||
122 | * to this function. | ||
123 | * | ||
124 | * FIXME: This should really be a platform specific issue - we should | ||
125 | * return false if GFP_DMA allocations may not satisfy the supplied 'mask'. | ||
126 | */ | ||
127 | static inline int dma_supported(struct device *dev, u64 mask) | ||
128 | { | ||
129 | if (mask < ISA_DMA_THRESHOLD) | ||
130 | return 0; | ||
131 | return 1; | ||
132 | } | ||
133 | |||
134 | static inline int dma_set_mask(struct device *dev, u64 dma_mask) | ||
135 | { | ||
136 | #ifdef CONFIG_DMABOUNCE | ||
137 | if (dev->archdata.dmabounce) { | ||
138 | if (dma_mask >= ISA_DMA_THRESHOLD) | ||
139 | return 0; | ||
140 | else | ||
141 | return -EIO; | ||
142 | } | ||
143 | #endif | ||
144 | if (!dev->dma_mask || !dma_supported(dev, dma_mask)) | ||
145 | return -EIO; | ||
146 | |||
147 | *dev->dma_mask = dma_mask; | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | 120 | ||
152 | /* | 121 | /* |
153 | * DMA errors are defined by all-bits-set in the DMA address. | 122 | * DMA errors are defined by all-bits-set in the DMA address. |
@@ -256,14 +225,14 @@ int dma_mmap_writecombine(struct device *, struct vm_area_struct *, | |||
256 | * @dev: valid struct device pointer | 225 | * @dev: valid struct device pointer |
257 | * @small_buf_size: size of buffers to use with small buffer pool | 226 | * @small_buf_size: size of buffers to use with small buffer pool |
258 | * @large_buf_size: size of buffers to use with large buffer pool (can be 0) | 227 | * @large_buf_size: size of buffers to use with large buffer pool (can be 0) |
228 | * @needs_bounce_fn: called to determine whether buffer needs bouncing | ||
259 | * | 229 | * |
260 | * This function should be called by low-level platform code to register | 230 | * This function should be called by low-level platform code to register |
261 | * a device as requireing DMA buffer bouncing. The function will allocate | 231 | * a device as requireing DMA buffer bouncing. The function will allocate |
262 | * appropriate DMA pools for the device. | 232 | * appropriate DMA pools for the device. |
263 | * | ||
264 | */ | 233 | */ |
265 | extern int dmabounce_register_dev(struct device *, unsigned long, | 234 | extern int dmabounce_register_dev(struct device *, unsigned long, |
266 | unsigned long); | 235 | unsigned long, int (*)(struct device *, dma_addr_t, size_t)); |
267 | 236 | ||
268 | /** | 237 | /** |
269 | * dmabounce_unregister_dev | 238 | * dmabounce_unregister_dev |
@@ -277,31 +246,9 @@ extern int dmabounce_register_dev(struct device *, unsigned long, | |||
277 | */ | 246 | */ |
278 | extern void dmabounce_unregister_dev(struct device *); | 247 | extern void dmabounce_unregister_dev(struct device *); |
279 | 248 | ||
280 | /** | ||
281 | * dma_needs_bounce | ||
282 | * | ||
283 | * @dev: valid struct device pointer | ||
284 | * @dma_handle: dma_handle of unbounced buffer | ||
285 | * @size: size of region being mapped | ||
286 | * | ||
287 | * Platforms that utilize the dmabounce mechanism must implement | ||
288 | * this function. | ||
289 | * | ||
290 | * The dmabounce routines call this function whenever a dma-mapping | ||
291 | * is requested to determine whether a given buffer needs to be bounced | ||
292 | * or not. The function must return 0 if the buffer is OK for | ||
293 | * DMA access and 1 if the buffer needs to be bounced. | ||
294 | * | ||
295 | */ | ||
296 | extern int dma_needs_bounce(struct device*, dma_addr_t, size_t); | ||
297 | |||
298 | /* | 249 | /* |
299 | * The DMA API, implemented by dmabounce.c. See below for descriptions. | 250 | * The DMA API, implemented by dmabounce.c. See below for descriptions. |
300 | */ | 251 | */ |
301 | extern dma_addr_t __dma_map_single(struct device *, void *, size_t, | ||
302 | enum dma_data_direction); | ||
303 | extern void __dma_unmap_single(struct device *, dma_addr_t, size_t, | ||
304 | enum dma_data_direction); | ||
305 | extern dma_addr_t __dma_map_page(struct device *, struct page *, | 252 | extern dma_addr_t __dma_map_page(struct device *, struct page *, |
306 | unsigned long, size_t, enum dma_data_direction); | 253 | unsigned long, size_t, enum dma_data_direction); |
307 | extern void __dma_unmap_page(struct device *, dma_addr_t, size_t, | 254 | extern void __dma_unmap_page(struct device *, dma_addr_t, size_t, |
@@ -328,13 +275,6 @@ static inline int dmabounce_sync_for_device(struct device *d, dma_addr_t addr, | |||
328 | } | 275 | } |
329 | 276 | ||
330 | 277 | ||
331 | static inline dma_addr_t __dma_map_single(struct device *dev, void *cpu_addr, | ||
332 | size_t size, enum dma_data_direction dir) | ||
333 | { | ||
334 | __dma_single_cpu_to_dev(cpu_addr, size, dir); | ||
335 | return virt_to_dma(dev, cpu_addr); | ||
336 | } | ||
337 | |||
338 | static inline dma_addr_t __dma_map_page(struct device *dev, struct page *page, | 278 | static inline dma_addr_t __dma_map_page(struct device *dev, struct page *page, |
339 | unsigned long offset, size_t size, enum dma_data_direction dir) | 279 | unsigned long offset, size_t size, enum dma_data_direction dir) |
340 | { | 280 | { |
@@ -342,12 +282,6 @@ static inline dma_addr_t __dma_map_page(struct device *dev, struct page *page, | |||
342 | return pfn_to_dma(dev, page_to_pfn(page)) + offset; | 282 | return pfn_to_dma(dev, page_to_pfn(page)) + offset; |
343 | } | 283 | } |
344 | 284 | ||
345 | static inline void __dma_unmap_single(struct device *dev, dma_addr_t handle, | ||
346 | size_t size, enum dma_data_direction dir) | ||
347 | { | ||
348 | __dma_single_dev_to_cpu(dma_to_virt(dev, handle), size, dir); | ||
349 | } | ||
350 | |||
351 | static inline void __dma_unmap_page(struct device *dev, dma_addr_t handle, | 285 | static inline void __dma_unmap_page(struct device *dev, dma_addr_t handle, |
352 | size_t size, enum dma_data_direction dir) | 286 | size_t size, enum dma_data_direction dir) |
353 | { | 287 | { |
@@ -373,14 +307,18 @@ static inline void __dma_unmap_page(struct device *dev, dma_addr_t handle, | |||
373 | static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, | 307 | static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, |
374 | size_t size, enum dma_data_direction dir) | 308 | size_t size, enum dma_data_direction dir) |
375 | { | 309 | { |
310 | unsigned long offset; | ||
311 | struct page *page; | ||
376 | dma_addr_t addr; | 312 | dma_addr_t addr; |
377 | 313 | ||
314 | BUG_ON(!virt_addr_valid(cpu_addr)); | ||
315 | BUG_ON(!virt_addr_valid(cpu_addr + size - 1)); | ||
378 | BUG_ON(!valid_dma_direction(dir)); | 316 | BUG_ON(!valid_dma_direction(dir)); |
379 | 317 | ||
380 | addr = __dma_map_single(dev, cpu_addr, size, dir); | 318 | page = virt_to_page(cpu_addr); |
381 | debug_dma_map_page(dev, virt_to_page(cpu_addr), | 319 | offset = (unsigned long)cpu_addr & ~PAGE_MASK; |
382 | (unsigned long)cpu_addr & ~PAGE_MASK, size, | 320 | addr = __dma_map_page(dev, page, offset, size, dir); |
383 | dir, addr, true); | 321 | debug_dma_map_page(dev, page, offset, size, dir, addr, true); |
384 | 322 | ||
385 | return addr; | 323 | return addr; |
386 | } | 324 | } |
@@ -430,7 +368,7 @@ static inline void dma_unmap_single(struct device *dev, dma_addr_t handle, | |||
430 | size_t size, enum dma_data_direction dir) | 368 | size_t size, enum dma_data_direction dir) |
431 | { | 369 | { |
432 | debug_dma_unmap_page(dev, handle, size, dir, true); | 370 | debug_dma_unmap_page(dev, handle, size, dir, true); |
433 | __dma_unmap_single(dev, handle, size, dir); | 371 | __dma_unmap_page(dev, handle, size, dir); |
434 | } | 372 | } |
435 | 373 | ||
436 | /** | 374 | /** |
diff --git a/arch/arm/include/asm/entry-macro-multi.S b/arch/arm/include/asm/entry-macro-multi.S index 2da8547de6d6..2f1e2098dfe7 100644 --- a/arch/arm/include/asm/entry-macro-multi.S +++ b/arch/arm/include/asm/entry-macro-multi.S | |||
@@ -4,8 +4,8 @@ | |||
4 | * Interrupt handling. Preserves r7, r8, r9 | 4 | * Interrupt handling. Preserves r7, r8, r9 |
5 | */ | 5 | */ |
6 | .macro arch_irq_handler_default | 6 | .macro arch_irq_handler_default |
7 | get_irqnr_preamble r5, lr | 7 | get_irqnr_preamble r6, lr |
8 | 1: get_irqnr_and_base r0, r6, r5, lr | 8 | 1: get_irqnr_and_base r0, r2, r6, lr |
9 | movne r1, sp | 9 | movne r1, sp |
10 | @ | 10 | @ |
11 | @ routine called with r0 = irq number, r1 = struct pt_regs * | 11 | @ routine called with r0 = irq number, r1 = struct pt_regs * |
@@ -17,17 +17,17 @@ | |||
17 | /* | 17 | /* |
18 | * XXX | 18 | * XXX |
19 | * | 19 | * |
20 | * this macro assumes that irqstat (r6) and base (r5) are | 20 | * this macro assumes that irqstat (r2) and base (r6) are |
21 | * preserved from get_irqnr_and_base above | 21 | * preserved from get_irqnr_and_base above |
22 | */ | 22 | */ |
23 | ALT_SMP(test_for_ipi r0, r6, r5, lr) | 23 | ALT_SMP(test_for_ipi r0, r2, r6, lr) |
24 | ALT_UP_B(9997f) | 24 | ALT_UP_B(9997f) |
25 | movne r1, sp | 25 | movne r1, sp |
26 | adrne lr, BSYM(1b) | 26 | adrne lr, BSYM(1b) |
27 | bne do_IPI | 27 | bne do_IPI |
28 | 28 | ||
29 | #ifdef CONFIG_LOCAL_TIMERS | 29 | #ifdef CONFIG_LOCAL_TIMERS |
30 | test_for_ltirq r0, r6, r5, lr | 30 | test_for_ltirq r0, r2, r6, lr |
31 | movne r0, sp | 31 | movne r0, sp |
32 | adrne lr, BSYM(1b) | 32 | adrne lr, BSYM(1b) |
33 | bne do_local_timer | 33 | bne do_local_timer |
@@ -40,7 +40,7 @@ | |||
40 | .align 5 | 40 | .align 5 |
41 | .global \symbol_name | 41 | .global \symbol_name |
42 | \symbol_name: | 42 | \symbol_name: |
43 | mov r4, lr | 43 | mov r8, lr |
44 | arch_irq_handler_default | 44 | arch_irq_handler_default |
45 | mov pc, r4 | 45 | mov pc, r8 |
46 | .endm | 46 | .endm |
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index af44a8fb3480..b8de516e600e 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h | |||
@@ -204,18 +204,6 @@ static inline unsigned long __phys_to_virt(unsigned long x) | |||
204 | #endif | 204 | #endif |
205 | 205 | ||
206 | /* | 206 | /* |
207 | * The DMA mask corresponding to the maximum bus address allocatable | ||
208 | * using GFP_DMA. The default here places no restriction on DMA | ||
209 | * allocations. This must be the smallest DMA mask in the system, | ||
210 | * so a successful GFP_DMA allocation will always satisfy this. | ||
211 | */ | ||
212 | #ifndef ARM_DMA_ZONE_SIZE | ||
213 | #define ISA_DMA_THRESHOLD (0xffffffffULL) | ||
214 | #else | ||
215 | #define ISA_DMA_THRESHOLD (PHYS_OFFSET + ARM_DMA_ZONE_SIZE - 1) | ||
216 | #endif | ||
217 | |||
218 | /* | ||
219 | * PFNs are used to describe any physical page; this means | 207 | * PFNs are used to describe any physical page; this means |
220 | * PFN 0 == physical address 0. | 208 | * PFN 0 == physical address 0. |
221 | * | 209 | * |
diff --git a/arch/arm/include/asm/pmu.h b/arch/arm/include/asm/pmu.h index 7544ce6b481a..67c70a31a1be 100644 --- a/arch/arm/include/asm/pmu.h +++ b/arch/arm/include/asm/pmu.h | |||
@@ -52,7 +52,7 @@ reserve_pmu(enum arm_pmu_type device); | |||
52 | * a cookie. | 52 | * a cookie. |
53 | */ | 53 | */ |
54 | extern int | 54 | extern int |
55 | release_pmu(struct platform_device *pdev); | 55 | release_pmu(enum arm_pmu_type type); |
56 | 56 | ||
57 | /** | 57 | /** |
58 | * init_pmu() - Initialise the PMU. | 58 | * init_pmu() - Initialise the PMU. |
diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h index 8ec535e11fd7..633d1cb84d87 100644 --- a/arch/arm/include/asm/proc-fns.h +++ b/arch/arm/include/asm/proc-fns.h | |||
@@ -82,13 +82,13 @@ extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm); | |||
82 | extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext); | 82 | extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext); |
83 | extern void cpu_reset(unsigned long addr) __attribute__((noreturn)); | 83 | extern void cpu_reset(unsigned long addr) __attribute__((noreturn)); |
84 | #else | 84 | #else |
85 | #define cpu_proc_init() processor._proc_init() | 85 | #define cpu_proc_init processor._proc_init |
86 | #define cpu_proc_fin() processor._proc_fin() | 86 | #define cpu_proc_fin processor._proc_fin |
87 | #define cpu_reset(addr) processor.reset(addr) | 87 | #define cpu_reset processor.reset |
88 | #define cpu_do_idle() processor._do_idle() | 88 | #define cpu_do_idle processor._do_idle |
89 | #define cpu_dcache_clean_area(addr,sz) processor.dcache_clean_area(addr,sz) | 89 | #define cpu_dcache_clean_area processor.dcache_clean_area |
90 | #define cpu_set_pte_ext(ptep,pte,ext) processor.set_pte_ext(ptep,pte,ext) | 90 | #define cpu_set_pte_ext processor.set_pte_ext |
91 | #define cpu_do_switch_mm(pgd,mm) processor.switch_mm(pgd,mm) | 91 | #define cpu_do_switch_mm processor.switch_mm |
92 | #endif | 92 | #endif |
93 | 93 | ||
94 | extern void cpu_resume(void); | 94 | extern void cpu_resume(void); |
diff --git a/arch/arm/include/asm/scatterlist.h b/arch/arm/include/asm/scatterlist.h index 2f87870d9347..cefdb8f898a1 100644 --- a/arch/arm/include/asm/scatterlist.h +++ b/arch/arm/include/asm/scatterlist.h | |||
@@ -1,6 +1,10 @@ | |||
1 | #ifndef _ASMARM_SCATTERLIST_H | 1 | #ifndef _ASMARM_SCATTERLIST_H |
2 | #define _ASMARM_SCATTERLIST_H | 2 | #define _ASMARM_SCATTERLIST_H |
3 | 3 | ||
4 | #ifdef CONFIG_ARM_HAS_SG_CHAIN | ||
5 | #define ARCH_HAS_SG_CHAIN | ||
6 | #endif | ||
7 | |||
4 | #include <asm/memory.h> | 8 | #include <asm/memory.h> |
5 | #include <asm/types.h> | 9 | #include <asm/types.h> |
6 | #include <asm-generic/scatterlist.h> | 10 | #include <asm-generic/scatterlist.h> |
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h index ee2ad8ae07af..915696dd9c7c 100644 --- a/arch/arm/include/asm/setup.h +++ b/arch/arm/include/asm/setup.h | |||
@@ -187,12 +187,16 @@ struct tagtable { | |||
187 | 187 | ||
188 | #define __tag __used __attribute__((__section__(".taglist.init"))) | 188 | #define __tag __used __attribute__((__section__(".taglist.init"))) |
189 | #define __tagtable(tag, fn) \ | 189 | #define __tagtable(tag, fn) \ |
190 | static struct tagtable __tagtable_##fn __tag = { tag, fn } | 190 | static const struct tagtable __tagtable_##fn __tag = { tag, fn } |
191 | 191 | ||
192 | /* | 192 | /* |
193 | * Memory map description | 193 | * Memory map description |
194 | */ | 194 | */ |
195 | #define NR_BANKS 8 | 195 | #ifdef CONFIG_ARCH_EP93XX |
196 | # define NR_BANKS 16 | ||
197 | #else | ||
198 | # define NR_BANKS 8 | ||
199 | #endif | ||
196 | 200 | ||
197 | struct membank { | 201 | struct membank { |
198 | phys_addr_t start; | 202 | phys_addr_t start; |
diff --git a/arch/arm/include/asm/suspend.h b/arch/arm/include/asm/suspend.h new file mode 100644 index 000000000000..b0e4e1a02318 --- /dev/null +++ b/arch/arm/include/asm/suspend.h | |||
@@ -0,0 +1,22 @@ | |||
1 | #ifndef __ASM_ARM_SUSPEND_H | ||
2 | #define __ASM_ARM_SUSPEND_H | ||
3 | |||
4 | #include <asm/memory.h> | ||
5 | #include <asm/tlbflush.h> | ||
6 | |||
7 | extern void cpu_resume(void); | ||
8 | |||
9 | /* | ||
10 | * Hide the first two arguments to __cpu_suspend - these are an implementation | ||
11 | * detail which platform code shouldn't have to know about. | ||
12 | */ | ||
13 | static inline int cpu_suspend(unsigned long arg, int (*fn)(unsigned long)) | ||
14 | { | ||
15 | extern int __cpu_suspend(int, long, unsigned long, | ||
16 | int (*)(unsigned long)); | ||
17 | int ret = __cpu_suspend(0, PHYS_OFFSET - PAGE_OFFSET, arg, fn); | ||
18 | flush_tlb_all(); | ||
19 | return ret; | ||
20 | } | ||
21 | |||
22 | #endif | ||
diff --git a/arch/arm/include/asm/tcm.h b/arch/arm/include/asm/tcm.h index 5929ef5d927a..8578d726ad78 100644 --- a/arch/arm/include/asm/tcm.h +++ b/arch/arm/include/asm/tcm.h | |||
@@ -27,5 +27,7 @@ | |||
27 | 27 | ||
28 | void *tcm_alloc(size_t len); | 28 | void *tcm_alloc(size_t len); |
29 | void tcm_free(void *addr, size_t len); | 29 | void tcm_free(void *addr, size_t len); |
30 | bool tcm_dtcm_present(void); | ||
31 | bool tcm_itcm_present(void); | ||
30 | 32 | ||
31 | #endif | 33 | #endif |
diff --git a/arch/arm/include/asm/tlbflush.h b/arch/arm/include/asm/tlbflush.h index d2005de383b8..8077145698ff 100644 --- a/arch/arm/include/asm/tlbflush.h +++ b/arch/arm/include/asm/tlbflush.h | |||
@@ -34,16 +34,12 @@ | |||
34 | #define TLB_V6_D_ASID (1 << 17) | 34 | #define TLB_V6_D_ASID (1 << 17) |
35 | #define TLB_V6_I_ASID (1 << 18) | 35 | #define TLB_V6_I_ASID (1 << 18) |
36 | 36 | ||
37 | #define TLB_BTB (1 << 28) | ||
38 | |||
39 | /* Unified Inner Shareable TLB operations (ARMv7 MP extensions) */ | 37 | /* Unified Inner Shareable TLB operations (ARMv7 MP extensions) */ |
40 | #define TLB_V7_UIS_PAGE (1 << 19) | 38 | #define TLB_V7_UIS_PAGE (1 << 19) |
41 | #define TLB_V7_UIS_FULL (1 << 20) | 39 | #define TLB_V7_UIS_FULL (1 << 20) |
42 | #define TLB_V7_UIS_ASID (1 << 21) | 40 | #define TLB_V7_UIS_ASID (1 << 21) |
43 | 41 | ||
44 | /* Inner Shareable BTB operation (ARMv7 MP extensions) */ | 42 | #define TLB_BARRIER (1 << 28) |
45 | #define TLB_V7_IS_BTB (1 << 22) | ||
46 | |||
47 | #define TLB_L2CLEAN_FR (1 << 29) /* Feroceon */ | 43 | #define TLB_L2CLEAN_FR (1 << 29) /* Feroceon */ |
48 | #define TLB_DCLEAN (1 << 30) | 44 | #define TLB_DCLEAN (1 << 30) |
49 | #define TLB_WB (1 << 31) | 45 | #define TLB_WB (1 << 31) |
@@ -58,7 +54,7 @@ | |||
58 | * v4wb - ARMv4 with write buffer without I TLB flush entry instruction | 54 | * v4wb - ARMv4 with write buffer without I TLB flush entry instruction |
59 | * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction | 55 | * v4wbi - ARMv4 with write buffer with I TLB flush entry instruction |
60 | * fr - Feroceon (v4wbi with non-outer-cacheable page table walks) | 56 | * fr - Feroceon (v4wbi with non-outer-cacheable page table walks) |
61 | * fa - Faraday (v4 with write buffer with UTLB and branch target buffer (BTB)) | 57 | * fa - Faraday (v4 with write buffer with UTLB) |
62 | * v6wbi - ARMv6 with write buffer with I TLB flush entry instruction | 58 | * v6wbi - ARMv6 with write buffer with I TLB flush entry instruction |
63 | * v7wbi - identical to v6wbi | 59 | * v7wbi - identical to v6wbi |
64 | */ | 60 | */ |
@@ -99,7 +95,7 @@ | |||
99 | # define v4_always_flags (-1UL) | 95 | # define v4_always_flags (-1UL) |
100 | #endif | 96 | #endif |
101 | 97 | ||
102 | #define fa_tlb_flags (TLB_WB | TLB_BTB | TLB_DCLEAN | \ | 98 | #define fa_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \ |
103 | TLB_V4_U_FULL | TLB_V4_U_PAGE) | 99 | TLB_V4_U_FULL | TLB_V4_U_PAGE) |
104 | 100 | ||
105 | #ifdef CONFIG_CPU_TLB_FA | 101 | #ifdef CONFIG_CPU_TLB_FA |
@@ -166,7 +162,7 @@ | |||
166 | # define v4wb_always_flags (-1UL) | 162 | # define v4wb_always_flags (-1UL) |
167 | #endif | 163 | #endif |
168 | 164 | ||
169 | #define v6wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BTB | \ | 165 | #define v6wbi_tlb_flags (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \ |
170 | TLB_V6_I_FULL | TLB_V6_D_FULL | \ | 166 | TLB_V6_I_FULL | TLB_V6_D_FULL | \ |
171 | TLB_V6_I_PAGE | TLB_V6_D_PAGE | \ | 167 | TLB_V6_I_PAGE | TLB_V6_D_PAGE | \ |
172 | TLB_V6_I_ASID | TLB_V6_D_ASID) | 168 | TLB_V6_I_ASID | TLB_V6_D_ASID) |
@@ -184,9 +180,9 @@ | |||
184 | # define v6wbi_always_flags (-1UL) | 180 | # define v6wbi_always_flags (-1UL) |
185 | #endif | 181 | #endif |
186 | 182 | ||
187 | #define v7wbi_tlb_flags_smp (TLB_WB | TLB_DCLEAN | TLB_V7_IS_BTB | \ | 183 | #define v7wbi_tlb_flags_smp (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \ |
188 | TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | TLB_V7_UIS_ASID) | 184 | TLB_V7_UIS_FULL | TLB_V7_UIS_PAGE | TLB_V7_UIS_ASID) |
189 | #define v7wbi_tlb_flags_up (TLB_WB | TLB_DCLEAN | TLB_BTB | \ | 185 | #define v7wbi_tlb_flags_up (TLB_WB | TLB_DCLEAN | TLB_BARRIER | \ |
190 | TLB_V6_U_FULL | TLB_V6_U_PAGE | TLB_V6_U_ASID) | 186 | TLB_V6_U_FULL | TLB_V6_U_PAGE | TLB_V6_U_ASID) |
191 | 187 | ||
192 | #ifdef CONFIG_CPU_TLB_V7 | 188 | #ifdef CONFIG_CPU_TLB_V7 |
@@ -341,15 +337,7 @@ static inline void local_flush_tlb_all(void) | |||
341 | if (tlb_flag(TLB_V7_UIS_FULL)) | 337 | if (tlb_flag(TLB_V7_UIS_FULL)) |
342 | asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc"); | 338 | asm("mcr p15, 0, %0, c8, c3, 0" : : "r" (zero) : "cc"); |
343 | 339 | ||
344 | if (tlb_flag(TLB_BTB)) { | 340 | if (tlb_flag(TLB_BARRIER)) { |
345 | /* flush the branch target cache */ | ||
346 | asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); | ||
347 | dsb(); | ||
348 | isb(); | ||
349 | } | ||
350 | if (tlb_flag(TLB_V7_IS_BTB)) { | ||
351 | /* flush the branch target cache */ | ||
352 | asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc"); | ||
353 | dsb(); | 341 | dsb(); |
354 | isb(); | 342 | isb(); |
355 | } | 343 | } |
@@ -389,17 +377,8 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm) | |||
389 | asm("mcr p15, 0, %0, c8, c3, 2" : : "r" (asid) : "cc"); | 377 | asm("mcr p15, 0, %0, c8, c3, 2" : : "r" (asid) : "cc"); |
390 | #endif | 378 | #endif |
391 | 379 | ||
392 | if (tlb_flag(TLB_BTB)) { | 380 | if (tlb_flag(TLB_BARRIER)) |
393 | /* flush the branch target cache */ | ||
394 | asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); | ||
395 | dsb(); | ||
396 | } | ||
397 | if (tlb_flag(TLB_V7_IS_BTB)) { | ||
398 | /* flush the branch target cache */ | ||
399 | asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc"); | ||
400 | dsb(); | 381 | dsb(); |
401 | isb(); | ||
402 | } | ||
403 | } | 382 | } |
404 | 383 | ||
405 | static inline void | 384 | static inline void |
@@ -439,17 +418,8 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) | |||
439 | asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (uaddr) : "cc"); | 418 | asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (uaddr) : "cc"); |
440 | #endif | 419 | #endif |
441 | 420 | ||
442 | if (tlb_flag(TLB_BTB)) { | 421 | if (tlb_flag(TLB_BARRIER)) |
443 | /* flush the branch target cache */ | ||
444 | asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); | ||
445 | dsb(); | ||
446 | } | ||
447 | if (tlb_flag(TLB_V7_IS_BTB)) { | ||
448 | /* flush the branch target cache */ | ||
449 | asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc"); | ||
450 | dsb(); | 422 | dsb(); |
451 | isb(); | ||
452 | } | ||
453 | } | 423 | } |
454 | 424 | ||
455 | static inline void local_flush_tlb_kernel_page(unsigned long kaddr) | 425 | static inline void local_flush_tlb_kernel_page(unsigned long kaddr) |
@@ -482,15 +452,7 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr) | |||
482 | if (tlb_flag(TLB_V7_UIS_PAGE)) | 452 | if (tlb_flag(TLB_V7_UIS_PAGE)) |
483 | asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (kaddr) : "cc"); | 453 | asm("mcr p15, 0, %0, c8, c3, 1" : : "r" (kaddr) : "cc"); |
484 | 454 | ||
485 | if (tlb_flag(TLB_BTB)) { | 455 | if (tlb_flag(TLB_BARRIER)) { |
486 | /* flush the branch target cache */ | ||
487 | asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc"); | ||
488 | dsb(); | ||
489 | isb(); | ||
490 | } | ||
491 | if (tlb_flag(TLB_V7_IS_BTB)) { | ||
492 | /* flush the branch target cache */ | ||
493 | asm("mcr p15, 0, %0, c7, c1, 6" : : "r" (zero) : "cc"); | ||
494 | dsb(); | 456 | dsb(); |
495 | isb(); | 457 | isb(); |
496 | } | 458 | } |
diff --git a/arch/arm/include/asm/traps.h b/arch/arm/include/asm/traps.h index f90756dc16dc..5b29a6673625 100644 --- a/arch/arm/include/asm/traps.h +++ b/arch/arm/include/asm/traps.h | |||
@@ -3,6 +3,9 @@ | |||
3 | 3 | ||
4 | #include <linux/list.h> | 4 | #include <linux/list.h> |
5 | 5 | ||
6 | struct pt_regs; | ||
7 | struct task_struct; | ||
8 | |||
6 | struct undef_hook { | 9 | struct undef_hook { |
7 | struct list_head node; | 10 | struct list_head node; |
8 | u32 instr_mask; | 11 | u32 instr_mask; |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 90c62cd51ca9..fa02a22a4c4b 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -29,21 +29,53 @@ | |||
29 | #include <asm/entry-macro-multi.S> | 29 | #include <asm/entry-macro-multi.S> |
30 | 30 | ||
31 | /* | 31 | /* |
32 | * Interrupt handling. Preserves r7, r8, r9 | 32 | * Interrupt handling. |
33 | */ | 33 | */ |
34 | .macro irq_handler | 34 | .macro irq_handler |
35 | #ifdef CONFIG_MULTI_IRQ_HANDLER | 35 | #ifdef CONFIG_MULTI_IRQ_HANDLER |
36 | ldr r5, =handle_arch_irq | 36 | ldr r1, =handle_arch_irq |
37 | mov r0, sp | 37 | mov r0, sp |
38 | ldr r5, [r5] | 38 | ldr r1, [r1] |
39 | adr lr, BSYM(9997f) | 39 | adr lr, BSYM(9997f) |
40 | teq r5, #0 | 40 | teq r1, #0 |
41 | movne pc, r5 | 41 | movne pc, r1 |
42 | #endif | 42 | #endif |
43 | arch_irq_handler_default | 43 | arch_irq_handler_default |
44 | 9997: | 44 | 9997: |
45 | .endm | 45 | .endm |
46 | 46 | ||
47 | .macro pabt_helper | ||
48 | @ PABORT handler takes pt_regs in r2, fault address in r4 and psr in r5 | ||
49 | #ifdef MULTI_PABORT | ||
50 | ldr ip, .LCprocfns | ||
51 | mov lr, pc | ||
52 | ldr pc, [ip, #PROCESSOR_PABT_FUNC] | ||
53 | #else | ||
54 | bl CPU_PABORT_HANDLER | ||
55 | #endif | ||
56 | .endm | ||
57 | |||
58 | .macro dabt_helper | ||
59 | |||
60 | @ | ||
61 | @ Call the processor-specific abort handler: | ||
62 | @ | ||
63 | @ r2 - pt_regs | ||
64 | @ r4 - aborted context pc | ||
65 | @ r5 - aborted context psr | ||
66 | @ | ||
67 | @ The abort handler must return the aborted address in r0, and | ||
68 | @ the fault status register in r1. r9 must be preserved. | ||
69 | @ | ||
70 | #ifdef MULTI_DABORT | ||
71 | ldr ip, .LCprocfns | ||
72 | mov lr, pc | ||
73 | ldr pc, [ip, #PROCESSOR_DABT_FUNC] | ||
74 | #else | ||
75 | bl CPU_DABORT_HANDLER | ||
76 | #endif | ||
77 | .endm | ||
78 | |||
47 | #ifdef CONFIG_KPROBES | 79 | #ifdef CONFIG_KPROBES |
48 | .section .kprobes.text,"ax",%progbits | 80 | .section .kprobes.text,"ax",%progbits |
49 | #else | 81 | #else |
@@ -126,106 +158,74 @@ ENDPROC(__und_invalid) | |||
126 | SPFIX( subeq sp, sp, #4 ) | 158 | SPFIX( subeq sp, sp, #4 ) |
127 | stmia sp, {r1 - r12} | 159 | stmia sp, {r1 - r12} |
128 | 160 | ||
129 | ldmia r0, {r1 - r3} | 161 | ldmia r0, {r3 - r5} |
130 | add r5, sp, #S_SP - 4 @ here for interlock avoidance | 162 | add r7, sp, #S_SP - 4 @ here for interlock avoidance |
131 | mov r4, #-1 @ "" "" "" "" | 163 | mov r6, #-1 @ "" "" "" "" |
132 | add r0, sp, #(S_FRAME_SIZE + \stack_hole - 4) | 164 | add r2, sp, #(S_FRAME_SIZE + \stack_hole - 4) |
133 | SPFIX( addeq r0, r0, #4 ) | 165 | SPFIX( addeq r2, r2, #4 ) |
134 | str r1, [sp, #-4]! @ save the "real" r0 copied | 166 | str r3, [sp, #-4]! @ save the "real" r0 copied |
135 | @ from the exception stack | 167 | @ from the exception stack |
136 | 168 | ||
137 | mov r1, lr | 169 | mov r3, lr |
138 | 170 | ||
139 | @ | 171 | @ |
140 | @ We are now ready to fill in the remaining blanks on the stack: | 172 | @ We are now ready to fill in the remaining blanks on the stack: |
141 | @ | 173 | @ |
142 | @ r0 - sp_svc | 174 | @ r2 - sp_svc |
143 | @ r1 - lr_svc | 175 | @ r3 - lr_svc |
144 | @ r2 - lr_<exception>, already fixed up for correct return/restart | 176 | @ r4 - lr_<exception>, already fixed up for correct return/restart |
145 | @ r3 - spsr_<exception> | 177 | @ r5 - spsr_<exception> |
146 | @ r4 - orig_r0 (see pt_regs definition in ptrace.h) | 178 | @ r6 - orig_r0 (see pt_regs definition in ptrace.h) |
147 | @ | 179 | @ |
148 | stmia r5, {r0 - r4} | 180 | stmia r7, {r2 - r6} |
181 | |||
182 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
183 | bl trace_hardirqs_off | ||
184 | #endif | ||
149 | .endm | 185 | .endm |
150 | 186 | ||
151 | .align 5 | 187 | .align 5 |
152 | __dabt_svc: | 188 | __dabt_svc: |
153 | svc_entry | 189 | svc_entry |
154 | |||
155 | @ | ||
156 | @ get ready to re-enable interrupts if appropriate | ||
157 | @ | ||
158 | mrs r9, cpsr | ||
159 | tst r3, #PSR_I_BIT | ||
160 | biceq r9, r9, #PSR_I_BIT | ||
161 | |||
162 | @ | ||
163 | @ Call the processor-specific abort handler: | ||
164 | @ | ||
165 | @ r2 - aborted context pc | ||
166 | @ r3 - aborted context cpsr | ||
167 | @ | ||
168 | @ The abort handler must return the aborted address in r0, and | ||
169 | @ the fault status register in r1. r9 must be preserved. | ||
170 | @ | ||
171 | #ifdef MULTI_DABORT | ||
172 | ldr r4, .LCprocfns | ||
173 | mov lr, pc | ||
174 | ldr pc, [r4, #PROCESSOR_DABT_FUNC] | ||
175 | #else | ||
176 | bl CPU_DABORT_HANDLER | ||
177 | #endif | ||
178 | |||
179 | @ | ||
180 | @ set desired IRQ state, then call main handler | ||
181 | @ | ||
182 | debug_entry r1 | ||
183 | msr cpsr_c, r9 | ||
184 | mov r2, sp | 190 | mov r2, sp |
185 | bl do_DataAbort | 191 | dabt_helper |
186 | 192 | ||
187 | @ | 193 | @ |
188 | @ IRQs off again before pulling preserved data off the stack | 194 | @ IRQs off again before pulling preserved data off the stack |
189 | @ | 195 | @ |
190 | disable_irq_notrace | 196 | disable_irq_notrace |
191 | 197 | ||
192 | @ | 198 | #ifdef CONFIG_TRACE_IRQFLAGS |
193 | @ restore SPSR and restart the instruction | 199 | tst r5, #PSR_I_BIT |
194 | @ | 200 | bleq trace_hardirqs_on |
195 | ldr r2, [sp, #S_PSR] | 201 | tst r5, #PSR_I_BIT |
196 | svc_exit r2 @ return from exception | 202 | blne trace_hardirqs_off |
203 | #endif | ||
204 | svc_exit r5 @ return from exception | ||
197 | UNWIND(.fnend ) | 205 | UNWIND(.fnend ) |
198 | ENDPROC(__dabt_svc) | 206 | ENDPROC(__dabt_svc) |
199 | 207 | ||
200 | .align 5 | 208 | .align 5 |
201 | __irq_svc: | 209 | __irq_svc: |
202 | svc_entry | 210 | svc_entry |
211 | irq_handler | ||
203 | 212 | ||
204 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
205 | bl trace_hardirqs_off | ||
206 | #endif | ||
207 | #ifdef CONFIG_PREEMPT | 213 | #ifdef CONFIG_PREEMPT |
208 | get_thread_info tsk | 214 | get_thread_info tsk |
209 | ldr r8, [tsk, #TI_PREEMPT] @ get preempt count | 215 | ldr r8, [tsk, #TI_PREEMPT] @ get preempt count |
210 | add r7, r8, #1 @ increment it | ||
211 | str r7, [tsk, #TI_PREEMPT] | ||
212 | #endif | ||
213 | |||
214 | irq_handler | ||
215 | #ifdef CONFIG_PREEMPT | ||
216 | str r8, [tsk, #TI_PREEMPT] @ restore preempt count | ||
217 | ldr r0, [tsk, #TI_FLAGS] @ get flags | 216 | ldr r0, [tsk, #TI_FLAGS] @ get flags |
218 | teq r8, #0 @ if preempt count != 0 | 217 | teq r8, #0 @ if preempt count != 0 |
219 | movne r0, #0 @ force flags to 0 | 218 | movne r0, #0 @ force flags to 0 |
220 | tst r0, #_TIF_NEED_RESCHED | 219 | tst r0, #_TIF_NEED_RESCHED |
221 | blne svc_preempt | 220 | blne svc_preempt |
222 | #endif | 221 | #endif |
223 | ldr r4, [sp, #S_PSR] @ irqs are already disabled | 222 | |
224 | #ifdef CONFIG_TRACE_IRQFLAGS | 223 | #ifdef CONFIG_TRACE_IRQFLAGS |
225 | tst r4, #PSR_I_BIT | 224 | @ The parent context IRQs must have been enabled to get here in |
226 | bleq trace_hardirqs_on | 225 | @ the first place, so there's no point checking the PSR I bit. |
226 | bl trace_hardirqs_on | ||
227 | #endif | 227 | #endif |
228 | svc_exit r4 @ return from exception | 228 | svc_exit r5 @ return from exception |
229 | UNWIND(.fnend ) | 229 | UNWIND(.fnend ) |
230 | ENDPROC(__irq_svc) | 230 | ENDPROC(__irq_svc) |
231 | 231 | ||
@@ -251,7 +251,6 @@ __und_svc: | |||
251 | #else | 251 | #else |
252 | svc_entry | 252 | svc_entry |
253 | #endif | 253 | #endif |
254 | |||
255 | @ | 254 | @ |
256 | @ call emulation code, which returns using r9 if it has emulated | 255 | @ call emulation code, which returns using r9 if it has emulated |
257 | @ the instruction, or the more conventional lr if we are to treat | 256 | @ the instruction, or the more conventional lr if we are to treat |
@@ -260,15 +259,16 @@ __und_svc: | |||
260 | @ r0 - instruction | 259 | @ r0 - instruction |
261 | @ | 260 | @ |
262 | #ifndef CONFIG_THUMB2_KERNEL | 261 | #ifndef CONFIG_THUMB2_KERNEL |
263 | ldr r0, [r2, #-4] | 262 | ldr r0, [r4, #-4] |
264 | #else | 263 | #else |
265 | ldrh r0, [r2, #-2] @ Thumb instruction at LR - 2 | 264 | ldrh r0, [r4, #-2] @ Thumb instruction at LR - 2 |
266 | and r9, r0, #0xf800 | 265 | and r9, r0, #0xf800 |
267 | cmp r9, #0xe800 @ 32-bit instruction if xx >= 0 | 266 | cmp r9, #0xe800 @ 32-bit instruction if xx >= 0 |
268 | ldrhhs r9, [r2] @ bottom 16 bits | 267 | ldrhhs r9, [r4] @ bottom 16 bits |
269 | orrhs r0, r9, r0, lsl #16 | 268 | orrhs r0, r9, r0, lsl #16 |
270 | #endif | 269 | #endif |
271 | adr r9, BSYM(1f) | 270 | adr r9, BSYM(1f) |
271 | mov r2, r4 | ||
272 | bl call_fpe | 272 | bl call_fpe |
273 | 273 | ||
274 | mov r0, sp @ struct pt_regs *regs | 274 | mov r0, sp @ struct pt_regs *regs |
@@ -282,45 +282,35 @@ __und_svc: | |||
282 | @ | 282 | @ |
283 | @ restore SPSR and restart the instruction | 283 | @ restore SPSR and restart the instruction |
284 | @ | 284 | @ |
285 | ldr r2, [sp, #S_PSR] @ Get SVC cpsr | 285 | ldr r5, [sp, #S_PSR] @ Get SVC cpsr |
286 | svc_exit r2 @ return from exception | 286 | #ifdef CONFIG_TRACE_IRQFLAGS |
287 | tst r5, #PSR_I_BIT | ||
288 | bleq trace_hardirqs_on | ||
289 | tst r5, #PSR_I_BIT | ||
290 | blne trace_hardirqs_off | ||
291 | #endif | ||
292 | svc_exit r5 @ return from exception | ||
287 | UNWIND(.fnend ) | 293 | UNWIND(.fnend ) |
288 | ENDPROC(__und_svc) | 294 | ENDPROC(__und_svc) |
289 | 295 | ||
290 | .align 5 | 296 | .align 5 |
291 | __pabt_svc: | 297 | __pabt_svc: |
292 | svc_entry | 298 | svc_entry |
293 | |||
294 | @ | ||
295 | @ re-enable interrupts if appropriate | ||
296 | @ | ||
297 | mrs r9, cpsr | ||
298 | tst r3, #PSR_I_BIT | ||
299 | biceq r9, r9, #PSR_I_BIT | ||
300 | |||
301 | mov r0, r2 @ pass address of aborted instruction. | ||
302 | #ifdef MULTI_PABORT | ||
303 | ldr r4, .LCprocfns | ||
304 | mov lr, pc | ||
305 | ldr pc, [r4, #PROCESSOR_PABT_FUNC] | ||
306 | #else | ||
307 | bl CPU_PABORT_HANDLER | ||
308 | #endif | ||
309 | debug_entry r1 | ||
310 | msr cpsr_c, r9 @ Maybe enable interrupts | ||
311 | mov r2, sp @ regs | 299 | mov r2, sp @ regs |
312 | bl do_PrefetchAbort @ call abort handler | 300 | pabt_helper |
313 | 301 | ||
314 | @ | 302 | @ |
315 | @ IRQs off again before pulling preserved data off the stack | 303 | @ IRQs off again before pulling preserved data off the stack |
316 | @ | 304 | @ |
317 | disable_irq_notrace | 305 | disable_irq_notrace |
318 | 306 | ||
319 | @ | 307 | #ifdef CONFIG_TRACE_IRQFLAGS |
320 | @ restore SPSR and restart the instruction | 308 | tst r5, #PSR_I_BIT |
321 | @ | 309 | bleq trace_hardirqs_on |
322 | ldr r2, [sp, #S_PSR] | 310 | tst r5, #PSR_I_BIT |
323 | svc_exit r2 @ return from exception | 311 | blne trace_hardirqs_off |
312 | #endif | ||
313 | svc_exit r5 @ return from exception | ||
324 | UNWIND(.fnend ) | 314 | UNWIND(.fnend ) |
325 | ENDPROC(__pabt_svc) | 315 | ENDPROC(__pabt_svc) |
326 | 316 | ||
@@ -351,23 +341,23 @@ ENDPROC(__pabt_svc) | |||
351 | ARM( stmib sp, {r1 - r12} ) | 341 | ARM( stmib sp, {r1 - r12} ) |
352 | THUMB( stmia sp, {r0 - r12} ) | 342 | THUMB( stmia sp, {r0 - r12} ) |
353 | 343 | ||
354 | ldmia r0, {r1 - r3} | 344 | ldmia r0, {r3 - r5} |
355 | add r0, sp, #S_PC @ here for interlock avoidance | 345 | add r0, sp, #S_PC @ here for interlock avoidance |
356 | mov r4, #-1 @ "" "" "" "" | 346 | mov r6, #-1 @ "" "" "" "" |
357 | 347 | ||
358 | str r1, [sp] @ save the "real" r0 copied | 348 | str r3, [sp] @ save the "real" r0 copied |
359 | @ from the exception stack | 349 | @ from the exception stack |
360 | 350 | ||
361 | @ | 351 | @ |
362 | @ We are now ready to fill in the remaining blanks on the stack: | 352 | @ We are now ready to fill in the remaining blanks on the stack: |
363 | @ | 353 | @ |
364 | @ r2 - lr_<exception>, already fixed up for correct return/restart | 354 | @ r4 - lr_<exception>, already fixed up for correct return/restart |
365 | @ r3 - spsr_<exception> | 355 | @ r5 - spsr_<exception> |
366 | @ r4 - orig_r0 (see pt_regs definition in ptrace.h) | 356 | @ r6 - orig_r0 (see pt_regs definition in ptrace.h) |
367 | @ | 357 | @ |
368 | @ Also, separately save sp_usr and lr_usr | 358 | @ Also, separately save sp_usr and lr_usr |
369 | @ | 359 | @ |
370 | stmia r0, {r2 - r4} | 360 | stmia r0, {r4 - r6} |
371 | ARM( stmdb r0, {sp, lr}^ ) | 361 | ARM( stmdb r0, {sp, lr}^ ) |
372 | THUMB( store_user_sp_lr r0, r1, S_SP - S_PC ) | 362 | THUMB( store_user_sp_lr r0, r1, S_SP - S_PC ) |
373 | 363 | ||
@@ -380,6 +370,10 @@ ENDPROC(__pabt_svc) | |||
380 | @ Clear FP to mark the first stack frame | 370 | @ Clear FP to mark the first stack frame |
381 | @ | 371 | @ |
382 | zero_fp | 372 | zero_fp |
373 | |||
374 | #ifdef CONFIG_IRQSOFF_TRACER | ||
375 | bl trace_hardirqs_off | ||
376 | #endif | ||
383 | .endm | 377 | .endm |
384 | 378 | ||
385 | .macro kuser_cmpxchg_check | 379 | .macro kuser_cmpxchg_check |
@@ -391,7 +385,7 @@ ENDPROC(__pabt_svc) | |||
391 | @ if it was interrupted in a critical region. Here we | 385 | @ if it was interrupted in a critical region. Here we |
392 | @ perform a quick test inline since it should be false | 386 | @ perform a quick test inline since it should be false |
393 | @ 99.9999% of the time. The rest is done out of line. | 387 | @ 99.9999% of the time. The rest is done out of line. |
394 | cmp r2, #TASK_SIZE | 388 | cmp r4, #TASK_SIZE |
395 | blhs kuser_cmpxchg_fixup | 389 | blhs kuser_cmpxchg_fixup |
396 | #endif | 390 | #endif |
397 | #endif | 391 | #endif |
@@ -401,32 +395,9 @@ ENDPROC(__pabt_svc) | |||
401 | __dabt_usr: | 395 | __dabt_usr: |
402 | usr_entry | 396 | usr_entry |
403 | kuser_cmpxchg_check | 397 | kuser_cmpxchg_check |
404 | |||
405 | @ | ||
406 | @ Call the processor-specific abort handler: | ||
407 | @ | ||
408 | @ r2 - aborted context pc | ||
409 | @ r3 - aborted context cpsr | ||
410 | @ | ||
411 | @ The abort handler must return the aborted address in r0, and | ||
412 | @ the fault status register in r1. | ||
413 | @ | ||
414 | #ifdef MULTI_DABORT | ||
415 | ldr r4, .LCprocfns | ||
416 | mov lr, pc | ||
417 | ldr pc, [r4, #PROCESSOR_DABT_FUNC] | ||
418 | #else | ||
419 | bl CPU_DABORT_HANDLER | ||
420 | #endif | ||
421 | |||
422 | @ | ||
423 | @ IRQs on, then call the main handler | ||
424 | @ | ||
425 | debug_entry r1 | ||
426 | enable_irq | ||
427 | mov r2, sp | 398 | mov r2, sp |
428 | adr lr, BSYM(ret_from_exception) | 399 | dabt_helper |
429 | b do_DataAbort | 400 | b ret_from_exception |
430 | UNWIND(.fnend ) | 401 | UNWIND(.fnend ) |
431 | ENDPROC(__dabt_usr) | 402 | ENDPROC(__dabt_usr) |
432 | 403 | ||
@@ -434,28 +405,8 @@ ENDPROC(__dabt_usr) | |||
434 | __irq_usr: | 405 | __irq_usr: |
435 | usr_entry | 406 | usr_entry |
436 | kuser_cmpxchg_check | 407 | kuser_cmpxchg_check |
437 | |||
438 | #ifdef CONFIG_IRQSOFF_TRACER | ||
439 | bl trace_hardirqs_off | ||
440 | #endif | ||
441 | |||
442 | get_thread_info tsk | ||
443 | #ifdef CONFIG_PREEMPT | ||
444 | ldr r8, [tsk, #TI_PREEMPT] @ get preempt count | ||
445 | add r7, r8, #1 @ increment it | ||
446 | str r7, [tsk, #TI_PREEMPT] | ||
447 | #endif | ||
448 | |||
449 | irq_handler | 408 | irq_handler |
450 | #ifdef CONFIG_PREEMPT | 409 | get_thread_info tsk |
451 | ldr r0, [tsk, #TI_PREEMPT] | ||
452 | str r8, [tsk, #TI_PREEMPT] | ||
453 | teq r0, r7 | ||
454 | ARM( strne r0, [r0, -r0] ) | ||
455 | THUMB( movne r0, #0 ) | ||
456 | THUMB( strne r0, [r0] ) | ||
457 | #endif | ||
458 | |||
459 | mov why, #0 | 410 | mov why, #0 |
460 | b ret_to_user_from_irq | 411 | b ret_to_user_from_irq |
461 | UNWIND(.fnend ) | 412 | UNWIND(.fnend ) |
@@ -467,6 +418,9 @@ ENDPROC(__irq_usr) | |||
467 | __und_usr: | 418 | __und_usr: |
468 | usr_entry | 419 | usr_entry |
469 | 420 | ||
421 | mov r2, r4 | ||
422 | mov r3, r5 | ||
423 | |||
470 | @ | 424 | @ |
471 | @ fall through to the emulation code, which returns using r9 if | 425 | @ fall through to the emulation code, which returns using r9 if |
472 | @ it has emulated the instruction, or the more conventional lr | 426 | @ it has emulated the instruction, or the more conventional lr |
@@ -682,19 +636,8 @@ ENDPROC(__und_usr_unknown) | |||
682 | .align 5 | 636 | .align 5 |
683 | __pabt_usr: | 637 | __pabt_usr: |
684 | usr_entry | 638 | usr_entry |
685 | |||
686 | mov r0, r2 @ pass address of aborted instruction. | ||
687 | #ifdef MULTI_PABORT | ||
688 | ldr r4, .LCprocfns | ||
689 | mov lr, pc | ||
690 | ldr pc, [r4, #PROCESSOR_PABT_FUNC] | ||
691 | #else | ||
692 | bl CPU_PABORT_HANDLER | ||
693 | #endif | ||
694 | debug_entry r1 | ||
695 | enable_irq @ Enable interrupts | ||
696 | mov r2, sp @ regs | 639 | mov r2, sp @ regs |
697 | bl do_PrefetchAbort @ call abort handler | 640 | pabt_helper |
698 | UNWIND(.fnend ) | 641 | UNWIND(.fnend ) |
699 | /* fall through */ | 642 | /* fall through */ |
700 | /* | 643 | /* |
@@ -927,13 +870,13 @@ __kuser_cmpxchg: @ 0xffff0fc0 | |||
927 | .text | 870 | .text |
928 | kuser_cmpxchg_fixup: | 871 | kuser_cmpxchg_fixup: |
929 | @ Called from kuser_cmpxchg_check macro. | 872 | @ Called from kuser_cmpxchg_check macro. |
930 | @ r2 = address of interrupted insn (must be preserved). | 873 | @ r4 = address of interrupted insn (must be preserved). |
931 | @ sp = saved regs. r7 and r8 are clobbered. | 874 | @ sp = saved regs. r7 and r8 are clobbered. |
932 | @ 1b = first critical insn, 2b = last critical insn. | 875 | @ 1b = first critical insn, 2b = last critical insn. |
933 | @ If r2 >= 1b and r2 <= 2b then saved pc_usr is set to 1b. | 876 | @ If r4 >= 1b and r4 <= 2b then saved pc_usr is set to 1b. |
934 | mov r7, #0xffff0fff | 877 | mov r7, #0xffff0fff |
935 | sub r7, r7, #(0xffff0fff - (0xffff0fc0 + (1b - __kuser_cmpxchg))) | 878 | sub r7, r7, #(0xffff0fff - (0xffff0fc0 + (1b - __kuser_cmpxchg))) |
936 | subs r8, r2, r7 | 879 | subs r8, r4, r7 |
937 | rsbcss r8, r8, #(2b - 1b) | 880 | rsbcss r8, r8, #(2b - 1b) |
938 | strcs r7, [sp, #S_PC] | 881 | strcs r7, [sp, #S_PC] |
939 | mov pc, lr | 882 | mov pc, lr |
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S index 051166c2a932..4d6ad8348e89 100644 --- a/arch/arm/kernel/entry-header.S +++ b/arch/arm/kernel/entry-header.S | |||
@@ -165,25 +165,6 @@ | |||
165 | .endm | 165 | .endm |
166 | #endif /* !CONFIG_THUMB2_KERNEL */ | 166 | #endif /* !CONFIG_THUMB2_KERNEL */ |
167 | 167 | ||
168 | @ | ||
169 | @ Debug exceptions are taken as prefetch or data aborts. | ||
170 | @ We must disable preemption during the handler so that | ||
171 | @ we can access the debug registers safely. | ||
172 | @ | ||
173 | .macro debug_entry, fsr | ||
174 | #if defined(CONFIG_HAVE_HW_BREAKPOINT) && defined(CONFIG_PREEMPT) | ||
175 | ldr r4, =0x40f @ mask out fsr.fs | ||
176 | and r5, r4, \fsr | ||
177 | cmp r5, #2 @ debug exception | ||
178 | bne 1f | ||
179 | get_thread_info r10 | ||
180 | ldr r6, [r10, #TI_PREEMPT] @ get preempt count | ||
181 | add r11, r6, #1 @ increment it | ||
182 | str r11, [r10, #TI_PREEMPT] | ||
183 | 1: | ||
184 | #endif | ||
185 | .endm | ||
186 | |||
187 | /* | 168 | /* |
188 | * These are the registers used in the syscall handler, and allow us to | 169 | * These are the registers used in the syscall handler, and allow us to |
189 | * have in theory up to 7 arguments to a function - r0 to r6. | 170 | * have in theory up to 7 arguments to a function - r0 to r6. |
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index 6b1e0ad9ec3b..d46f25968bec 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S | |||
@@ -32,8 +32,16 @@ | |||
32 | * numbers for r1. | 32 | * numbers for r1. |
33 | * | 33 | * |
34 | */ | 34 | */ |
35 | .arm | ||
36 | |||
35 | __HEAD | 37 | __HEAD |
36 | ENTRY(stext) | 38 | ENTRY(stext) |
39 | |||
40 | THUMB( adr r9, BSYM(1f) ) @ Kernel is always entered in ARM. | ||
41 | THUMB( bx r9 ) @ If this is a Thumb-2 kernel, | ||
42 | THUMB( .thumb ) @ switch to Thumb now. | ||
43 | THUMB(1: ) | ||
44 | |||
37 | setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode | 45 | setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode |
38 | @ and irqs disabled | 46 | @ and irqs disabled |
39 | #ifndef CONFIG_CPU_CP15 | 47 | #ifndef CONFIG_CPU_CP15 |
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 278c1b0ebb2e..742b6108a001 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S | |||
@@ -71,8 +71,16 @@ | |||
71 | * crap here - that's what the boot loader (or in extreme, well justified | 71 | * crap here - that's what the boot loader (or in extreme, well justified |
72 | * circumstances, zImage) is for. | 72 | * circumstances, zImage) is for. |
73 | */ | 73 | */ |
74 | .arm | ||
75 | |||
74 | __HEAD | 76 | __HEAD |
75 | ENTRY(stext) | 77 | ENTRY(stext) |
78 | |||
79 | THUMB( adr r9, BSYM(1f) ) @ Kernel is always entered in ARM. | ||
80 | THUMB( bx r9 ) @ If this is a Thumb-2 kernel, | ||
81 | THUMB( .thumb ) @ switch to Thumb now. | ||
82 | THUMB(1: ) | ||
83 | |||
76 | setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode | 84 | setmode PSR_F_BIT | PSR_I_BIT | SVC_MODE, r9 @ ensure svc mode |
77 | @ and irqs disabled | 85 | @ and irqs disabled |
78 | mrc p15, 0, r9, c0, c0 @ get processor id | 86 | mrc p15, 0, r9, c0, c0 @ get processor id |
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c index 87acc25d7a3e..a927ca1f5566 100644 --- a/arch/arm/kernel/hw_breakpoint.c +++ b/arch/arm/kernel/hw_breakpoint.c | |||
@@ -796,7 +796,7 @@ unlock: | |||
796 | 796 | ||
797 | /* | 797 | /* |
798 | * Called from either the Data Abort Handler [watchpoint] or the | 798 | * Called from either the Data Abort Handler [watchpoint] or the |
799 | * Prefetch Abort Handler [breakpoint] with preemption disabled. | 799 | * Prefetch Abort Handler [breakpoint] with interrupts disabled. |
800 | */ | 800 | */ |
801 | static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, | 801 | static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, |
802 | struct pt_regs *regs) | 802 | struct pt_regs *regs) |
@@ -804,8 +804,10 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, | |||
804 | int ret = 0; | 804 | int ret = 0; |
805 | u32 dscr; | 805 | u32 dscr; |
806 | 806 | ||
807 | /* We must be called with preemption disabled. */ | 807 | preempt_disable(); |
808 | WARN_ON(preemptible()); | 808 | |
809 | if (interrupts_enabled(regs)) | ||
810 | local_irq_enable(); | ||
809 | 811 | ||
810 | /* We only handle watchpoints and hardware breakpoints. */ | 812 | /* We only handle watchpoints and hardware breakpoints. */ |
811 | ARM_DBG_READ(c1, 0, dscr); | 813 | ARM_DBG_READ(c1, 0, dscr); |
@@ -824,10 +826,6 @@ static int hw_breakpoint_pending(unsigned long addr, unsigned int fsr, | |||
824 | ret = 1; /* Unhandled fault. */ | 826 | ret = 1; /* Unhandled fault. */ |
825 | } | 827 | } |
826 | 828 | ||
827 | /* | ||
828 | * Re-enable preemption after it was disabled in the | ||
829 | * low-level exception handling code. | ||
830 | */ | ||
831 | preempt_enable(); | 829 | preempt_enable(); |
832 | 830 | ||
833 | return ret; | 831 | return ret; |
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c index 83bbad03fcc6..0f928a131af8 100644 --- a/arch/arm/kernel/irq.c +++ b/arch/arm/kernel/irq.c | |||
@@ -131,54 +131,63 @@ int __init arch_probe_nr_irqs(void) | |||
131 | 131 | ||
132 | #ifdef CONFIG_HOTPLUG_CPU | 132 | #ifdef CONFIG_HOTPLUG_CPU |
133 | 133 | ||
134 | static bool migrate_one_irq(struct irq_data *d) | 134 | static bool migrate_one_irq(struct irq_desc *desc) |
135 | { | 135 | { |
136 | unsigned int cpu = cpumask_any_and(d->affinity, cpu_online_mask); | 136 | struct irq_data *d = irq_desc_get_irq_data(desc); |
137 | const struct cpumask *affinity = d->affinity; | ||
138 | struct irq_chip *c; | ||
137 | bool ret = false; | 139 | bool ret = false; |
138 | 140 | ||
139 | if (cpu >= nr_cpu_ids) { | 141 | /* |
140 | cpu = cpumask_any(cpu_online_mask); | 142 | * If this is a per-CPU interrupt, or the affinity does not |
143 | * include this CPU, then we have nothing to do. | ||
144 | */ | ||
145 | if (irqd_is_per_cpu(d) || !cpumask_test_cpu(smp_processor_id(), affinity)) | ||
146 | return false; | ||
147 | |||
148 | if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) { | ||
149 | affinity = cpu_online_mask; | ||
141 | ret = true; | 150 | ret = true; |
142 | } | 151 | } |
143 | 152 | ||
144 | pr_debug("IRQ%u: moving from cpu%u to cpu%u\n", d->irq, d->node, cpu); | 153 | c = irq_data_get_irq_chip(d); |
145 | 154 | if (c->irq_set_affinity) | |
146 | d->chip->irq_set_affinity(d, cpumask_of(cpu), true); | 155 | c->irq_set_affinity(d, affinity, true); |
156 | else | ||
157 | pr_debug("IRQ%u: unable to set affinity\n", d->irq); | ||
147 | 158 | ||
148 | return ret; | 159 | return ret; |
149 | } | 160 | } |
150 | 161 | ||
151 | /* | 162 | /* |
152 | * The CPU has been marked offline. Migrate IRQs off this CPU. If | 163 | * The current CPU has been marked offline. Migrate IRQs off this CPU. |
153 | * the affinity settings do not allow other CPUs, force them onto any | 164 | * If the affinity settings do not allow other CPUs, force them onto any |
154 | * available CPU. | 165 | * available CPU. |
166 | * | ||
167 | * Note: we must iterate over all IRQs, whether they have an attached | ||
168 | * action structure or not, as we need to get chained interrupts too. | ||
155 | */ | 169 | */ |
156 | void migrate_irqs(void) | 170 | void migrate_irqs(void) |
157 | { | 171 | { |
158 | unsigned int i, cpu = smp_processor_id(); | 172 | unsigned int i; |
159 | struct irq_desc *desc; | 173 | struct irq_desc *desc; |
160 | unsigned long flags; | 174 | unsigned long flags; |
161 | 175 | ||
162 | local_irq_save(flags); | 176 | local_irq_save(flags); |
163 | 177 | ||
164 | for_each_irq_desc(i, desc) { | 178 | for_each_irq_desc(i, desc) { |
165 | struct irq_data *d = &desc->irq_data; | ||
166 | bool affinity_broken = false; | 179 | bool affinity_broken = false; |
167 | 180 | ||
168 | raw_spin_lock(&desc->lock); | 181 | if (!desc) |
169 | do { | 182 | continue; |
170 | if (desc->action == NULL) | ||
171 | break; | ||
172 | |||
173 | if (d->node != cpu) | ||
174 | break; | ||
175 | 183 | ||
176 | affinity_broken = migrate_one_irq(d); | 184 | raw_spin_lock(&desc->lock); |
177 | } while (0); | 185 | affinity_broken = migrate_one_irq(desc); |
178 | raw_spin_unlock(&desc->lock); | 186 | raw_spin_unlock(&desc->lock); |
179 | 187 | ||
180 | if (affinity_broken && printk_ratelimit()) | 188 | if (affinity_broken && printk_ratelimit()) |
181 | pr_warning("IRQ%u no longer affine to CPU%u\n", i, cpu); | 189 | pr_warning("IRQ%u no longer affine to CPU%u\n", i, |
190 | smp_processor_id()); | ||
182 | } | 191 | } |
183 | 192 | ||
184 | local_irq_restore(flags); | 193 | local_irq_restore(flags); |
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c index d53c0abc4dd3..8d8507858e5c 100644 --- a/arch/arm/kernel/perf_event.c +++ b/arch/arm/kernel/perf_event.c | |||
@@ -435,7 +435,7 @@ armpmu_reserve_hardware(void) | |||
435 | if (irq >= 0) | 435 | if (irq >= 0) |
436 | free_irq(irq, NULL); | 436 | free_irq(irq, NULL); |
437 | } | 437 | } |
438 | release_pmu(pmu_device); | 438 | release_pmu(ARM_PMU_DEVICE_CPU); |
439 | pmu_device = NULL; | 439 | pmu_device = NULL; |
440 | } | 440 | } |
441 | 441 | ||
@@ -454,7 +454,7 @@ armpmu_release_hardware(void) | |||
454 | } | 454 | } |
455 | armpmu->stop(); | 455 | armpmu->stop(); |
456 | 456 | ||
457 | release_pmu(pmu_device); | 457 | release_pmu(ARM_PMU_DEVICE_CPU); |
458 | pmu_device = NULL; | 458 | pmu_device = NULL; |
459 | } | 459 | } |
460 | 460 | ||
@@ -583,7 +583,7 @@ static int armpmu_event_init(struct perf_event *event) | |||
583 | static void armpmu_enable(struct pmu *pmu) | 583 | static void armpmu_enable(struct pmu *pmu) |
584 | { | 584 | { |
585 | /* Enable all of the perf events on hardware. */ | 585 | /* Enable all of the perf events on hardware. */ |
586 | int idx; | 586 | int idx, enabled = 0; |
587 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); | 587 | struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); |
588 | 588 | ||
589 | if (!armpmu) | 589 | if (!armpmu) |
@@ -596,9 +596,11 @@ static void armpmu_enable(struct pmu *pmu) | |||
596 | continue; | 596 | continue; |
597 | 597 | ||
598 | armpmu->enable(&event->hw, idx); | 598 | armpmu->enable(&event->hw, idx); |
599 | enabled = 1; | ||
599 | } | 600 | } |
600 | 601 | ||
601 | armpmu->start(); | 602 | if (enabled) |
603 | armpmu->start(); | ||
602 | } | 604 | } |
603 | 605 | ||
604 | static void armpmu_disable(struct pmu *pmu) | 606 | static void armpmu_disable(struct pmu *pmu) |
diff --git a/arch/arm/kernel/pmu.c b/arch/arm/kernel/pmu.c index 2c79eec19262..2b70709376c3 100644 --- a/arch/arm/kernel/pmu.c +++ b/arch/arm/kernel/pmu.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/interrupt.h> | 17 | #include <linux/interrupt.h> |
18 | #include <linux/kernel.h> | 18 | #include <linux/kernel.h> |
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/of_device.h> | ||
20 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
21 | 22 | ||
22 | #include <asm/pmu.h> | 23 | #include <asm/pmu.h> |
@@ -25,36 +26,88 @@ static volatile long pmu_lock; | |||
25 | 26 | ||
26 | static struct platform_device *pmu_devices[ARM_NUM_PMU_DEVICES]; | 27 | static struct platform_device *pmu_devices[ARM_NUM_PMU_DEVICES]; |
27 | 28 | ||
28 | static int __devinit pmu_device_probe(struct platform_device *pdev) | 29 | static int __devinit pmu_register(struct platform_device *pdev, |
30 | enum arm_pmu_type type) | ||
29 | { | 31 | { |
30 | 32 | if (type < 0 || type >= ARM_NUM_PMU_DEVICES) { | |
31 | if (pdev->id < 0 || pdev->id >= ARM_NUM_PMU_DEVICES) { | ||
32 | pr_warning("received registration request for unknown " | 33 | pr_warning("received registration request for unknown " |
33 | "device %d\n", pdev->id); | 34 | "device %d\n", type); |
34 | return -EINVAL; | 35 | return -EINVAL; |
35 | } | 36 | } |
36 | 37 | ||
37 | if (pmu_devices[pdev->id]) | 38 | if (pmu_devices[type]) { |
38 | pr_warning("registering new PMU device type %d overwrites " | 39 | pr_warning("rejecting duplicate registration of PMU device " |
39 | "previous registration!\n", pdev->id); | 40 | "type %d.", type); |
40 | else | 41 | return -ENOSPC; |
41 | pr_info("registered new PMU device of type %d\n", | 42 | } |
42 | pdev->id); | ||
43 | 43 | ||
44 | pmu_devices[pdev->id] = pdev; | 44 | pr_info("registered new PMU device of type %d\n", type); |
45 | pmu_devices[type] = pdev; | ||
45 | return 0; | 46 | return 0; |
46 | } | 47 | } |
47 | 48 | ||
48 | static struct platform_driver pmu_driver = { | 49 | #define OF_MATCH_PMU(_name, _type) { \ |
50 | .compatible = _name, \ | ||
51 | .data = (void *)_type, \ | ||
52 | } | ||
53 | |||
54 | #define OF_MATCH_CPU(name) OF_MATCH_PMU(name, ARM_PMU_DEVICE_CPU) | ||
55 | |||
56 | static struct of_device_id armpmu_of_device_ids[] = { | ||
57 | OF_MATCH_CPU("arm,cortex-a9-pmu"), | ||
58 | OF_MATCH_CPU("arm,cortex-a8-pmu"), | ||
59 | OF_MATCH_CPU("arm,arm1136-pmu"), | ||
60 | OF_MATCH_CPU("arm,arm1176-pmu"), | ||
61 | {}, | ||
62 | }; | ||
63 | |||
64 | #define PLAT_MATCH_PMU(_name, _type) { \ | ||
65 | .name = _name, \ | ||
66 | .driver_data = _type, \ | ||
67 | } | ||
68 | |||
69 | #define PLAT_MATCH_CPU(_name) PLAT_MATCH_PMU(_name, ARM_PMU_DEVICE_CPU) | ||
70 | |||
71 | static struct platform_device_id armpmu_plat_device_ids[] = { | ||
72 | PLAT_MATCH_CPU("arm-pmu"), | ||
73 | {}, | ||
74 | }; | ||
75 | |||
76 | enum arm_pmu_type armpmu_device_type(struct platform_device *pdev) | ||
77 | { | ||
78 | const struct of_device_id *of_id; | ||
79 | const struct platform_device_id *pdev_id; | ||
80 | |||
81 | /* provided by of_device_id table */ | ||
82 | if (pdev->dev.of_node) { | ||
83 | of_id = of_match_device(armpmu_of_device_ids, &pdev->dev); | ||
84 | BUG_ON(!of_id); | ||
85 | return (enum arm_pmu_type)of_id->data; | ||
86 | } | ||
87 | |||
88 | /* Provided by platform_device_id table */ | ||
89 | pdev_id = platform_get_device_id(pdev); | ||
90 | BUG_ON(!pdev_id); | ||
91 | return pdev_id->driver_data; | ||
92 | } | ||
93 | |||
94 | static int __devinit armpmu_device_probe(struct platform_device *pdev) | ||
95 | { | ||
96 | return pmu_register(pdev, armpmu_device_type(pdev)); | ||
97 | } | ||
98 | |||
99 | static struct platform_driver armpmu_driver = { | ||
49 | .driver = { | 100 | .driver = { |
50 | .name = "arm-pmu", | 101 | .name = "arm-pmu", |
102 | .of_match_table = armpmu_of_device_ids, | ||
51 | }, | 103 | }, |
52 | .probe = pmu_device_probe, | 104 | .probe = armpmu_device_probe, |
105 | .id_table = armpmu_plat_device_ids, | ||
53 | }; | 106 | }; |
54 | 107 | ||
55 | static int __init register_pmu_driver(void) | 108 | static int __init register_pmu_driver(void) |
56 | { | 109 | { |
57 | return platform_driver_register(&pmu_driver); | 110 | return platform_driver_register(&armpmu_driver); |
58 | } | 111 | } |
59 | device_initcall(register_pmu_driver); | 112 | device_initcall(register_pmu_driver); |
60 | 113 | ||
@@ -77,11 +130,11 @@ reserve_pmu(enum arm_pmu_type device) | |||
77 | EXPORT_SYMBOL_GPL(reserve_pmu); | 130 | EXPORT_SYMBOL_GPL(reserve_pmu); |
78 | 131 | ||
79 | int | 132 | int |
80 | release_pmu(struct platform_device *pdev) | 133 | release_pmu(enum arm_pmu_type device) |
81 | { | 134 | { |
82 | if (WARN_ON(pdev != pmu_devices[pdev->id])) | 135 | if (WARN_ON(!pmu_devices[device])) |
83 | return -EINVAL; | 136 | return -EINVAL; |
84 | clear_bit_unlock(pdev->id, &pmu_lock); | 137 | clear_bit_unlock(device, &pmu_lock); |
85 | return 0; | 138 | return 0; |
86 | } | 139 | } |
87 | EXPORT_SYMBOL_GPL(release_pmu); | 140 | EXPORT_SYMBOL_GPL(release_pmu); |
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index ed11fb08b05a..9c3278f37796 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -73,6 +73,7 @@ __setup("fpe=", fpe_setup); | |||
73 | #endif | 73 | #endif |
74 | 74 | ||
75 | extern void paging_init(struct machine_desc *desc); | 75 | extern void paging_init(struct machine_desc *desc); |
76 | extern void sanity_check_meminfo(void); | ||
76 | extern void reboot_setup(char *str); | 77 | extern void reboot_setup(char *str); |
77 | 78 | ||
78 | unsigned int processor_id; | 79 | unsigned int processor_id; |
@@ -342,54 +343,6 @@ static void __init feat_v6_fixup(void) | |||
342 | elf_hwcap &= ~HWCAP_TLS; | 343 | elf_hwcap &= ~HWCAP_TLS; |
343 | } | 344 | } |
344 | 345 | ||
345 | static void __init setup_processor(void) | ||
346 | { | ||
347 | struct proc_info_list *list; | ||
348 | |||
349 | /* | ||
350 | * locate processor in the list of supported processor | ||
351 | * types. The linker builds this table for us from the | ||
352 | * entries in arch/arm/mm/proc-*.S | ||
353 | */ | ||
354 | list = lookup_processor_type(read_cpuid_id()); | ||
355 | if (!list) { | ||
356 | printk("CPU configuration botched (ID %08x), unable " | ||
357 | "to continue.\n", read_cpuid_id()); | ||
358 | while (1); | ||
359 | } | ||
360 | |||
361 | cpu_name = list->cpu_name; | ||
362 | |||
363 | #ifdef MULTI_CPU | ||
364 | processor = *list->proc; | ||
365 | #endif | ||
366 | #ifdef MULTI_TLB | ||
367 | cpu_tlb = *list->tlb; | ||
368 | #endif | ||
369 | #ifdef MULTI_USER | ||
370 | cpu_user = *list->user; | ||
371 | #endif | ||
372 | #ifdef MULTI_CACHE | ||
373 | cpu_cache = *list->cache; | ||
374 | #endif | ||
375 | |||
376 | printk("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n", | ||
377 | cpu_name, read_cpuid_id(), read_cpuid_id() & 15, | ||
378 | proc_arch[cpu_architecture()], cr_alignment); | ||
379 | |||
380 | sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS); | ||
381 | sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS); | ||
382 | elf_hwcap = list->elf_hwcap; | ||
383 | #ifndef CONFIG_ARM_THUMB | ||
384 | elf_hwcap &= ~HWCAP_THUMB; | ||
385 | #endif | ||
386 | |||
387 | feat_v6_fixup(); | ||
388 | |||
389 | cacheid_init(); | ||
390 | cpu_proc_init(); | ||
391 | } | ||
392 | |||
393 | /* | 346 | /* |
394 | * cpu_init - initialise one CPU. | 347 | * cpu_init - initialise one CPU. |
395 | * | 348 | * |
@@ -405,6 +358,8 @@ void cpu_init(void) | |||
405 | BUG(); | 358 | BUG(); |
406 | } | 359 | } |
407 | 360 | ||
361 | cpu_proc_init(); | ||
362 | |||
408 | /* | 363 | /* |
409 | * Define the placement constraint for the inline asm directive below. | 364 | * Define the placement constraint for the inline asm directive below. |
410 | * In Thumb-2, msr with an immediate value is not allowed. | 365 | * In Thumb-2, msr with an immediate value is not allowed. |
@@ -441,6 +396,54 @@ void cpu_init(void) | |||
441 | : "r14"); | 396 | : "r14"); |
442 | } | 397 | } |
443 | 398 | ||
399 | static void __init setup_processor(void) | ||
400 | { | ||
401 | struct proc_info_list *list; | ||
402 | |||
403 | /* | ||
404 | * locate processor in the list of supported processor | ||
405 | * types. The linker builds this table for us from the | ||
406 | * entries in arch/arm/mm/proc-*.S | ||
407 | */ | ||
408 | list = lookup_processor_type(read_cpuid_id()); | ||
409 | if (!list) { | ||
410 | printk("CPU configuration botched (ID %08x), unable " | ||
411 | "to continue.\n", read_cpuid_id()); | ||
412 | while (1); | ||
413 | } | ||
414 | |||
415 | cpu_name = list->cpu_name; | ||
416 | |||
417 | #ifdef MULTI_CPU | ||
418 | processor = *list->proc; | ||
419 | #endif | ||
420 | #ifdef MULTI_TLB | ||
421 | cpu_tlb = *list->tlb; | ||
422 | #endif | ||
423 | #ifdef MULTI_USER | ||
424 | cpu_user = *list->user; | ||
425 | #endif | ||
426 | #ifdef MULTI_CACHE | ||
427 | cpu_cache = *list->cache; | ||
428 | #endif | ||
429 | |||
430 | printk("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n", | ||
431 | cpu_name, read_cpuid_id(), read_cpuid_id() & 15, | ||
432 | proc_arch[cpu_architecture()], cr_alignment); | ||
433 | |||
434 | sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS); | ||
435 | sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS); | ||
436 | elf_hwcap = list->elf_hwcap; | ||
437 | #ifndef CONFIG_ARM_THUMB | ||
438 | elf_hwcap &= ~HWCAP_THUMB; | ||
439 | #endif | ||
440 | |||
441 | feat_v6_fixup(); | ||
442 | |||
443 | cacheid_init(); | ||
444 | cpu_init(); | ||
445 | } | ||
446 | |||
444 | void __init dump_machine_table(void) | 447 | void __init dump_machine_table(void) |
445 | { | 448 | { |
446 | struct machine_desc *p; | 449 | struct machine_desc *p; |
@@ -900,6 +903,7 @@ void __init setup_arch(char **cmdline_p) | |||
900 | 903 | ||
901 | parse_early_param(); | 904 | parse_early_param(); |
902 | 905 | ||
906 | sanity_check_meminfo(); | ||
903 | arm_memblock_init(&meminfo, mdesc); | 907 | arm_memblock_init(&meminfo, mdesc); |
904 | 908 | ||
905 | paging_init(mdesc); | 909 | paging_init(mdesc); |
@@ -913,7 +917,6 @@ void __init setup_arch(char **cmdline_p) | |||
913 | #endif | 917 | #endif |
914 | reserve_crashkernel(); | 918 | reserve_crashkernel(); |
915 | 919 | ||
916 | cpu_init(); | ||
917 | tcm_init(); | 920 | tcm_init(); |
918 | 921 | ||
919 | #ifdef CONFIG_MULTI_IRQ_HANDLER | 922 | #ifdef CONFIG_MULTI_IRQ_HANDLER |
diff --git a/arch/arm/kernel/sleep.S b/arch/arm/kernel/sleep.S index 6398ead9d1c0..dc902f2c6845 100644 --- a/arch/arm/kernel/sleep.S +++ b/arch/arm/kernel/sleep.S | |||
@@ -10,64 +10,61 @@ | |||
10 | /* | 10 | /* |
11 | * Save CPU state for a suspend | 11 | * Save CPU state for a suspend |
12 | * r1 = v:p offset | 12 | * r1 = v:p offset |
13 | * r3 = virtual return function | 13 | * r2 = suspend function arg0 |
14 | * Note: sp is decremented to allocate space for CPU state on stack | 14 | * r3 = suspend function |
15 | * r0-r3,r9,r10,lr corrupted | ||
16 | */ | 15 | */ |
17 | ENTRY(cpu_suspend) | 16 | ENTRY(__cpu_suspend) |
18 | mov r9, lr | 17 | stmfd sp!, {r4 - r11, lr} |
19 | #ifdef MULTI_CPU | 18 | #ifdef MULTI_CPU |
20 | ldr r10, =processor | 19 | ldr r10, =processor |
21 | mov r2, sp @ current virtual SP | 20 | ldr r5, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state |
22 | ldr r0, [r10, #CPU_SLEEP_SIZE] @ size of CPU sleep state | ||
23 | ldr ip, [r10, #CPU_DO_RESUME] @ virtual resume function | 21 | ldr ip, [r10, #CPU_DO_RESUME] @ virtual resume function |
24 | sub sp, sp, r0 @ allocate CPU state on stack | 22 | #else |
25 | mov r0, sp @ save pointer | 23 | ldr r5, =cpu_suspend_size |
24 | ldr ip, =cpu_do_resume | ||
25 | #endif | ||
26 | mov r6, sp @ current virtual SP | ||
27 | sub sp, sp, r5 @ allocate CPU state on stack | ||
28 | mov r0, sp @ save pointer to CPU save block | ||
26 | add ip, ip, r1 @ convert resume fn to phys | 29 | add ip, ip, r1 @ convert resume fn to phys |
27 | stmfd sp!, {r1, r2, r3, ip} @ save v:p, virt SP, retfn, phys resume fn | 30 | stmfd sp!, {r1, r6, ip} @ save v:p, virt SP, phys resume fn |
28 | ldr r3, =sleep_save_sp | 31 | ldr r5, =sleep_save_sp |
29 | add r2, sp, r1 @ convert SP to phys | 32 | add r6, sp, r1 @ convert SP to phys |
33 | stmfd sp!, {r2, r3} @ save suspend func arg and pointer | ||
30 | #ifdef CONFIG_SMP | 34 | #ifdef CONFIG_SMP |
31 | ALT_SMP(mrc p15, 0, lr, c0, c0, 5) | 35 | ALT_SMP(mrc p15, 0, lr, c0, c0, 5) |
32 | ALT_UP(mov lr, #0) | 36 | ALT_UP(mov lr, #0) |
33 | and lr, lr, #15 | 37 | and lr, lr, #15 |
34 | str r2, [r3, lr, lsl #2] @ save phys SP | 38 | str r6, [r5, lr, lsl #2] @ save phys SP |
35 | #else | 39 | #else |
36 | str r2, [r3] @ save phys SP | 40 | str r6, [r5] @ save phys SP |
37 | #endif | 41 | #endif |
42 | #ifdef MULTI_CPU | ||
38 | mov lr, pc | 43 | mov lr, pc |
39 | ldr pc, [r10, #CPU_DO_SUSPEND] @ save CPU state | 44 | ldr pc, [r10, #CPU_DO_SUSPEND] @ save CPU state |
40 | #else | 45 | #else |
41 | mov r2, sp @ current virtual SP | ||
42 | ldr r0, =cpu_suspend_size | ||
43 | sub sp, sp, r0 @ allocate CPU state on stack | ||
44 | mov r0, sp @ save pointer | ||
45 | stmfd sp!, {r1, r2, r3} @ save v:p, virt SP, return fn | ||
46 | ldr r3, =sleep_save_sp | ||
47 | add r2, sp, r1 @ convert SP to phys | ||
48 | #ifdef CONFIG_SMP | ||
49 | ALT_SMP(mrc p15, 0, lr, c0, c0, 5) | ||
50 | ALT_UP(mov lr, #0) | ||
51 | and lr, lr, #15 | ||
52 | str r2, [r3, lr, lsl #2] @ save phys SP | ||
53 | #else | ||
54 | str r2, [r3] @ save phys SP | ||
55 | #endif | ||
56 | bl cpu_do_suspend | 46 | bl cpu_do_suspend |
57 | #endif | 47 | #endif |
58 | 48 | ||
59 | @ flush data cache | 49 | @ flush data cache |
60 | #ifdef MULTI_CACHE | 50 | #ifdef MULTI_CACHE |
61 | ldr r10, =cpu_cache | 51 | ldr r10, =cpu_cache |
62 | mov lr, r9 | 52 | mov lr, pc |
63 | ldr pc, [r10, #CACHE_FLUSH_KERN_ALL] | 53 | ldr pc, [r10, #CACHE_FLUSH_KERN_ALL] |
64 | #else | 54 | #else |
65 | mov lr, r9 | 55 | bl __cpuc_flush_kern_all |
66 | b __cpuc_flush_kern_all | ||
67 | #endif | 56 | #endif |
68 | ENDPROC(cpu_suspend) | 57 | adr lr, BSYM(cpu_suspend_abort) |
58 | ldmfd sp!, {r0, pc} @ call suspend fn | ||
59 | ENDPROC(__cpu_suspend) | ||
69 | .ltorg | 60 | .ltorg |
70 | 61 | ||
62 | cpu_suspend_abort: | ||
63 | ldmia sp!, {r1 - r3} @ pop v:p, virt SP, phys resume fn | ||
64 | mov sp, r2 | ||
65 | ldmfd sp!, {r4 - r11, pc} | ||
66 | ENDPROC(cpu_suspend_abort) | ||
67 | |||
71 | /* | 68 | /* |
72 | * r0 = control register value | 69 | * r0 = control register value |
73 | * r1 = v:p offset (preserved by cpu_do_resume) | 70 | * r1 = v:p offset (preserved by cpu_do_resume) |
@@ -97,7 +94,9 @@ ENDPROC(cpu_resume_turn_mmu_on) | |||
97 | cpu_resume_after_mmu: | 94 | cpu_resume_after_mmu: |
98 | str r5, [r2, r4, lsl #2] @ restore old mapping | 95 | str r5, [r2, r4, lsl #2] @ restore old mapping |
99 | mcr p15, 0, r0, c1, c0, 0 @ turn on D-cache | 96 | mcr p15, 0, r0, c1, c0, 0 @ turn on D-cache |
100 | mov pc, lr | 97 | bl cpu_init @ restore the und/abt/irq banked regs |
98 | mov r0, #0 @ return zero on success | ||
99 | ldmfd sp!, {r4 - r11, pc} | ||
101 | ENDPROC(cpu_resume_after_mmu) | 100 | ENDPROC(cpu_resume_after_mmu) |
102 | 101 | ||
103 | /* | 102 | /* |
@@ -120,20 +119,11 @@ ENTRY(cpu_resume) | |||
120 | ldr r0, sleep_save_sp @ stack phys addr | 119 | ldr r0, sleep_save_sp @ stack phys addr |
121 | #endif | 120 | #endif |
122 | setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1 @ set SVC, irqs off | 121 | setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1 @ set SVC, irqs off |
123 | #ifdef MULTI_CPU | 122 | @ load v:p, stack, resume fn |
124 | @ load v:p, stack, return fn, resume fn | 123 | ARM( ldmia r0!, {r1, sp, pc} ) |
125 | ARM( ldmia r0!, {r1, sp, lr, pc} ) | 124 | THUMB( ldmia r0!, {r1, r2, r3} ) |
126 | THUMB( ldmia r0!, {r1, r2, r3, r4} ) | ||
127 | THUMB( mov sp, r2 ) | 125 | THUMB( mov sp, r2 ) |
128 | THUMB( mov lr, r3 ) | 126 | THUMB( bx r3 ) |
129 | THUMB( bx r4 ) | ||
130 | #else | ||
131 | @ load v:p, stack, return fn | ||
132 | ARM( ldmia r0!, {r1, sp, lr} ) | ||
133 | THUMB( ldmia r0!, {r1, r2, lr} ) | ||
134 | THUMB( mov sp, r2 ) | ||
135 | b cpu_do_resume | ||
136 | #endif | ||
137 | ENDPROC(cpu_resume) | 127 | ENDPROC(cpu_resume) |
138 | 128 | ||
139 | sleep_save_sp: | 129 | sleep_save_sp: |
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index e7f92a4321f3..167e3cbe1f2f 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
@@ -365,8 +365,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
365 | */ | 365 | */ |
366 | if (max_cpus > ncores) | 366 | if (max_cpus > ncores) |
367 | max_cpus = ncores; | 367 | max_cpus = ncores; |
368 | 368 | if (ncores > 1 && max_cpus) { | |
369 | if (max_cpus > 1) { | ||
370 | /* | 369 | /* |
371 | * Enable the local timer or broadcast device for the | 370 | * Enable the local timer or broadcast device for the |
372 | * boot CPU, but only if we have more than one CPU. | 371 | * boot CPU, but only if we have more than one CPU. |
@@ -374,6 +373,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
374 | percpu_timer_setup(); | 373 | percpu_timer_setup(); |
375 | 374 | ||
376 | /* | 375 | /* |
376 | * Initialise the present map, which describes the set of CPUs | ||
377 | * actually populated at the present time. A platform should | ||
378 | * re-initialize the map in platform_smp_prepare_cpus() if | ||
379 | * present != possible (e.g. physical hotplug). | ||
380 | */ | ||
381 | init_cpu_present(&cpu_possible_map); | ||
382 | |||
383 | /* | ||
377 | * Initialise the SCU if there are more than one CPU | 384 | * Initialise the SCU if there are more than one CPU |
378 | * and let them know where to start. | 385 | * and let them know where to start. |
379 | */ | 386 | */ |
diff --git a/arch/arm/kernel/smp_scu.c b/arch/arm/kernel/smp_scu.c index a1e757c3439b..79ed5e7f204a 100644 --- a/arch/arm/kernel/smp_scu.c +++ b/arch/arm/kernel/smp_scu.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #define SCU_INVALIDATE 0x0c | 20 | #define SCU_INVALIDATE 0x0c |
21 | #define SCU_FPGA_REVISION 0x10 | 21 | #define SCU_FPGA_REVISION 0x10 |
22 | 22 | ||
23 | #ifdef CONFIG_SMP | ||
23 | /* | 24 | /* |
24 | * Get the number of CPU cores from the SCU configuration | 25 | * Get the number of CPU cores from the SCU configuration |
25 | */ | 26 | */ |
@@ -50,6 +51,7 @@ void __init scu_enable(void __iomem *scu_base) | |||
50 | */ | 51 | */ |
51 | flush_cache_all(); | 52 | flush_cache_all(); |
52 | } | 53 | } |
54 | #endif | ||
53 | 55 | ||
54 | /* | 56 | /* |
55 | * Set the executing CPUs power mode as defined. This will be in | 57 | * Set the executing CPUs power mode as defined. This will be in |
diff --git a/arch/arm/kernel/smp_twd.c b/arch/arm/kernel/smp_twd.c index 60636f499cb3..2c277d40cee6 100644 --- a/arch/arm/kernel/smp_twd.c +++ b/arch/arm/kernel/smp_twd.c | |||
@@ -115,7 +115,7 @@ static void __cpuinit twd_calibrate_rate(void) | |||
115 | twd_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5); | 115 | twd_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5); |
116 | 116 | ||
117 | printk("%lu.%02luMHz.\n", twd_timer_rate / 1000000, | 117 | printk("%lu.%02luMHz.\n", twd_timer_rate / 1000000, |
118 | (twd_timer_rate / 1000000) % 100); | 118 | (twd_timer_rate / 10000) % 100); |
119 | } | 119 | } |
120 | } | 120 | } |
121 | 121 | ||
diff --git a/arch/arm/kernel/tcm.c b/arch/arm/kernel/tcm.c index f5cf660eefcc..30e302d33e0a 100644 --- a/arch/arm/kernel/tcm.c +++ b/arch/arm/kernel/tcm.c | |||
@@ -19,6 +19,8 @@ | |||
19 | #include "tcm.h" | 19 | #include "tcm.h" |
20 | 20 | ||
21 | static struct gen_pool *tcm_pool; | 21 | static struct gen_pool *tcm_pool; |
22 | static bool dtcm_present; | ||
23 | static bool itcm_present; | ||
22 | 24 | ||
23 | /* TCM section definitions from the linker */ | 25 | /* TCM section definitions from the linker */ |
24 | extern char __itcm_start, __sitcm_text, __eitcm_text; | 26 | extern char __itcm_start, __sitcm_text, __eitcm_text; |
@@ -90,6 +92,18 @@ void tcm_free(void *addr, size_t len) | |||
90 | } | 92 | } |
91 | EXPORT_SYMBOL(tcm_free); | 93 | EXPORT_SYMBOL(tcm_free); |
92 | 94 | ||
95 | bool tcm_dtcm_present(void) | ||
96 | { | ||
97 | return dtcm_present; | ||
98 | } | ||
99 | EXPORT_SYMBOL(tcm_dtcm_present); | ||
100 | |||
101 | bool tcm_itcm_present(void) | ||
102 | { | ||
103 | return itcm_present; | ||
104 | } | ||
105 | EXPORT_SYMBOL(tcm_itcm_present); | ||
106 | |||
93 | static int __init setup_tcm_bank(u8 type, u8 bank, u8 banks, | 107 | static int __init setup_tcm_bank(u8 type, u8 bank, u8 banks, |
94 | u32 *offset) | 108 | u32 *offset) |
95 | { | 109 | { |
@@ -134,6 +148,10 @@ static int __init setup_tcm_bank(u8 type, u8 bank, u8 banks, | |||
134 | (tcm_region & 1) ? "" : "not "); | 148 | (tcm_region & 1) ? "" : "not "); |
135 | } | 149 | } |
136 | 150 | ||
151 | /* Not much fun you can do with a size 0 bank */ | ||
152 | if (tcm_size == 0) | ||
153 | return 0; | ||
154 | |||
137 | /* Force move the TCM bank to where we want it, enable */ | 155 | /* Force move the TCM bank to where we want it, enable */ |
138 | tcm_region = *offset | (tcm_region & 0x00000ffeU) | 1; | 156 | tcm_region = *offset | (tcm_region & 0x00000ffeU) | 1; |
139 | 157 | ||
@@ -165,12 +183,20 @@ void __init tcm_init(void) | |||
165 | u32 tcm_status = read_cpuid_tcmstatus(); | 183 | u32 tcm_status = read_cpuid_tcmstatus(); |
166 | u8 dtcm_banks = (tcm_status >> 16) & 0x03; | 184 | u8 dtcm_banks = (tcm_status >> 16) & 0x03; |
167 | u8 itcm_banks = (tcm_status & 0x03); | 185 | u8 itcm_banks = (tcm_status & 0x03); |
186 | size_t dtcm_code_sz = &__edtcm_data - &__sdtcm_data; | ||
187 | size_t itcm_code_sz = &__eitcm_text - &__sitcm_text; | ||
168 | char *start; | 188 | char *start; |
169 | char *end; | 189 | char *end; |
170 | char *ram; | 190 | char *ram; |
171 | int ret; | 191 | int ret; |
172 | int i; | 192 | int i; |
173 | 193 | ||
194 | /* Values greater than 2 for D/ITCM banks are "reserved" */ | ||
195 | if (dtcm_banks > 2) | ||
196 | dtcm_banks = 0; | ||
197 | if (itcm_banks > 2) | ||
198 | itcm_banks = 0; | ||
199 | |||
174 | /* Setup DTCM if present */ | 200 | /* Setup DTCM if present */ |
175 | if (dtcm_banks > 0) { | 201 | if (dtcm_banks > 0) { |
176 | for (i = 0; i < dtcm_banks; i++) { | 202 | for (i = 0; i < dtcm_banks; i++) { |
@@ -178,6 +204,13 @@ void __init tcm_init(void) | |||
178 | if (ret) | 204 | if (ret) |
179 | return; | 205 | return; |
180 | } | 206 | } |
207 | /* This means you compiled more code than fits into DTCM */ | ||
208 | if (dtcm_code_sz > (dtcm_end - DTCM_OFFSET)) { | ||
209 | pr_info("CPU DTCM: %u bytes of code compiled to " | ||
210 | "DTCM but only %lu bytes of DTCM present\n", | ||
211 | dtcm_code_sz, (dtcm_end - DTCM_OFFSET)); | ||
212 | goto no_dtcm; | ||
213 | } | ||
181 | dtcm_res.end = dtcm_end - 1; | 214 | dtcm_res.end = dtcm_end - 1; |
182 | request_resource(&iomem_resource, &dtcm_res); | 215 | request_resource(&iomem_resource, &dtcm_res); |
183 | dtcm_iomap[0].length = dtcm_end - DTCM_OFFSET; | 216 | dtcm_iomap[0].length = dtcm_end - DTCM_OFFSET; |
@@ -186,12 +219,16 @@ void __init tcm_init(void) | |||
186 | start = &__sdtcm_data; | 219 | start = &__sdtcm_data; |
187 | end = &__edtcm_data; | 220 | end = &__edtcm_data; |
188 | ram = &__dtcm_start; | 221 | ram = &__dtcm_start; |
189 | /* This means you compiled more code than fits into DTCM */ | 222 | memcpy(start, ram, dtcm_code_sz); |
190 | BUG_ON((end - start) > (dtcm_end - DTCM_OFFSET)); | 223 | pr_debug("CPU DTCM: copied data from %p - %p\n", |
191 | memcpy(start, ram, (end-start)); | 224 | start, end); |
192 | pr_debug("CPU DTCM: copied data from %p - %p\n", start, end); | 225 | dtcm_present = true; |
226 | } else if (dtcm_code_sz) { | ||
227 | pr_info("CPU DTCM: %u bytes of code compiled to DTCM but no " | ||
228 | "DTCM banks present in CPU\n", dtcm_code_sz); | ||
193 | } | 229 | } |
194 | 230 | ||
231 | no_dtcm: | ||
195 | /* Setup ITCM if present */ | 232 | /* Setup ITCM if present */ |
196 | if (itcm_banks > 0) { | 233 | if (itcm_banks > 0) { |
197 | for (i = 0; i < itcm_banks; i++) { | 234 | for (i = 0; i < itcm_banks; i++) { |
@@ -199,6 +236,13 @@ void __init tcm_init(void) | |||
199 | if (ret) | 236 | if (ret) |
200 | return; | 237 | return; |
201 | } | 238 | } |
239 | /* This means you compiled more code than fits into ITCM */ | ||
240 | if (itcm_code_sz > (itcm_end - ITCM_OFFSET)) { | ||
241 | pr_info("CPU ITCM: %u bytes of code compiled to " | ||
242 | "ITCM but only %lu bytes of ITCM present\n", | ||
243 | itcm_code_sz, (itcm_end - ITCM_OFFSET)); | ||
244 | return; | ||
245 | } | ||
202 | itcm_res.end = itcm_end - 1; | 246 | itcm_res.end = itcm_end - 1; |
203 | request_resource(&iomem_resource, &itcm_res); | 247 | request_resource(&iomem_resource, &itcm_res); |
204 | itcm_iomap[0].length = itcm_end - ITCM_OFFSET; | 248 | itcm_iomap[0].length = itcm_end - ITCM_OFFSET; |
@@ -207,10 +251,13 @@ void __init tcm_init(void) | |||
207 | start = &__sitcm_text; | 251 | start = &__sitcm_text; |
208 | end = &__eitcm_text; | 252 | end = &__eitcm_text; |
209 | ram = &__itcm_start; | 253 | ram = &__itcm_start; |
210 | /* This means you compiled more code than fits into ITCM */ | 254 | memcpy(start, ram, itcm_code_sz); |
211 | BUG_ON((end - start) > (itcm_end - ITCM_OFFSET)); | 255 | pr_debug("CPU ITCM: copied code from %p - %p\n", |
212 | memcpy(start, ram, (end-start)); | 256 | start, end); |
213 | pr_debug("CPU ITCM: copied code from %p - %p\n", start, end); | 257 | itcm_present = true; |
258 | } else if (itcm_code_sz) { | ||
259 | pr_info("CPU ITCM: %u bytes of code compiled to ITCM but no " | ||
260 | "ITCM banks present in CPU\n", itcm_code_sz); | ||
214 | } | 261 | } |
215 | } | 262 | } |
216 | 263 | ||
@@ -221,7 +268,6 @@ void __init tcm_init(void) | |||
221 | */ | 268 | */ |
222 | static int __init setup_tcm_pool(void) | 269 | static int __init setup_tcm_pool(void) |
223 | { | 270 | { |
224 | u32 tcm_status = read_cpuid_tcmstatus(); | ||
225 | u32 dtcm_pool_start = (u32) &__edtcm_data; | 271 | u32 dtcm_pool_start = (u32) &__edtcm_data; |
226 | u32 itcm_pool_start = (u32) &__eitcm_text; | 272 | u32 itcm_pool_start = (u32) &__eitcm_text; |
227 | int ret; | 273 | int ret; |
@@ -236,7 +282,7 @@ static int __init setup_tcm_pool(void) | |||
236 | pr_debug("Setting up TCM memory pool\n"); | 282 | pr_debug("Setting up TCM memory pool\n"); |
237 | 283 | ||
238 | /* Add the rest of DTCM to the TCM pool */ | 284 | /* Add the rest of DTCM to the TCM pool */ |
239 | if (tcm_status & (0x03 << 16)) { | 285 | if (dtcm_present) { |
240 | if (dtcm_pool_start < dtcm_end) { | 286 | if (dtcm_pool_start < dtcm_end) { |
241 | ret = gen_pool_add(tcm_pool, dtcm_pool_start, | 287 | ret = gen_pool_add(tcm_pool, dtcm_pool_start, |
242 | dtcm_end - dtcm_pool_start, -1); | 288 | dtcm_end - dtcm_pool_start, -1); |
@@ -253,7 +299,7 @@ static int __init setup_tcm_pool(void) | |||
253 | } | 299 | } |
254 | 300 | ||
255 | /* Add the rest of ITCM to the TCM pool */ | 301 | /* Add the rest of ITCM to the TCM pool */ |
256 | if (tcm_status & 0x03) { | 302 | if (itcm_present) { |
257 | if (itcm_pool_start < itcm_end) { | 303 | if (itcm_pool_start < itcm_end) { |
258 | ret = gen_pool_add(tcm_pool, itcm_pool_start, | 304 | ret = gen_pool_add(tcm_pool, itcm_pool_start, |
259 | itcm_end - itcm_pool_start, -1); | 305 | itcm_end - itcm_pool_start, -1); |
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index e5287f21badc..bf977f8514f6 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S | |||
@@ -38,57 +38,6 @@ jiffies = jiffies_64 + 4; | |||
38 | 38 | ||
39 | SECTIONS | 39 | SECTIONS |
40 | { | 40 | { |
41 | #ifdef CONFIG_XIP_KERNEL | ||
42 | . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR); | ||
43 | #else | ||
44 | . = PAGE_OFFSET + TEXT_OFFSET; | ||
45 | #endif | ||
46 | |||
47 | .init : { /* Init code and data */ | ||
48 | _stext = .; | ||
49 | _sinittext = .; | ||
50 | HEAD_TEXT | ||
51 | INIT_TEXT | ||
52 | ARM_EXIT_KEEP(EXIT_TEXT) | ||
53 | _einittext = .; | ||
54 | ARM_CPU_DISCARD(PROC_INFO) | ||
55 | __arch_info_begin = .; | ||
56 | *(.arch.info.init) | ||
57 | __arch_info_end = .; | ||
58 | __tagtable_begin = .; | ||
59 | *(.taglist.init) | ||
60 | __tagtable_end = .; | ||
61 | #ifdef CONFIG_SMP_ON_UP | ||
62 | __smpalt_begin = .; | ||
63 | *(.alt.smp.init) | ||
64 | __smpalt_end = .; | ||
65 | #endif | ||
66 | |||
67 | __pv_table_begin = .; | ||
68 | *(.pv_table) | ||
69 | __pv_table_end = .; | ||
70 | |||
71 | INIT_SETUP(16) | ||
72 | |||
73 | INIT_CALLS | ||
74 | CON_INITCALL | ||
75 | SECURITY_INITCALL | ||
76 | INIT_RAM_FS | ||
77 | |||
78 | #ifndef CONFIG_XIP_KERNEL | ||
79 | __init_begin = _stext; | ||
80 | INIT_DATA | ||
81 | ARM_EXIT_KEEP(EXIT_DATA) | ||
82 | #endif | ||
83 | } | ||
84 | |||
85 | PERCPU_SECTION(32) | ||
86 | |||
87 | #ifndef CONFIG_XIP_KERNEL | ||
88 | . = ALIGN(PAGE_SIZE); | ||
89 | __init_end = .; | ||
90 | #endif | ||
91 | |||
92 | /* | 41 | /* |
93 | * unwind exit sections must be discarded before the rest of the | 42 | * unwind exit sections must be discarded before the rest of the |
94 | * unwind sections get included. | 43 | * unwind sections get included. |
@@ -106,10 +55,22 @@ SECTIONS | |||
106 | *(.fixup) | 55 | *(.fixup) |
107 | *(__ex_table) | 56 | *(__ex_table) |
108 | #endif | 57 | #endif |
58 | #ifndef CONFIG_SMP_ON_UP | ||
59 | *(.alt.smp.init) | ||
60 | #endif | ||
109 | } | 61 | } |
110 | 62 | ||
63 | #ifdef CONFIG_XIP_KERNEL | ||
64 | . = XIP_VIRT_ADDR(CONFIG_XIP_PHYS_ADDR); | ||
65 | #else | ||
66 | . = PAGE_OFFSET + TEXT_OFFSET; | ||
67 | #endif | ||
68 | .head.text : { | ||
69 | _text = .; | ||
70 | HEAD_TEXT | ||
71 | } | ||
111 | .text : { /* Real text segment */ | 72 | .text : { /* Real text segment */ |
112 | _text = .; /* Text and read-only data */ | 73 | _stext = .; /* Text and read-only data */ |
113 | __exception_text_start = .; | 74 | __exception_text_start = .; |
114 | *(.exception.text) | 75 | *(.exception.text) |
115 | __exception_text_end = .; | 76 | __exception_text_end = .; |
@@ -122,8 +83,6 @@ SECTIONS | |||
122 | *(.fixup) | 83 | *(.fixup) |
123 | #endif | 84 | #endif |
124 | *(.gnu.warning) | 85 | *(.gnu.warning) |
125 | *(.rodata) | ||
126 | *(.rodata.*) | ||
127 | *(.glue_7) | 86 | *(.glue_7) |
128 | *(.glue_7t) | 87 | *(.glue_7t) |
129 | . = ALIGN(4); | 88 | . = ALIGN(4); |
@@ -152,10 +111,63 @@ SECTIONS | |||
152 | 111 | ||
153 | _etext = .; /* End of text and rodata section */ | 112 | _etext = .; /* End of text and rodata section */ |
154 | 113 | ||
114 | #ifndef CONFIG_XIP_KERNEL | ||
115 | . = ALIGN(PAGE_SIZE); | ||
116 | __init_begin = .; | ||
117 | #endif | ||
118 | |||
119 | INIT_TEXT_SECTION(8) | ||
120 | .exit.text : { | ||
121 | ARM_EXIT_KEEP(EXIT_TEXT) | ||
122 | } | ||
123 | .init.proc.info : { | ||
124 | ARM_CPU_DISCARD(PROC_INFO) | ||
125 | } | ||
126 | .init.arch.info : { | ||
127 | __arch_info_begin = .; | ||
128 | *(.arch.info.init) | ||
129 | __arch_info_end = .; | ||
130 | } | ||
131 | .init.tagtable : { | ||
132 | __tagtable_begin = .; | ||
133 | *(.taglist.init) | ||
134 | __tagtable_end = .; | ||
135 | } | ||
136 | #ifdef CONFIG_SMP_ON_UP | ||
137 | .init.smpalt : { | ||
138 | __smpalt_begin = .; | ||
139 | *(.alt.smp.init) | ||
140 | __smpalt_end = .; | ||
141 | } | ||
142 | #endif | ||
143 | .init.pv_table : { | ||
144 | __pv_table_begin = .; | ||
145 | *(.pv_table) | ||
146 | __pv_table_end = .; | ||
147 | } | ||
148 | .init.data : { | ||
149 | #ifndef CONFIG_XIP_KERNEL | ||
150 | INIT_DATA | ||
151 | #endif | ||
152 | INIT_SETUP(16) | ||
153 | INIT_CALLS | ||
154 | CON_INITCALL | ||
155 | SECURITY_INITCALL | ||
156 | INIT_RAM_FS | ||
157 | } | ||
158 | #ifndef CONFIG_XIP_KERNEL | ||
159 | .exit.data : { | ||
160 | ARM_EXIT_KEEP(EXIT_DATA) | ||
161 | } | ||
162 | #endif | ||
163 | |||
164 | PERCPU_SECTION(32) | ||
165 | |||
155 | #ifdef CONFIG_XIP_KERNEL | 166 | #ifdef CONFIG_XIP_KERNEL |
156 | __data_loc = ALIGN(4); /* location in binary */ | 167 | __data_loc = ALIGN(4); /* location in binary */ |
157 | . = PAGE_OFFSET + TEXT_OFFSET; | 168 | . = PAGE_OFFSET + TEXT_OFFSET; |
158 | #else | 169 | #else |
170 | __init_end = .; | ||
159 | . = ALIGN(THREAD_SIZE); | 171 | . = ALIGN(THREAD_SIZE); |
160 | __data_loc = .; | 172 | __data_loc = .; |
161 | #endif | 173 | #endif |
@@ -270,12 +282,6 @@ SECTIONS | |||
270 | 282 | ||
271 | /* Default discards */ | 283 | /* Default discards */ |
272 | DISCARDS | 284 | DISCARDS |
273 | |||
274 | #ifndef CONFIG_SMP_ON_UP | ||
275 | /DISCARD/ : { | ||
276 | *(.alt.smp.init) | ||
277 | } | ||
278 | #endif | ||
279 | } | 285 | } |
280 | 286 | ||
281 | /* | 287 | /* |
diff --git a/arch/arm/mach-bcmring/include/mach/entry-macro.S b/arch/arm/mach-bcmring/include/mach/entry-macro.S index 7d393ca010ac..94c950d783ba 100644 --- a/arch/arm/mach-bcmring/include/mach/entry-macro.S +++ b/arch/arm/mach-bcmring/include/mach/entry-macro.S | |||
@@ -80,7 +80,3 @@ | |||
80 | 80 | ||
81 | .macro arch_ret_to_user, tmp1, tmp2 | 81 | .macro arch_ret_to_user, tmp1, tmp2 |
82 | .endm | 82 | .endm |
83 | |||
84 | .macro irq_prio_table | ||
85 | .endm | ||
86 | |||
diff --git a/arch/arm/mach-davinci/board-dm365-evm.c b/arch/arm/mach-davinci/board-dm365-evm.c index c67f684ee3e5..09a87e61ffcf 100644 --- a/arch/arm/mach-davinci/board-dm365-evm.c +++ b/arch/arm/mach-davinci/board-dm365-evm.c | |||
@@ -520,7 +520,7 @@ fail: | |||
520 | */ | 520 | */ |
521 | if (have_imager()) { | 521 | if (have_imager()) { |
522 | label = "HD imager"; | 522 | label = "HD imager"; |
523 | mux |= 1; | 523 | mux |= 2; |
524 | 524 | ||
525 | /* externally mux MMC1/ENET/AIC33 to imager */ | 525 | /* externally mux MMC1/ENET/AIC33 to imager */ |
526 | mux |= BIT(6) | BIT(5) | BIT(3); | 526 | mux |= BIT(6) | BIT(5) | BIT(3); |
@@ -540,7 +540,7 @@ fail: | |||
540 | resets &= ~BIT(1); | 540 | resets &= ~BIT(1); |
541 | 541 | ||
542 | if (have_tvp7002()) { | 542 | if (have_tvp7002()) { |
543 | mux |= 2; | 543 | mux |= 1; |
544 | resets &= ~BIT(2); | 544 | resets &= ~BIT(2); |
545 | label = "tvp7002 HD"; | 545 | label = "tvp7002 HD"; |
546 | } else { | 546 | } else { |
diff --git a/arch/arm/mach-davinci/gpio.c b/arch/arm/mach-davinci/gpio.c index e7221398e5af..cafbe13a82a5 100644 --- a/arch/arm/mach-davinci/gpio.c +++ b/arch/arm/mach-davinci/gpio.c | |||
@@ -254,8 +254,10 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc) | |||
254 | { | 254 | { |
255 | struct davinci_gpio_regs __iomem *g; | 255 | struct davinci_gpio_regs __iomem *g; |
256 | u32 mask = 0xffff; | 256 | u32 mask = 0xffff; |
257 | struct davinci_gpio_controller *d; | ||
257 | 258 | ||
258 | g = (__force struct davinci_gpio_regs __iomem *) irq_desc_get_handler_data(desc); | 259 | d = (struct davinci_gpio_controller *)irq_desc_get_handler_data(desc); |
260 | g = (struct davinci_gpio_regs __iomem *)d->regs; | ||
259 | 261 | ||
260 | /* we only care about one bank */ | 262 | /* we only care about one bank */ |
261 | if (irq & 1) | 263 | if (irq & 1) |
@@ -274,11 +276,14 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc) | |||
274 | if (!status) | 276 | if (!status) |
275 | break; | 277 | break; |
276 | __raw_writel(status, &g->intstat); | 278 | __raw_writel(status, &g->intstat); |
277 | if (irq & 1) | ||
278 | status >>= 16; | ||
279 | 279 | ||
280 | /* now demux them to the right lowlevel handler */ | 280 | /* now demux them to the right lowlevel handler */ |
281 | n = (int)irq_get_handler_data(irq); | 281 | n = d->irq_base; |
282 | if (irq & 1) { | ||
283 | n += 16; | ||
284 | status >>= 16; | ||
285 | } | ||
286 | |||
282 | while (status) { | 287 | while (status) { |
283 | res = ffs(status); | 288 | res = ffs(status); |
284 | n += res; | 289 | n += res; |
@@ -424,7 +429,13 @@ static int __init davinci_gpio_irq_setup(void) | |||
424 | 429 | ||
425 | /* set up all irqs in this bank */ | 430 | /* set up all irqs in this bank */ |
426 | irq_set_chained_handler(bank_irq, gpio_irq_handler); | 431 | irq_set_chained_handler(bank_irq, gpio_irq_handler); |
427 | irq_set_handler_data(bank_irq, (__force void *)g); | 432 | |
433 | /* | ||
434 | * Each chip handles 32 gpios, and each irq bank consists of 16 | ||
435 | * gpio irqs. Pass the irq bank's corresponding controller to | ||
436 | * the chained irq handler. | ||
437 | */ | ||
438 | irq_set_handler_data(bank_irq, &chips[gpio / 32]); | ||
428 | 439 | ||
429 | for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) { | 440 | for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) { |
430 | irq_set_chip(irq, &gpio_irqchip); | 441 | irq_set_chip(irq, &gpio_irqchip); |
diff --git a/arch/arm/mach-davinci/include/mach/entry-macro.S b/arch/arm/mach-davinci/include/mach/entry-macro.S index fbdebc7cb409..e14c0dc0e12c 100644 --- a/arch/arm/mach-davinci/include/mach/entry-macro.S +++ b/arch/arm/mach-davinci/include/mach/entry-macro.S | |||
@@ -46,6 +46,3 @@ | |||
46 | #endif | 46 | #endif |
47 | 1002: | 47 | 1002: |
48 | .endm | 48 | .endm |
49 | |||
50 | .macro irq_prio_table | ||
51 | .endm | ||
diff --git a/arch/arm/mach-davinci/irq.c b/arch/arm/mach-davinci/irq.c index bfe68ec4e1a6..952dc126c390 100644 --- a/arch/arm/mach-davinci/irq.c +++ b/arch/arm/mach-davinci/irq.c | |||
@@ -52,8 +52,14 @@ davinci_alloc_gc(void __iomem *base, unsigned int irq_start, unsigned int num) | |||
52 | struct irq_chip_type *ct; | 52 | struct irq_chip_type *ct; |
53 | 53 | ||
54 | gc = irq_alloc_generic_chip("AINTC", 1, irq_start, base, handle_edge_irq); | 54 | gc = irq_alloc_generic_chip("AINTC", 1, irq_start, base, handle_edge_irq); |
55 | if (!gc) { | ||
56 | pr_err("%s: irq_alloc_generic_chip for IRQ %u failed\n", | ||
57 | __func__, irq_start); | ||
58 | return; | ||
59 | } | ||
60 | |||
55 | ct = gc->chip_types; | 61 | ct = gc->chip_types; |
56 | ct->chip.irq_ack = irq_gc_ack; | 62 | ct->chip.irq_ack = irq_gc_ack_set_bit; |
57 | ct->chip.irq_mask = irq_gc_mask_clr_bit; | 63 | ct->chip.irq_mask = irq_gc_mask_clr_bit; |
58 | ct->chip.irq_unmask = irq_gc_mask_set_bit; | 64 | ct->chip.irq_unmask = irq_gc_mask_set_bit; |
59 | 65 | ||
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c index 1d4b65fd673e..6659a0d137a3 100644 --- a/arch/arm/mach-ep93xx/core.c +++ b/arch/arm/mach-ep93xx/core.c | |||
@@ -251,9 +251,9 @@ static void ep93xx_uart_set_mctrl(struct amba_device *dev, | |||
251 | unsigned int mcr; | 251 | unsigned int mcr; |
252 | 252 | ||
253 | mcr = 0; | 253 | mcr = 0; |
254 | if (!(mctrl & TIOCM_RTS)) | 254 | if (mctrl & TIOCM_RTS) |
255 | mcr |= 2; | 255 | mcr |= 2; |
256 | if (!(mctrl & TIOCM_DTR)) | 256 | if (mctrl & TIOCM_DTR) |
257 | mcr |= 1; | 257 | mcr |= 1; |
258 | 258 | ||
259 | __raw_writel(mcr, base + EP93XX_UART_MCR_OFFSET); | 259 | __raw_writel(mcr, base + EP93XX_UART_MCR_OFFSET); |
diff --git a/arch/arm/mach-exynos4/cpu.c b/arch/arm/mach-exynos4/cpu.c index 9babe4473e88..bfd621460abf 100644 --- a/arch/arm/mach-exynos4/cpu.c +++ b/arch/arm/mach-exynos4/cpu.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <plat/sdhci.h> | 23 | #include <plat/sdhci.h> |
24 | #include <plat/devs.h> | 24 | #include <plat/devs.h> |
25 | #include <plat/fimc-core.h> | 25 | #include <plat/fimc-core.h> |
26 | #include <plat/iic-core.h> | ||
26 | 27 | ||
27 | #include <mach/regs-irq.h> | 28 | #include <mach/regs-irq.h> |
28 | 29 | ||
@@ -132,6 +133,11 @@ void __init exynos4_map_io(void) | |||
132 | s3c_fimc_setname(1, "exynos4-fimc"); | 133 | s3c_fimc_setname(1, "exynos4-fimc"); |
133 | s3c_fimc_setname(2, "exynos4-fimc"); | 134 | s3c_fimc_setname(2, "exynos4-fimc"); |
134 | s3c_fimc_setname(3, "exynos4-fimc"); | 135 | s3c_fimc_setname(3, "exynos4-fimc"); |
136 | |||
137 | /* The I2C bus controllers are directly compatible with s3c2440 */ | ||
138 | s3c_i2c0_setname("s3c2440-i2c"); | ||
139 | s3c_i2c1_setname("s3c2440-i2c"); | ||
140 | s3c_i2c2_setname("s3c2440-i2c"); | ||
135 | } | 141 | } |
136 | 142 | ||
137 | void __init exynos4_init_clocks(int xtal) | 143 | void __init exynos4_init_clocks(int xtal) |
diff --git a/arch/arm/mach-exynos4/dev-audio.c b/arch/arm/mach-exynos4/dev-audio.c index 1eed5f9f7bd3..983069a53239 100644 --- a/arch/arm/mach-exynos4/dev-audio.c +++ b/arch/arm/mach-exynos4/dev-audio.c | |||
@@ -330,7 +330,7 @@ struct platform_device exynos4_device_ac97 = { | |||
330 | 330 | ||
331 | static int exynos4_spdif_cfg_gpio(struct platform_device *pdev) | 331 | static int exynos4_spdif_cfg_gpio(struct platform_device *pdev) |
332 | { | 332 | { |
333 | s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 2, S3C_GPIO_SFN(3)); | 333 | s3c_gpio_cfgpin_range(EXYNOS4_GPC1(0), 2, S3C_GPIO_SFN(4)); |
334 | 334 | ||
335 | return 0; | 335 | return 0; |
336 | } | 336 | } |
diff --git a/arch/arm/mach-exynos4/headsmp.S b/arch/arm/mach-exynos4/headsmp.S index 6c6cfc50c46b..3cdeb3647542 100644 --- a/arch/arm/mach-exynos4/headsmp.S +++ b/arch/arm/mach-exynos4/headsmp.S | |||
@@ -13,7 +13,7 @@ | |||
13 | #include <linux/linkage.h> | 13 | #include <linux/linkage.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | 15 | ||
16 | __INIT | 16 | __CPUINIT |
17 | 17 | ||
18 | /* | 18 | /* |
19 | * exynos4 specific entry point for secondary CPUs. This provides | 19 | * exynos4 specific entry point for secondary CPUs. This provides |
diff --git a/arch/arm/mach-exynos4/mach-smdkv310.c b/arch/arm/mach-exynos4/mach-smdkv310.c index 152676471b67..edd814110da8 100644 --- a/arch/arm/mach-exynos4/mach-smdkv310.c +++ b/arch/arm/mach-exynos4/mach-smdkv310.c | |||
@@ -78,9 +78,7 @@ static struct s3c2410_uartcfg smdkv310_uartcfgs[] __initdata = { | |||
78 | }; | 78 | }; |
79 | 79 | ||
80 | static struct s3c_sdhci_platdata smdkv310_hsmmc0_pdata __initdata = { | 80 | static struct s3c_sdhci_platdata smdkv310_hsmmc0_pdata __initdata = { |
81 | .cd_type = S3C_SDHCI_CD_GPIO, | 81 | .cd_type = S3C_SDHCI_CD_INTERNAL, |
82 | .ext_cd_gpio = EXYNOS4_GPK0(2), | ||
83 | .ext_cd_gpio_invert = 1, | ||
84 | .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, | 82 | .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, |
85 | #ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT | 83 | #ifdef CONFIG_EXYNOS4_SDHCI_CH0_8BIT |
86 | .max_width = 8, | 84 | .max_width = 8, |
@@ -96,9 +94,7 @@ static struct s3c_sdhci_platdata smdkv310_hsmmc1_pdata __initdata = { | |||
96 | }; | 94 | }; |
97 | 95 | ||
98 | static struct s3c_sdhci_platdata smdkv310_hsmmc2_pdata __initdata = { | 96 | static struct s3c_sdhci_platdata smdkv310_hsmmc2_pdata __initdata = { |
99 | .cd_type = S3C_SDHCI_CD_GPIO, | 97 | .cd_type = S3C_SDHCI_CD_INTERNAL, |
100 | .ext_cd_gpio = EXYNOS4_GPK2(2), | ||
101 | .ext_cd_gpio_invert = 1, | ||
102 | .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, | 98 | .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, |
103 | #ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT | 99 | #ifdef CONFIG_EXYNOS4_SDHCI_CH2_8BIT |
104 | .max_width = 8, | 100 | .max_width = 8, |
diff --git a/arch/arm/mach-exynos4/platsmp.c b/arch/arm/mach-exynos4/platsmp.c index c5e65a02be8d..b68d5bdf04cf 100644 --- a/arch/arm/mach-exynos4/platsmp.c +++ b/arch/arm/mach-exynos4/platsmp.c | |||
@@ -154,14 +154,6 @@ void __init smp_init_cpus(void) | |||
154 | 154 | ||
155 | void __init platform_smp_prepare_cpus(unsigned int max_cpus) | 155 | void __init platform_smp_prepare_cpus(unsigned int max_cpus) |
156 | { | 156 | { |
157 | int i; | ||
158 | |||
159 | /* | ||
160 | * Initialise the present map, which describes the set of CPUs | ||
161 | * actually populated at the present time. | ||
162 | */ | ||
163 | for (i = 0; i < max_cpus; i++) | ||
164 | set_cpu_present(i, true); | ||
165 | 157 | ||
166 | scu_enable(scu_base_addr()); | 158 | scu_enable(scu_base_addr()); |
167 | 159 | ||
diff --git a/arch/arm/mach-exynos4/pm.c b/arch/arm/mach-exynos4/pm.c index 8755ca8dd48d..533c28f758ca 100644 --- a/arch/arm/mach-exynos4/pm.c +++ b/arch/arm/mach-exynos4/pm.c | |||
@@ -280,7 +280,7 @@ static struct sleep_save exynos4_l2cc_save[] = { | |||
280 | SAVE_ITEM(S5P_VA_L2CC + L2X0_AUX_CTRL), | 280 | SAVE_ITEM(S5P_VA_L2CC + L2X0_AUX_CTRL), |
281 | }; | 281 | }; |
282 | 282 | ||
283 | void exynos4_cpu_suspend(void) | 283 | static int exynos4_cpu_suspend(unsigned long arg) |
284 | { | 284 | { |
285 | unsigned long tmp; | 285 | unsigned long tmp; |
286 | unsigned long mask = 0xFFFFFFFF; | 286 | unsigned long mask = 0xFFFFFFFF; |
diff --git a/arch/arm/mach-exynos4/sleep.S b/arch/arm/mach-exynos4/sleep.S index 6b62425417a6..0984078f1eba 100644 --- a/arch/arm/mach-exynos4/sleep.S +++ b/arch/arm/mach-exynos4/sleep.S | |||
@@ -33,28 +33,6 @@ | |||
33 | .text | 33 | .text |
34 | 34 | ||
35 | /* | 35 | /* |
36 | * s3c_cpu_save | ||
37 | * | ||
38 | * entry: | ||
39 | * r1 = v:p offset | ||
40 | */ | ||
41 | |||
42 | ENTRY(s3c_cpu_save) | ||
43 | |||
44 | stmfd sp!, { r3 - r12, lr } | ||
45 | ldr r3, =resume_with_mmu | ||
46 | bl cpu_suspend | ||
47 | |||
48 | ldr r0, =pm_cpu_sleep | ||
49 | ldr r0, [ r0 ] | ||
50 | mov pc, r0 | ||
51 | |||
52 | resume_with_mmu: | ||
53 | ldmfd sp!, { r3 - r12, pc } | ||
54 | |||
55 | .ltorg | ||
56 | |||
57 | /* | ||
58 | * sleep magic, to allow the bootloader to check for an valid | 36 | * sleep magic, to allow the bootloader to check for an valid |
59 | * image to resume to. Must be the first word before the | 37 | * image to resume to. Must be the first word before the |
60 | * s3c_cpu_resume entry. | 38 | * s3c_cpu_resume entry. |
diff --git a/arch/arm/mach-h720x/include/mach/entry-macro.S b/arch/arm/mach-h720x/include/mach/entry-macro.S index 6d3b917c4a18..c3948e5ba4a0 100644 --- a/arch/arm/mach-h720x/include/mach/entry-macro.S +++ b/arch/arm/mach-h720x/include/mach/entry-macro.S | |||
@@ -57,9 +57,6 @@ | |||
57 | tst \irqstat, #1 @ bit 0 should be set | 57 | tst \irqstat, #1 @ bit 0 should be set |
58 | .endm | 58 | .endm |
59 | 59 | ||
60 | .macro irq_prio_table | ||
61 | .endm | ||
62 | |||
63 | #else | 60 | #else |
64 | #error hynix processor selection missmatch | 61 | #error hynix processor selection missmatch |
65 | #endif | 62 | #endif |
diff --git a/arch/arm/mach-ixp4xx/common-pci.c b/arch/arm/mach-ixp4xx/common-pci.c index e9a589395723..e2e98bbb6413 100644 --- a/arch/arm/mach-ixp4xx/common-pci.c +++ b/arch/arm/mach-ixp4xx/common-pci.c | |||
@@ -316,6 +316,11 @@ static int abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *r | |||
316 | } | 316 | } |
317 | 317 | ||
318 | 318 | ||
319 | static int ixp4xx_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) | ||
320 | { | ||
321 | return (dma_addr + size) >= SZ_64M; | ||
322 | } | ||
323 | |||
319 | /* | 324 | /* |
320 | * Setup DMA mask to 64MB on PCI devices. Ignore all other devices. | 325 | * Setup DMA mask to 64MB on PCI devices. Ignore all other devices. |
321 | */ | 326 | */ |
@@ -324,7 +329,7 @@ static int ixp4xx_pci_platform_notify(struct device *dev) | |||
324 | if(dev->bus == &pci_bus_type) { | 329 | if(dev->bus == &pci_bus_type) { |
325 | *dev->dma_mask = SZ_64M - 1; | 330 | *dev->dma_mask = SZ_64M - 1; |
326 | dev->coherent_dma_mask = SZ_64M - 1; | 331 | dev->coherent_dma_mask = SZ_64M - 1; |
327 | dmabounce_register_dev(dev, 2048, 4096); | 332 | dmabounce_register_dev(dev, 2048, 4096, ixp4xx_needs_bounce); |
328 | } | 333 | } |
329 | return 0; | 334 | return 0; |
330 | } | 335 | } |
@@ -337,11 +342,6 @@ static int ixp4xx_pci_platform_notify_remove(struct device *dev) | |||
337 | return 0; | 342 | return 0; |
338 | } | 343 | } |
339 | 344 | ||
340 | int dma_needs_bounce(struct device *dev, dma_addr_t dma_addr, size_t size) | ||
341 | { | ||
342 | return (dev->bus == &pci_bus_type ) && ((dma_addr + size) >= SZ_64M); | ||
343 | } | ||
344 | |||
345 | void __init ixp4xx_pci_preinit(void) | 345 | void __init ixp4xx_pci_preinit(void) |
346 | { | 346 | { |
347 | unsigned long cpuid = read_cpuid_id(); | 347 | unsigned long cpuid = read_cpuid_id(); |
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 74ed81a3cb1a..07772575d7ab 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c | |||
@@ -419,14 +419,20 @@ static void notrace ixp4xx_update_sched_clock(void) | |||
419 | /* | 419 | /* |
420 | * clocksource | 420 | * clocksource |
421 | */ | 421 | */ |
422 | |||
423 | static cycle_t ixp4xx_clocksource_read(struct clocksource *c) | ||
424 | { | ||
425 | return *IXP4XX_OSTS; | ||
426 | } | ||
427 | |||
422 | unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ; | 428 | unsigned long ixp4xx_timer_freq = IXP4XX_TIMER_FREQ; |
423 | EXPORT_SYMBOL(ixp4xx_timer_freq); | 429 | EXPORT_SYMBOL(ixp4xx_timer_freq); |
424 | static void __init ixp4xx_clocksource_init(void) | 430 | static void __init ixp4xx_clocksource_init(void) |
425 | { | 431 | { |
426 | init_sched_clock(&cd, ixp4xx_update_sched_clock, 32, ixp4xx_timer_freq); | 432 | init_sched_clock(&cd, ixp4xx_update_sched_clock, 32, ixp4xx_timer_freq); |
427 | 433 | ||
428 | clocksource_mmio_init(&IXP4XX_OSTS, "OSTS", ixp4xx_timer_freq, 200, 32, | 434 | clocksource_mmio_init(NULL, "OSTS", ixp4xx_timer_freq, 200, 32, |
429 | clocksource_mmio_readl_up); | 435 | ixp4xx_clocksource_read); |
430 | } | 436 | } |
431 | 437 | ||
432 | /* | 438 | /* |
diff --git a/arch/arm/mach-lpc32xx/include/mach/entry-macro.S b/arch/arm/mach-lpc32xx/include/mach/entry-macro.S index 870227c96602..b725f6c93975 100644 --- a/arch/arm/mach-lpc32xx/include/mach/entry-macro.S +++ b/arch/arm/mach-lpc32xx/include/mach/entry-macro.S | |||
@@ -41,7 +41,3 @@ | |||
41 | rsb \irqnr, \irqnr, #31 | 41 | rsb \irqnr, \irqnr, #31 |
42 | teq \irqstat, #0 | 42 | teq \irqstat, #0 |
43 | .endm | 43 | .endm |
44 | |||
45 | .macro irq_prio_table | ||
46 | .endm | ||
47 | |||
diff --git a/arch/arm/mach-mmp/pxa168.c b/arch/arm/mach-mmp/pxa168.c index 72b4e7631583..ab9f999106c7 100644 --- a/arch/arm/mach-mmp/pxa168.c +++ b/arch/arm/mach-mmp/pxa168.c | |||
@@ -79,7 +79,7 @@ static APBC_CLK(ssp4, PXA168_SSP4, 4, 0); | |||
79 | static APBC_CLK(ssp5, PXA168_SSP5, 4, 0); | 79 | static APBC_CLK(ssp5, PXA168_SSP5, 4, 0); |
80 | static APBC_CLK(keypad, PXA168_KPC, 0, 32000); | 80 | static APBC_CLK(keypad, PXA168_KPC, 0, 32000); |
81 | 81 | ||
82 | static APMU_CLK(nand, NAND, 0x01db, 208000000); | 82 | static APMU_CLK(nand, NAND, 0x19b, 156000000); |
83 | static APMU_CLK(lcd, LCD, 0x7f, 312000000); | 83 | static APMU_CLK(lcd, LCD, 0x7f, 312000000); |
84 | 84 | ||
85 | /* device and clock bindings */ | 85 | /* device and clock bindings */ |
diff --git a/arch/arm/mach-mmp/pxa910.c b/arch/arm/mach-mmp/pxa910.c index 8f92ccd26edf..1464607aa60d 100644 --- a/arch/arm/mach-mmp/pxa910.c +++ b/arch/arm/mach-mmp/pxa910.c | |||
@@ -110,7 +110,7 @@ static APBC_CLK(pwm2, PXA910_PWM2, 1, 13000000); | |||
110 | static APBC_CLK(pwm3, PXA910_PWM3, 1, 13000000); | 110 | static APBC_CLK(pwm3, PXA910_PWM3, 1, 13000000); |
111 | static APBC_CLK(pwm4, PXA910_PWM4, 1, 13000000); | 111 | static APBC_CLK(pwm4, PXA910_PWM4, 1, 13000000); |
112 | 112 | ||
113 | static APMU_CLK(nand, NAND, 0x01db, 208000000); | 113 | static APMU_CLK(nand, NAND, 0x19b, 156000000); |
114 | static APMU_CLK(u2o, USB, 0x1b, 480000000); | 114 | static APMU_CLK(u2o, USB, 0x1b, 480000000); |
115 | 115 | ||
116 | /* device and clock bindings */ | 116 | /* device and clock bindings */ |
diff --git a/arch/arm/mach-msm/platsmp.c b/arch/arm/mach-msm/platsmp.c index 2034098cf015..315b9f365329 100644 --- a/arch/arm/mach-msm/platsmp.c +++ b/arch/arm/mach-msm/platsmp.c | |||
@@ -157,12 +157,4 @@ void __init smp_init_cpus(void) | |||
157 | 157 | ||
158 | void __init platform_smp_prepare_cpus(unsigned int max_cpus) | 158 | void __init platform_smp_prepare_cpus(unsigned int max_cpus) |
159 | { | 159 | { |
160 | int i; | ||
161 | |||
162 | /* | ||
163 | * Initialise the present map, which describes the set of CPUs | ||
164 | * actually populated at the present time. | ||
165 | */ | ||
166 | for (i = 0; i < max_cpus; i++) | ||
167 | set_cpu_present(i, true); | ||
168 | } | 160 | } |
diff --git a/arch/arm/mach-omap1/board-ams-delta.c b/arch/arm/mach-omap1/board-ams-delta.c index de88c9297b68..f49ce85d2448 100644 --- a/arch/arm/mach-omap1/board-ams-delta.c +++ b/arch/arm/mach-omap1/board-ams-delta.c | |||
@@ -215,7 +215,7 @@ static struct omap_kp_platform_data ams_delta_kp_data __initdata = { | |||
215 | .delay = 9, | 215 | .delay = 9, |
216 | }; | 216 | }; |
217 | 217 | ||
218 | static struct platform_device ams_delta_kp_device __initdata = { | 218 | static struct platform_device ams_delta_kp_device = { |
219 | .name = "omap-keypad", | 219 | .name = "omap-keypad", |
220 | .id = -1, | 220 | .id = -1, |
221 | .dev = { | 221 | .dev = { |
@@ -225,12 +225,12 @@ static struct platform_device ams_delta_kp_device __initdata = { | |||
225 | .resource = ams_delta_kp_resources, | 225 | .resource = ams_delta_kp_resources, |
226 | }; | 226 | }; |
227 | 227 | ||
228 | static struct platform_device ams_delta_lcd_device __initdata = { | 228 | static struct platform_device ams_delta_lcd_device = { |
229 | .name = "lcd_ams_delta", | 229 | .name = "lcd_ams_delta", |
230 | .id = -1, | 230 | .id = -1, |
231 | }; | 231 | }; |
232 | 232 | ||
233 | static struct platform_device ams_delta_led_device __initdata = { | 233 | static struct platform_device ams_delta_led_device = { |
234 | .name = "ams-delta-led", | 234 | .name = "ams-delta-led", |
235 | .id = -1 | 235 | .id = -1 |
236 | }; | 236 | }; |
@@ -267,7 +267,7 @@ static struct soc_camera_link ams_delta_iclink = { | |||
267 | .power = ams_delta_camera_power, | 267 | .power = ams_delta_camera_power, |
268 | }; | 268 | }; |
269 | 269 | ||
270 | static struct platform_device ams_delta_camera_device __initdata = { | 270 | static struct platform_device ams_delta_camera_device = { |
271 | .name = "soc-camera-pdrv", | 271 | .name = "soc-camera-pdrv", |
272 | .id = 0, | 272 | .id = 0, |
273 | .dev = { | 273 | .dev = { |
diff --git a/arch/arm/mach-omap1/gpio15xx.c b/arch/arm/mach-omap1/gpio15xx.c index 04c4b04cf54e..364137c2042c 100644 --- a/arch/arm/mach-omap1/gpio15xx.c +++ b/arch/arm/mach-omap1/gpio15xx.c | |||
@@ -41,7 +41,7 @@ static struct __initdata omap_gpio_platform_data omap15xx_mpu_gpio_config = { | |||
41 | .bank_stride = 1, | 41 | .bank_stride = 1, |
42 | }; | 42 | }; |
43 | 43 | ||
44 | static struct __initdata platform_device omap15xx_mpu_gpio = { | 44 | static struct platform_device omap15xx_mpu_gpio = { |
45 | .name = "omap_gpio", | 45 | .name = "omap_gpio", |
46 | .id = 0, | 46 | .id = 0, |
47 | .dev = { | 47 | .dev = { |
@@ -70,7 +70,7 @@ static struct __initdata omap_gpio_platform_data omap15xx_gpio_config = { | |||
70 | .bank_width = 16, | 70 | .bank_width = 16, |
71 | }; | 71 | }; |
72 | 72 | ||
73 | static struct __initdata platform_device omap15xx_gpio = { | 73 | static struct platform_device omap15xx_gpio = { |
74 | .name = "omap_gpio", | 74 | .name = "omap_gpio", |
75 | .id = 1, | 75 | .id = 1, |
76 | .dev = { | 76 | .dev = { |
diff --git a/arch/arm/mach-omap1/gpio16xx.c b/arch/arm/mach-omap1/gpio16xx.c index 5dd0d4c82b24..293a246e2824 100644 --- a/arch/arm/mach-omap1/gpio16xx.c +++ b/arch/arm/mach-omap1/gpio16xx.c | |||
@@ -44,7 +44,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_mpu_gpio_config = { | |||
44 | .bank_stride = 1, | 44 | .bank_stride = 1, |
45 | }; | 45 | }; |
46 | 46 | ||
47 | static struct __initdata platform_device omap16xx_mpu_gpio = { | 47 | static struct platform_device omap16xx_mpu_gpio = { |
48 | .name = "omap_gpio", | 48 | .name = "omap_gpio", |
49 | .id = 0, | 49 | .id = 0, |
50 | .dev = { | 50 | .dev = { |
@@ -73,7 +73,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_gpio1_config = { | |||
73 | .bank_width = 16, | 73 | .bank_width = 16, |
74 | }; | 74 | }; |
75 | 75 | ||
76 | static struct __initdata platform_device omap16xx_gpio1 = { | 76 | static struct platform_device omap16xx_gpio1 = { |
77 | .name = "omap_gpio", | 77 | .name = "omap_gpio", |
78 | .id = 1, | 78 | .id = 1, |
79 | .dev = { | 79 | .dev = { |
@@ -102,7 +102,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_gpio2_config = { | |||
102 | .bank_width = 16, | 102 | .bank_width = 16, |
103 | }; | 103 | }; |
104 | 104 | ||
105 | static struct __initdata platform_device omap16xx_gpio2 = { | 105 | static struct platform_device omap16xx_gpio2 = { |
106 | .name = "omap_gpio", | 106 | .name = "omap_gpio", |
107 | .id = 2, | 107 | .id = 2, |
108 | .dev = { | 108 | .dev = { |
@@ -131,7 +131,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_gpio3_config = { | |||
131 | .bank_width = 16, | 131 | .bank_width = 16, |
132 | }; | 132 | }; |
133 | 133 | ||
134 | static struct __initdata platform_device omap16xx_gpio3 = { | 134 | static struct platform_device omap16xx_gpio3 = { |
135 | .name = "omap_gpio", | 135 | .name = "omap_gpio", |
136 | .id = 3, | 136 | .id = 3, |
137 | .dev = { | 137 | .dev = { |
@@ -160,7 +160,7 @@ static struct __initdata omap_gpio_platform_data omap16xx_gpio4_config = { | |||
160 | .bank_width = 16, | 160 | .bank_width = 16, |
161 | }; | 161 | }; |
162 | 162 | ||
163 | static struct __initdata platform_device omap16xx_gpio4 = { | 163 | static struct platform_device omap16xx_gpio4 = { |
164 | .name = "omap_gpio", | 164 | .name = "omap_gpio", |
165 | .id = 4, | 165 | .id = 4, |
166 | .dev = { | 166 | .dev = { |
diff --git a/arch/arm/mach-omap1/gpio7xx.c b/arch/arm/mach-omap1/gpio7xx.c index 1204c8b871af..c6ad248d63a6 100644 --- a/arch/arm/mach-omap1/gpio7xx.c +++ b/arch/arm/mach-omap1/gpio7xx.c | |||
@@ -46,7 +46,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_mpu_gpio_config = { | |||
46 | .bank_stride = 2, | 46 | .bank_stride = 2, |
47 | }; | 47 | }; |
48 | 48 | ||
49 | static struct __initdata platform_device omap7xx_mpu_gpio = { | 49 | static struct platform_device omap7xx_mpu_gpio = { |
50 | .name = "omap_gpio", | 50 | .name = "omap_gpio", |
51 | .id = 0, | 51 | .id = 0, |
52 | .dev = { | 52 | .dev = { |
@@ -75,7 +75,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio1_config = { | |||
75 | .bank_width = 32, | 75 | .bank_width = 32, |
76 | }; | 76 | }; |
77 | 77 | ||
78 | static struct __initdata platform_device omap7xx_gpio1 = { | 78 | static struct platform_device omap7xx_gpio1 = { |
79 | .name = "omap_gpio", | 79 | .name = "omap_gpio", |
80 | .id = 1, | 80 | .id = 1, |
81 | .dev = { | 81 | .dev = { |
@@ -104,7 +104,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio2_config = { | |||
104 | .bank_width = 32, | 104 | .bank_width = 32, |
105 | }; | 105 | }; |
106 | 106 | ||
107 | static struct __initdata platform_device omap7xx_gpio2 = { | 107 | static struct platform_device omap7xx_gpio2 = { |
108 | .name = "omap_gpio", | 108 | .name = "omap_gpio", |
109 | .id = 2, | 109 | .id = 2, |
110 | .dev = { | 110 | .dev = { |
@@ -133,7 +133,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio3_config = { | |||
133 | .bank_width = 32, | 133 | .bank_width = 32, |
134 | }; | 134 | }; |
135 | 135 | ||
136 | static struct __initdata platform_device omap7xx_gpio3 = { | 136 | static struct platform_device omap7xx_gpio3 = { |
137 | .name = "omap_gpio", | 137 | .name = "omap_gpio", |
138 | .id = 3, | 138 | .id = 3, |
139 | .dev = { | 139 | .dev = { |
@@ -162,7 +162,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio4_config = { | |||
162 | .bank_width = 32, | 162 | .bank_width = 32, |
163 | }; | 163 | }; |
164 | 164 | ||
165 | static struct __initdata platform_device omap7xx_gpio4 = { | 165 | static struct platform_device omap7xx_gpio4 = { |
166 | .name = "omap_gpio", | 166 | .name = "omap_gpio", |
167 | .id = 4, | 167 | .id = 4, |
168 | .dev = { | 168 | .dev = { |
@@ -191,7 +191,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio5_config = { | |||
191 | .bank_width = 32, | 191 | .bank_width = 32, |
192 | }; | 192 | }; |
193 | 193 | ||
194 | static struct __initdata platform_device omap7xx_gpio5 = { | 194 | static struct platform_device omap7xx_gpio5 = { |
195 | .name = "omap_gpio", | 195 | .name = "omap_gpio", |
196 | .id = 5, | 196 | .id = 5, |
197 | .dev = { | 197 | .dev = { |
@@ -220,7 +220,7 @@ static struct __initdata omap_gpio_platform_data omap7xx_gpio6_config = { | |||
220 | .bank_width = 32, | 220 | .bank_width = 32, |
221 | }; | 221 | }; |
222 | 222 | ||
223 | static struct __initdata platform_device omap7xx_gpio6 = { | 223 | static struct platform_device omap7xx_gpio6 = { |
224 | .name = "omap_gpio", | 224 | .name = "omap_gpio", |
225 | .id = 6, | 225 | .id = 6, |
226 | .dev = { | 226 | .dev = { |
diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index 990366726c58..88bd6f7705f0 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c | |||
@@ -558,7 +558,7 @@ static struct radio_si4713_platform_data rx51_si4713_data __initdata_or_module = | |||
558 | .subdev_board_info = &rx51_si4713_board_info, | 558 | .subdev_board_info = &rx51_si4713_board_info, |
559 | }; | 559 | }; |
560 | 560 | ||
561 | static struct platform_device rx51_si4713_dev __initdata_or_module = { | 561 | static struct platform_device rx51_si4713_dev = { |
562 | .name = "radio-si4713", | 562 | .name = "radio-si4713", |
563 | .id = -1, | 563 | .id = -1, |
564 | .dev = { | 564 | .dev = { |
diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c index da53ba3917ca..aab884fecc55 100644 --- a/arch/arm/mach-omap2/control.c +++ b/arch/arm/mach-omap2/control.c | |||
@@ -286,14 +286,15 @@ void omap3_save_scratchpad_contents(void) | |||
286 | scratchpad_contents.boot_config_ptr = 0x0; | 286 | scratchpad_contents.boot_config_ptr = 0x0; |
287 | if (cpu_is_omap3630()) | 287 | if (cpu_is_omap3630()) |
288 | scratchpad_contents.public_restore_ptr = | 288 | scratchpad_contents.public_restore_ptr = |
289 | virt_to_phys(get_omap3630_restore_pointer()); | 289 | virt_to_phys(omap3_restore_3630); |
290 | else if (omap_rev() != OMAP3430_REV_ES3_0 && | 290 | else if (omap_rev() != OMAP3430_REV_ES3_0 && |
291 | omap_rev() != OMAP3430_REV_ES3_1) | 291 | omap_rev() != OMAP3430_REV_ES3_1) |
292 | scratchpad_contents.public_restore_ptr = | 292 | scratchpad_contents.public_restore_ptr = |
293 | virt_to_phys(get_restore_pointer()); | 293 | virt_to_phys(omap3_restore); |
294 | else | 294 | else |
295 | scratchpad_contents.public_restore_ptr = | 295 | scratchpad_contents.public_restore_ptr = |
296 | virt_to_phys(get_es3_restore_pointer()); | 296 | virt_to_phys(omap3_restore_es3); |
297 | |||
297 | if (omap_type() == OMAP2_DEVICE_TYPE_GP) | 298 | if (omap_type() == OMAP2_DEVICE_TYPE_GP) |
298 | scratchpad_contents.secure_ram_restore_ptr = 0x0; | 299 | scratchpad_contents.secure_ram_restore_ptr = 0x0; |
299 | else | 300 | else |
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h index a016c8b59e00..d4ef75d5a382 100644 --- a/arch/arm/mach-omap2/control.h +++ b/arch/arm/mach-omap2/control.h | |||
@@ -386,9 +386,9 @@ extern void omap4_ctrl_pad_writel(u32 val, u16 offset); | |||
386 | 386 | ||
387 | extern void omap3_save_scratchpad_contents(void); | 387 | extern void omap3_save_scratchpad_contents(void); |
388 | extern void omap3_clear_scratchpad_contents(void); | 388 | extern void omap3_clear_scratchpad_contents(void); |
389 | extern u32 *get_restore_pointer(void); | 389 | extern void omap3_restore(void); |
390 | extern u32 *get_es3_restore_pointer(void); | 390 | extern void omap3_restore_es3(void); |
391 | extern u32 *get_omap3630_restore_pointer(void); | 391 | extern void omap3_restore_3630(void); |
392 | extern u32 omap3_arm_context[128]; | 392 | extern u32 omap3_arm_context[128]; |
393 | extern void omap3_control_save_context(void); | 393 | extern void omap3_control_save_context(void); |
394 | extern void omap3_control_restore_context(void); | 394 | extern void omap3_control_restore_context(void); |
diff --git a/arch/arm/mach-omap2/include/mach/entry-macro.S b/arch/arm/mach-omap2/include/mach/entry-macro.S index a48690b90990..ceb8b7e593d7 100644 --- a/arch/arm/mach-omap2/include/mach/entry-macro.S +++ b/arch/arm/mach-omap2/include/mach/entry-macro.S | |||
@@ -165,6 +165,3 @@ | |||
165 | #endif | 165 | #endif |
166 | 166 | ||
167 | #endif /* MULTI_OMAP2 */ | 167 | #endif /* MULTI_OMAP2 */ |
168 | |||
169 | .macro irq_prio_table | ||
170 | .endm | ||
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index ecfe93c4b585..ce65e9329c7b 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c | |||
@@ -125,14 +125,6 @@ void __init smp_init_cpus(void) | |||
125 | 125 | ||
126 | void __init platform_smp_prepare_cpus(unsigned int max_cpus) | 126 | void __init platform_smp_prepare_cpus(unsigned int max_cpus) |
127 | { | 127 | { |
128 | int i; | ||
129 | |||
130 | /* | ||
131 | * Initialise the present map, which describes the set of CPUs | ||
132 | * actually populated at the present time. | ||
133 | */ | ||
134 | for (i = 0; i < max_cpus; i++) | ||
135 | set_cpu_present(i, true); | ||
136 | 128 | ||
137 | /* | 129 | /* |
138 | * Initialise the SCU and wake up the secondary core using | 130 | * Initialise the SCU and wake up the secondary core using |
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h index 45bcfce77352..04ee56646126 100644 --- a/arch/arm/mach-omap2/pm.h +++ b/arch/arm/mach-omap2/pm.h | |||
@@ -88,18 +88,28 @@ extern int pm_dbg_regset_init(int reg_set); | |||
88 | #define pm_dbg_regset_init(reg_set) do {} while (0); | 88 | #define pm_dbg_regset_init(reg_set) do {} while (0); |
89 | #endif /* CONFIG_PM_DEBUG */ | 89 | #endif /* CONFIG_PM_DEBUG */ |
90 | 90 | ||
91 | /* 24xx */ | ||
91 | extern void omap24xx_idle_loop_suspend(void); | 92 | extern void omap24xx_idle_loop_suspend(void); |
93 | extern unsigned int omap24xx_idle_loop_suspend_sz; | ||
92 | 94 | ||
93 | extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl, | 95 | extern void omap24xx_cpu_suspend(u32 dll_ctrl, void __iomem *sdrc_dlla_ctrl, |
94 | void __iomem *sdrc_power); | 96 | void __iomem *sdrc_power); |
95 | extern void omap34xx_cpu_suspend(u32 *addr, int save_state); | 97 | extern unsigned int omap24xx_cpu_suspend_sz; |
96 | extern int save_secure_ram_context(u32 *addr); | ||
97 | extern void omap3_save_scratchpad_contents(void); | ||
98 | 98 | ||
99 | extern unsigned int omap24xx_idle_loop_suspend_sz; | 99 | /* 3xxx */ |
100 | extern void omap34xx_cpu_suspend(int save_state); | ||
101 | |||
102 | /* omap3_do_wfi function pointer and size, for copy to SRAM */ | ||
103 | extern void omap3_do_wfi(void); | ||
104 | extern unsigned int omap3_do_wfi_sz; | ||
105 | /* ... and its pointer from SRAM after copy */ | ||
106 | extern void (*omap3_do_wfi_sram)(void); | ||
107 | |||
108 | /* save_secure_ram_context function pointer and size, for copy to SRAM */ | ||
109 | extern int save_secure_ram_context(u32 *addr); | ||
100 | extern unsigned int save_secure_ram_context_sz; | 110 | extern unsigned int save_secure_ram_context_sz; |
101 | extern unsigned int omap24xx_cpu_suspend_sz; | 111 | |
102 | extern unsigned int omap34xx_cpu_suspend_sz; | 112 | extern void omap3_save_scratchpad_contents(void); |
103 | 113 | ||
104 | #define PM_RTA_ERRATUM_i608 (1 << 0) | 114 | #define PM_RTA_ERRATUM_i608 (1 << 0) |
105 | #define PM_SDRC_WAKEUP_ERRATUM_i583 (1 << 1) | 115 | #define PM_SDRC_WAKEUP_ERRATUM_i583 (1 << 1) |
diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index c155c9d1c82c..b77d82665abb 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c | |||
@@ -31,6 +31,8 @@ | |||
31 | #include <linux/console.h> | 31 | #include <linux/console.h> |
32 | #include <trace/events/power.h> | 32 | #include <trace/events/power.h> |
33 | 33 | ||
34 | #include <asm/suspend.h> | ||
35 | |||
34 | #include <plat/sram.h> | 36 | #include <plat/sram.h> |
35 | #include "clockdomain.h" | 37 | #include "clockdomain.h" |
36 | #include "powerdomain.h" | 38 | #include "powerdomain.h" |
@@ -40,8 +42,6 @@ | |||
40 | #include <plat/gpmc.h> | 42 | #include <plat/gpmc.h> |
41 | #include <plat/dma.h> | 43 | #include <plat/dma.h> |
42 | 44 | ||
43 | #include <asm/tlbflush.h> | ||
44 | |||
45 | #include "cm2xxx_3xxx.h" | 45 | #include "cm2xxx_3xxx.h" |
46 | #include "cm-regbits-34xx.h" | 46 | #include "cm-regbits-34xx.h" |
47 | #include "prm-regbits-34xx.h" | 47 | #include "prm-regbits-34xx.h" |
@@ -64,11 +64,6 @@ static inline bool is_suspending(void) | |||
64 | } | 64 | } |
65 | #endif | 65 | #endif |
66 | 66 | ||
67 | /* Scratchpad offsets */ | ||
68 | #define OMAP343X_TABLE_ADDRESS_OFFSET 0xc4 | ||
69 | #define OMAP343X_TABLE_VALUE_OFFSET 0xc0 | ||
70 | #define OMAP343X_CONTROL_REG_VALUE_OFFSET 0xc8 | ||
71 | |||
72 | /* pm34xx errata defined in pm.h */ | 67 | /* pm34xx errata defined in pm.h */ |
73 | u16 pm34xx_errata; | 68 | u16 pm34xx_errata; |
74 | 69 | ||
@@ -83,9 +78,8 @@ struct power_state { | |||
83 | 78 | ||
84 | static LIST_HEAD(pwrst_list); | 79 | static LIST_HEAD(pwrst_list); |
85 | 80 | ||
86 | static void (*_omap_sram_idle)(u32 *addr, int save_state); | ||
87 | |||
88 | static int (*_omap_save_secure_sram)(u32 *addr); | 81 | static int (*_omap_save_secure_sram)(u32 *addr); |
82 | void (*omap3_do_wfi_sram)(void); | ||
89 | 83 | ||
90 | static struct powerdomain *mpu_pwrdm, *neon_pwrdm; | 84 | static struct powerdomain *mpu_pwrdm, *neon_pwrdm; |
91 | static struct powerdomain *core_pwrdm, *per_pwrdm; | 85 | static struct powerdomain *core_pwrdm, *per_pwrdm; |
@@ -312,28 +306,25 @@ static irqreturn_t prcm_interrupt_handler (int irq, void *dev_id) | |||
312 | return IRQ_HANDLED; | 306 | return IRQ_HANDLED; |
313 | } | 307 | } |
314 | 308 | ||
315 | /* Function to restore the table entry that was modified for enabling MMU */ | 309 | static void omap34xx_save_context(u32 *save) |
316 | static void restore_table_entry(void) | ||
317 | { | 310 | { |
318 | void __iomem *scratchpad_address; | 311 | u32 val; |
319 | u32 previous_value, control_reg_value; | ||
320 | u32 *address; | ||
321 | 312 | ||
322 | scratchpad_address = OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD); | 313 | /* Read Auxiliary Control Register */ |
314 | asm("mrc p15, 0, %0, c1, c0, 1" : "=r" (val)); | ||
315 | *save++ = 1; | ||
316 | *save++ = val; | ||
323 | 317 | ||
324 | /* Get address of entry that was modified */ | 318 | /* Read L2 AUX ctrl register */ |
325 | address = (u32 *)__raw_readl(scratchpad_address + | 319 | asm("mrc p15, 1, %0, c9, c0, 2" : "=r" (val)); |
326 | OMAP343X_TABLE_ADDRESS_OFFSET); | 320 | *save++ = 1; |
327 | /* Get the previous value which needs to be restored */ | 321 | *save++ = val; |
328 | previous_value = __raw_readl(scratchpad_address + | 322 | } |
329 | OMAP343X_TABLE_VALUE_OFFSET); | 323 | |
330 | address = __va(address); | 324 | static int omap34xx_do_sram_idle(unsigned long save_state) |
331 | *address = previous_value; | 325 | { |
332 | flush_tlb_all(); | 326 | omap34xx_cpu_suspend(save_state); |
333 | control_reg_value = __raw_readl(scratchpad_address | 327 | return 0; |
334 | + OMAP343X_CONTROL_REG_VALUE_OFFSET); | ||
335 | /* This will enable caches and prediction */ | ||
336 | set_cr(control_reg_value); | ||
337 | } | 328 | } |
338 | 329 | ||
339 | void omap_sram_idle(void) | 330 | void omap_sram_idle(void) |
@@ -352,9 +343,6 @@ void omap_sram_idle(void) | |||
352 | int core_prev_state, per_prev_state; | 343 | int core_prev_state, per_prev_state; |
353 | u32 sdrc_pwr = 0; | 344 | u32 sdrc_pwr = 0; |
354 | 345 | ||
355 | if (!_omap_sram_idle) | ||
356 | return; | ||
357 | |||
358 | pwrdm_clear_all_prev_pwrst(mpu_pwrdm); | 346 | pwrdm_clear_all_prev_pwrst(mpu_pwrdm); |
359 | pwrdm_clear_all_prev_pwrst(neon_pwrdm); | 347 | pwrdm_clear_all_prev_pwrst(neon_pwrdm); |
360 | pwrdm_clear_all_prev_pwrst(core_pwrdm); | 348 | pwrdm_clear_all_prev_pwrst(core_pwrdm); |
@@ -432,12 +420,16 @@ void omap_sram_idle(void) | |||
432 | sdrc_pwr = sdrc_read_reg(SDRC_POWER); | 420 | sdrc_pwr = sdrc_read_reg(SDRC_POWER); |
433 | 421 | ||
434 | /* | 422 | /* |
435 | * omap3_arm_context is the location where ARM registers | 423 | * omap3_arm_context is the location where some ARM context |
436 | * get saved. The restore path then reads from this | 424 | * get saved. The rest is placed on the stack, and restored |
437 | * location and restores them back. | 425 | * from there before resuming. |
438 | */ | 426 | */ |
439 | _omap_sram_idle(omap3_arm_context, save_state); | 427 | if (save_state) |
440 | cpu_init(); | 428 | omap34xx_save_context(omap3_arm_context); |
429 | if (save_state == 1 || save_state == 3) | ||
430 | cpu_suspend(save_state, omap34xx_do_sram_idle); | ||
431 | else | ||
432 | omap34xx_do_sram_idle(save_state); | ||
441 | 433 | ||
442 | /* Restore normal SDRC POWER settings */ | 434 | /* Restore normal SDRC POWER settings */ |
443 | if (omap_rev() >= OMAP3430_REV_ES3_0 && | 435 | if (omap_rev() >= OMAP3430_REV_ES3_0 && |
@@ -445,10 +437,6 @@ void omap_sram_idle(void) | |||
445 | core_next_state == PWRDM_POWER_OFF) | 437 | core_next_state == PWRDM_POWER_OFF) |
446 | sdrc_write_reg(sdrc_pwr, SDRC_POWER); | 438 | sdrc_write_reg(sdrc_pwr, SDRC_POWER); |
447 | 439 | ||
448 | /* Restore table entry modified during MMU restoration */ | ||
449 | if (pwrdm_read_prev_pwrst(mpu_pwrdm) == PWRDM_POWER_OFF) | ||
450 | restore_table_entry(); | ||
451 | |||
452 | /* CORE */ | 440 | /* CORE */ |
453 | if (core_next_state < PWRDM_POWER_ON) { | 441 | if (core_next_state < PWRDM_POWER_ON) { |
454 | core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm); | 442 | core_prev_state = pwrdm_read_prev_pwrst(core_pwrdm); |
@@ -852,10 +840,17 @@ static int __init clkdms_setup(struct clockdomain *clkdm, void *unused) | |||
852 | return 0; | 840 | return 0; |
853 | } | 841 | } |
854 | 842 | ||
843 | /* | ||
844 | * Push functions to SRAM | ||
845 | * | ||
846 | * The minimum set of functions is pushed to SRAM for execution: | ||
847 | * - omap3_do_wfi for erratum i581 WA, | ||
848 | * - save_secure_ram_context for security extensions. | ||
849 | */ | ||
855 | void omap_push_sram_idle(void) | 850 | void omap_push_sram_idle(void) |
856 | { | 851 | { |
857 | _omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend, | 852 | omap3_do_wfi_sram = omap_sram_push(omap3_do_wfi, omap3_do_wfi_sz); |
858 | omap34xx_cpu_suspend_sz); | 853 | |
859 | if (omap_type() != OMAP2_DEVICE_TYPE_GP) | 854 | if (omap_type() != OMAP2_DEVICE_TYPE_GP) |
860 | _omap_save_secure_sram = omap_sram_push(save_secure_ram_context, | 855 | _omap_save_secure_sram = omap_sram_push(save_secure_ram_context, |
861 | save_secure_ram_context_sz); | 856 | save_secure_ram_context_sz); |
@@ -920,7 +915,6 @@ static int __init omap3_pm_init(void) | |||
920 | per_clkdm = clkdm_lookup("per_clkdm"); | 915 | per_clkdm = clkdm_lookup("per_clkdm"); |
921 | core_clkdm = clkdm_lookup("core_clkdm"); | 916 | core_clkdm = clkdm_lookup("core_clkdm"); |
922 | 917 | ||
923 | omap_push_sram_idle(); | ||
924 | #ifdef CONFIG_SUSPEND | 918 | #ifdef CONFIG_SUSPEND |
925 | suspend_set_ops(&omap_pm_ops); | 919 | suspend_set_ops(&omap_pm_ops); |
926 | #endif /* CONFIG_SUSPEND */ | 920 | #endif /* CONFIG_SUSPEND */ |
diff --git a/arch/arm/mach-omap2/sleep34xx.S b/arch/arm/mach-omap2/sleep34xx.S index 63f10669571a..f2ea1bd1c691 100644 --- a/arch/arm/mach-omap2/sleep34xx.S +++ b/arch/arm/mach-omap2/sleep34xx.S | |||
@@ -74,46 +74,6 @@ | |||
74 | * API functions | 74 | * API functions |
75 | */ | 75 | */ |
76 | 76 | ||
77 | /* | ||
78 | * The "get_*restore_pointer" functions are used to provide a | ||
79 | * physical restore address where the ROM code jumps while waking | ||
80 | * up from MPU OFF/OSWR state. | ||
81 | * The restore pointer is stored into the scratchpad. | ||
82 | */ | ||
83 | |||
84 | .text | ||
85 | /* Function call to get the restore pointer for resume from OFF */ | ||
86 | ENTRY(get_restore_pointer) | ||
87 | stmfd sp!, {lr} @ save registers on stack | ||
88 | adr r0, restore | ||
89 | ldmfd sp!, {pc} @ restore regs and return | ||
90 | ENDPROC(get_restore_pointer) | ||
91 | .align | ||
92 | ENTRY(get_restore_pointer_sz) | ||
93 | .word . - get_restore_pointer | ||
94 | |||
95 | .text | ||
96 | /* Function call to get the restore pointer for 3630 resume from OFF */ | ||
97 | ENTRY(get_omap3630_restore_pointer) | ||
98 | stmfd sp!, {lr} @ save registers on stack | ||
99 | adr r0, restore_3630 | ||
100 | ldmfd sp!, {pc} @ restore regs and return | ||
101 | ENDPROC(get_omap3630_restore_pointer) | ||
102 | .align | ||
103 | ENTRY(get_omap3630_restore_pointer_sz) | ||
104 | .word . - get_omap3630_restore_pointer | ||
105 | |||
106 | .text | ||
107 | /* Function call to get the restore pointer for ES3 to resume from OFF */ | ||
108 | ENTRY(get_es3_restore_pointer) | ||
109 | stmfd sp!, {lr} @ save registers on stack | ||
110 | adr r0, restore_es3 | ||
111 | ldmfd sp!, {pc} @ restore regs and return | ||
112 | ENDPROC(get_es3_restore_pointer) | ||
113 | .align | ||
114 | ENTRY(get_es3_restore_pointer_sz) | ||
115 | .word . - get_es3_restore_pointer | ||
116 | |||
117 | .text | 77 | .text |
118 | /* | 78 | /* |
119 | * L2 cache needs to be toggled for stable OFF mode functionality on 3630. | 79 | * L2 cache needs to be toggled for stable OFF mode functionality on 3630. |
@@ -133,7 +93,7 @@ ENDPROC(enable_omap3630_toggle_l2_on_restore) | |||
133 | /* Function to call rom code to save secure ram context */ | 93 | /* Function to call rom code to save secure ram context */ |
134 | .align 3 | 94 | .align 3 |
135 | ENTRY(save_secure_ram_context) | 95 | ENTRY(save_secure_ram_context) |
136 | stmfd sp!, {r1-r12, lr} @ save registers on stack | 96 | stmfd sp!, {r4 - r11, lr} @ save registers on stack |
137 | adr r3, api_params @ r3 points to parameters | 97 | adr r3, api_params @ r3 points to parameters |
138 | str r0, [r3,#0x4] @ r0 has sdram address | 98 | str r0, [r3,#0x4] @ r0 has sdram address |
139 | ldr r12, high_mask | 99 | ldr r12, high_mask |
@@ -152,7 +112,7 @@ ENTRY(save_secure_ram_context) | |||
152 | nop | 112 | nop |
153 | nop | 113 | nop |
154 | nop | 114 | nop |
155 | ldmfd sp!, {r1-r12, pc} | 115 | ldmfd sp!, {r4 - r11, pc} |
156 | .align | 116 | .align |
157 | sram_phy_addr_mask: | 117 | sram_phy_addr_mask: |
158 | .word SRAM_BASE_P | 118 | .word SRAM_BASE_P |
@@ -179,69 +139,38 @@ ENTRY(save_secure_ram_context_sz) | |||
179 | * | 139 | * |
180 | * | 140 | * |
181 | * Notes: | 141 | * Notes: |
182 | * - this code gets copied to internal SRAM at boot and after wake-up | 142 | * - only the minimum set of functions gets copied to internal SRAM at boot |
183 | * from OFF mode. The execution pointer in SRAM is _omap_sram_idle. | 143 | * and after wake-up from OFF mode, cf. omap_push_sram_idle. The function |
144 | * pointers in SDRAM or SRAM are called depending on the desired low power | ||
145 | * target state. | ||
184 | * - when the OMAP wakes up it continues at different execution points | 146 | * - when the OMAP wakes up it continues at different execution points |
185 | * depending on the low power mode (non-OFF vs OFF modes), | 147 | * depending on the low power mode (non-OFF vs OFF modes), |
186 | * cf. 'Resume path for xxx mode' comments. | 148 | * cf. 'Resume path for xxx mode' comments. |
187 | */ | 149 | */ |
188 | .align 3 | 150 | .align 3 |
189 | ENTRY(omap34xx_cpu_suspend) | 151 | ENTRY(omap34xx_cpu_suspend) |
190 | stmfd sp!, {r0-r12, lr} @ save registers on stack | 152 | stmfd sp!, {r4 - r11, lr} @ save registers on stack |
191 | 153 | ||
192 | /* | 154 | /* |
193 | * r0 contains CPU context save/restore pointer in sdram | 155 | * r0 contains information about saving context: |
194 | * r1 contains information about saving context: | ||
195 | * 0 - No context lost | 156 | * 0 - No context lost |
196 | * 1 - Only L1 and logic lost | 157 | * 1 - Only L1 and logic lost |
197 | * 2 - Only L2 lost (Even L1 is retained we clean it along with L2) | 158 | * 2 - Only L2 lost (Even L1 is retained we clean it along with L2) |
198 | * 3 - Both L1 and L2 lost and logic lost | 159 | * 3 - Both L1 and L2 lost and logic lost |
199 | */ | 160 | */ |
200 | 161 | ||
201 | /* Directly jump to WFI is the context save is not required */ | 162 | /* |
202 | cmp r1, #0x0 | 163 | * For OFF mode: save context and jump to WFI in SDRAM (omap3_do_wfi) |
203 | beq omap3_do_wfi | 164 | * For non-OFF modes: jump to the WFI code in SRAM (omap3_do_wfi_sram) |
165 | */ | ||
166 | ldr r4, omap3_do_wfi_sram_addr | ||
167 | ldr r5, [r4] | ||
168 | cmp r0, #0x0 @ If no context save required, | ||
169 | bxeq r5 @ jump to the WFI code in SRAM | ||
170 | |||
204 | 171 | ||
205 | /* Otherwise fall through to the save context code */ | 172 | /* Otherwise fall through to the save context code */ |
206 | save_context_wfi: | 173 | save_context_wfi: |
207 | mov r8, r0 @ Store SDRAM address in r8 | ||
208 | mrc p15, 0, r5, c1, c0, 1 @ Read Auxiliary Control Register | ||
209 | mov r4, #0x1 @ Number of parameters for restore call | ||
210 | stmia r8!, {r4-r5} @ Push parameters for restore call | ||
211 | mrc p15, 1, r5, c9, c0, 2 @ Read L2 AUX ctrl register | ||
212 | stmia r8!, {r4-r5} @ Push parameters for restore call | ||
213 | |||
214 | /* Check what that target sleep state is from r1 */ | ||
215 | cmp r1, #0x2 @ Only L2 lost, no need to save context | ||
216 | beq clean_caches | ||
217 | |||
218 | l1_logic_lost: | ||
219 | mov r4, sp @ Store sp | ||
220 | mrs r5, spsr @ Store spsr | ||
221 | mov r6, lr @ Store lr | ||
222 | stmia r8!, {r4-r6} | ||
223 | |||
224 | mrc p15, 0, r4, c1, c0, 2 @ Coprocessor access control register | ||
225 | mrc p15, 0, r5, c2, c0, 0 @ TTBR0 | ||
226 | mrc p15, 0, r6, c2, c0, 1 @ TTBR1 | ||
227 | mrc p15, 0, r7, c2, c0, 2 @ TTBCR | ||
228 | stmia r8!, {r4-r7} | ||
229 | |||
230 | mrc p15, 0, r4, c3, c0, 0 @ Domain access Control Register | ||
231 | mrc p15, 0, r5, c10, c2, 0 @ PRRR | ||
232 | mrc p15, 0, r6, c10, c2, 1 @ NMRR | ||
233 | stmia r8!,{r4-r6} | ||
234 | |||
235 | mrc p15, 0, r4, c13, c0, 1 @ Context ID | ||
236 | mrc p15, 0, r5, c13, c0, 2 @ User r/w thread and process ID | ||
237 | mrc p15, 0, r6, c12, c0, 0 @ Secure or NS vector base address | ||
238 | mrs r7, cpsr @ Store current cpsr | ||
239 | stmia r8!, {r4-r7} | ||
240 | |||
241 | mrc p15, 0, r4, c1, c0, 0 @ save control register | ||
242 | stmia r8!, {r4} | ||
243 | |||
244 | clean_caches: | ||
245 | /* | 174 | /* |
246 | * jump out to kernel flush routine | 175 | * jump out to kernel flush routine |
247 | * - reuse that code is better | 176 | * - reuse that code is better |
@@ -284,7 +213,32 @@ clean_caches: | |||
284 | THUMB( nop ) | 213 | THUMB( nop ) |
285 | .arm | 214 | .arm |
286 | 215 | ||
287 | omap3_do_wfi: | 216 | b omap3_do_wfi |
217 | |||
218 | /* | ||
219 | * Local variables | ||
220 | */ | ||
221 | omap3_do_wfi_sram_addr: | ||
222 | .word omap3_do_wfi_sram | ||
223 | kernel_flush: | ||
224 | .word v7_flush_dcache_all | ||
225 | |||
226 | /* =================================== | ||
227 | * == WFI instruction => Enter idle == | ||
228 | * =================================== | ||
229 | */ | ||
230 | |||
231 | /* | ||
232 | * Do WFI instruction | ||
233 | * Includes the resume path for non-OFF modes | ||
234 | * | ||
235 | * This code gets copied to internal SRAM and is accessible | ||
236 | * from both SDRAM and SRAM: | ||
237 | * - executed from SRAM for non-off modes (omap3_do_wfi_sram), | ||
238 | * - executed from SDRAM for OFF mode (omap3_do_wfi). | ||
239 | */ | ||
240 | .align 3 | ||
241 | ENTRY(omap3_do_wfi) | ||
288 | ldr r4, sdrc_power @ read the SDRC_POWER register | 242 | ldr r4, sdrc_power @ read the SDRC_POWER register |
289 | ldr r5, [r4] @ read the contents of SDRC_POWER | 243 | ldr r5, [r4] @ read the contents of SDRC_POWER |
290 | orr r5, r5, #0x40 @ enable self refresh on idle req | 244 | orr r5, r5, #0x40 @ enable self refresh on idle req |
@@ -316,8 +270,86 @@ omap3_do_wfi: | |||
316 | nop | 270 | nop |
317 | nop | 271 | nop |
318 | nop | 272 | nop |
319 | bl wait_sdrc_ok | ||
320 | 273 | ||
274 | /* | ||
275 | * This function implements the erratum ID i581 WA: | ||
276 | * SDRC state restore before accessing the SDRAM | ||
277 | * | ||
278 | * Only used at return from non-OFF mode. For OFF | ||
279 | * mode the ROM code configures the SDRC and | ||
280 | * the DPLL before calling the restore code directly | ||
281 | * from DDR. | ||
282 | */ | ||
283 | |||
284 | /* Make sure SDRC accesses are ok */ | ||
285 | wait_sdrc_ok: | ||
286 | |||
287 | /* DPLL3 must be locked before accessing the SDRC. Maybe the HW ensures this */ | ||
288 | ldr r4, cm_idlest_ckgen | ||
289 | wait_dpll3_lock: | ||
290 | ldr r5, [r4] | ||
291 | tst r5, #1 | ||
292 | beq wait_dpll3_lock | ||
293 | |||
294 | ldr r4, cm_idlest1_core | ||
295 | wait_sdrc_ready: | ||
296 | ldr r5, [r4] | ||
297 | tst r5, #0x2 | ||
298 | bne wait_sdrc_ready | ||
299 | /* allow DLL powerdown upon hw idle req */ | ||
300 | ldr r4, sdrc_power | ||
301 | ldr r5, [r4] | ||
302 | bic r5, r5, #0x40 | ||
303 | str r5, [r4] | ||
304 | |||
305 | /* | ||
306 | * PC-relative stores lead to undefined behaviour in Thumb-2: use a r7 as a | ||
307 | * base instead. | ||
308 | * Be careful not to clobber r7 when maintaing this code. | ||
309 | */ | ||
310 | |||
311 | is_dll_in_lock_mode: | ||
312 | /* Is dll in lock mode? */ | ||
313 | ldr r4, sdrc_dlla_ctrl | ||
314 | ldr r5, [r4] | ||
315 | tst r5, #0x4 | ||
316 | bne exit_nonoff_modes @ Return if locked | ||
317 | /* wait till dll locks */ | ||
318 | adr r7, kick_counter | ||
319 | wait_dll_lock_timed: | ||
320 | ldr r4, wait_dll_lock_counter | ||
321 | add r4, r4, #1 | ||
322 | str r4, [r7, #wait_dll_lock_counter - kick_counter] | ||
323 | ldr r4, sdrc_dlla_status | ||
324 | /* Wait 20uS for lock */ | ||
325 | mov r6, #8 | ||
326 | wait_dll_lock: | ||
327 | subs r6, r6, #0x1 | ||
328 | beq kick_dll | ||
329 | ldr r5, [r4] | ||
330 | and r5, r5, #0x4 | ||
331 | cmp r5, #0x4 | ||
332 | bne wait_dll_lock | ||
333 | b exit_nonoff_modes @ Return when locked | ||
334 | |||
335 | /* disable/reenable DLL if not locked */ | ||
336 | kick_dll: | ||
337 | ldr r4, sdrc_dlla_ctrl | ||
338 | ldr r5, [r4] | ||
339 | mov r6, r5 | ||
340 | bic r6, #(1<<3) @ disable dll | ||
341 | str r6, [r4] | ||
342 | dsb | ||
343 | orr r6, r6, #(1<<3) @ enable dll | ||
344 | str r6, [r4] | ||
345 | dsb | ||
346 | ldr r4, kick_counter | ||
347 | add r4, r4, #1 | ||
348 | str r4, [r7] @ kick_counter | ||
349 | b wait_dll_lock_timed | ||
350 | |||
351 | exit_nonoff_modes: | ||
352 | /* Re-enable C-bit if needed */ | ||
321 | mrc p15, 0, r0, c1, c0, 0 | 353 | mrc p15, 0, r0, c1, c0, 0 |
322 | tst r0, #(1 << 2) @ Check C bit enabled? | 354 | tst r0, #(1 << 2) @ Check C bit enabled? |
323 | orreq r0, r0, #(1 << 2) @ Enable the C bit if cleared | 355 | orreq r0, r0, #(1 << 2) @ Enable the C bit if cleared |
@@ -329,7 +361,32 @@ omap3_do_wfi: | |||
329 | * == Exit point from non-OFF modes == | 361 | * == Exit point from non-OFF modes == |
330 | * =================================== | 362 | * =================================== |
331 | */ | 363 | */ |
332 | ldmfd sp!, {r0-r12, pc} @ restore regs and return | 364 | ldmfd sp!, {r4 - r11, pc} @ restore regs and return |
365 | |||
366 | /* | ||
367 | * Local variables | ||
368 | */ | ||
369 | sdrc_power: | ||
370 | .word SDRC_POWER_V | ||
371 | cm_idlest1_core: | ||
372 | .word CM_IDLEST1_CORE_V | ||
373 | cm_idlest_ckgen: | ||
374 | .word CM_IDLEST_CKGEN_V | ||
375 | sdrc_dlla_status: | ||
376 | .word SDRC_DLLA_STATUS_V | ||
377 | sdrc_dlla_ctrl: | ||
378 | .word SDRC_DLLA_CTRL_V | ||
379 | /* | ||
380 | * When exporting to userspace while the counters are in SRAM, | ||
381 | * these 2 words need to be at the end to facilitate retrival! | ||
382 | */ | ||
383 | kick_counter: | ||
384 | .word 0 | ||
385 | wait_dll_lock_counter: | ||
386 | .word 0 | ||
387 | |||
388 | ENTRY(omap3_do_wfi_sz) | ||
389 | .word . - omap3_do_wfi | ||
333 | 390 | ||
334 | 391 | ||
335 | /* | 392 | /* |
@@ -346,13 +403,17 @@ omap3_do_wfi: | |||
346 | * restore_es3: applies to 34xx >= ES3.0 | 403 | * restore_es3: applies to 34xx >= ES3.0 |
347 | * restore_3630: applies to 36xx | 404 | * restore_3630: applies to 36xx |
348 | * restore: common code for 3xxx | 405 | * restore: common code for 3xxx |
406 | * | ||
407 | * Note: when back from CORE and MPU OFF mode we are running | ||
408 | * from SDRAM, without MMU, without the caches and prediction. | ||
409 | * Also the SRAM content has been cleared. | ||
349 | */ | 410 | */ |
350 | restore_es3: | 411 | ENTRY(omap3_restore_es3) |
351 | ldr r5, pm_prepwstst_core_p | 412 | ldr r5, pm_prepwstst_core_p |
352 | ldr r4, [r5] | 413 | ldr r4, [r5] |
353 | and r4, r4, #0x3 | 414 | and r4, r4, #0x3 |
354 | cmp r4, #0x0 @ Check if previous power state of CORE is OFF | 415 | cmp r4, #0x0 @ Check if previous power state of CORE is OFF |
355 | bne restore | 416 | bne omap3_restore @ Fall through to OMAP3 common code |
356 | adr r0, es3_sdrc_fix | 417 | adr r0, es3_sdrc_fix |
357 | ldr r1, sram_base | 418 | ldr r1, sram_base |
358 | ldr r2, es3_sdrc_fix_sz | 419 | ldr r2, es3_sdrc_fix_sz |
@@ -364,35 +425,32 @@ copy_to_sram: | |||
364 | bne copy_to_sram | 425 | bne copy_to_sram |
365 | ldr r1, sram_base | 426 | ldr r1, sram_base |
366 | blx r1 | 427 | blx r1 |
367 | b restore | 428 | b omap3_restore @ Fall through to OMAP3 common code |
429 | ENDPROC(omap3_restore_es3) | ||
368 | 430 | ||
369 | restore_3630: | 431 | ENTRY(omap3_restore_3630) |
370 | ldr r1, pm_prepwstst_core_p | 432 | ldr r1, pm_prepwstst_core_p |
371 | ldr r2, [r1] | 433 | ldr r2, [r1] |
372 | and r2, r2, #0x3 | 434 | and r2, r2, #0x3 |
373 | cmp r2, #0x0 @ Check if previous power state of CORE is OFF | 435 | cmp r2, #0x0 @ Check if previous power state of CORE is OFF |
374 | bne restore | 436 | bne omap3_restore @ Fall through to OMAP3 common code |
375 | /* Disable RTA before giving control */ | 437 | /* Disable RTA before giving control */ |
376 | ldr r1, control_mem_rta | 438 | ldr r1, control_mem_rta |
377 | mov r2, #OMAP36XX_RTA_DISABLE | 439 | mov r2, #OMAP36XX_RTA_DISABLE |
378 | str r2, [r1] | 440 | str r2, [r1] |
441 | ENDPROC(omap3_restore_3630) | ||
379 | 442 | ||
380 | /* Fall through to common code for the remaining logic */ | 443 | /* Fall through to common code for the remaining logic */ |
381 | 444 | ||
382 | restore: | 445 | ENTRY(omap3_restore) |
383 | /* | 446 | /* |
384 | * Check what was the reason for mpu reset and store the reason in r9: | 447 | * Read the pwstctrl register to check the reason for mpu reset. |
385 | * 0 - No context lost | 448 | * This tells us what was lost. |
386 | * 1 - Only L1 and logic lost | ||
387 | * 2 - Only L2 lost - In this case, we wont be here | ||
388 | * 3 - Both L1 and L2 lost | ||
389 | */ | 449 | */ |
390 | ldr r1, pm_pwstctrl_mpu | 450 | ldr r1, pm_pwstctrl_mpu |
391 | ldr r2, [r1] | 451 | ldr r2, [r1] |
392 | and r2, r2, #0x3 | 452 | and r2, r2, #0x3 |
393 | cmp r2, #0x0 @ Check if target power state was OFF or RET | 453 | cmp r2, #0x0 @ Check if target power state was OFF or RET |
394 | moveq r9, #0x3 @ MPU OFF => L1 and L2 lost | ||
395 | movne r9, #0x1 @ Only L1 and L2 lost => avoid L2 invalidation | ||
396 | bne logic_l1_restore | 454 | bne logic_l1_restore |
397 | 455 | ||
398 | ldr r0, l2dis_3630 | 456 | ldr r0, l2dis_3630 |
@@ -471,115 +529,39 @@ logic_l1_restore: | |||
471 | orr r1, r1, #2 @ re-enable L2 cache | 529 | orr r1, r1, #2 @ re-enable L2 cache |
472 | mcr p15, 0, r1, c1, c0, 1 | 530 | mcr p15, 0, r1, c1, c0, 1 |
473 | skipl2reen: | 531 | skipl2reen: |
474 | mov r1, #0 | ||
475 | /* | ||
476 | * Invalidate all instruction caches to PoU | ||
477 | * and flush branch target cache | ||
478 | */ | ||
479 | mcr p15, 0, r1, c7, c5, 0 | ||
480 | 532 | ||
481 | ldr r4, scratchpad_base | 533 | /* Now branch to the common CPU resume function */ |
482 | ldr r3, [r4,#0xBC] | 534 | b cpu_resume |
483 | adds r3, r3, #16 | 535 | ENDPROC(omap3_restore) |
484 | 536 | ||
485 | ldmia r3!, {r4-r6} | 537 | .ltorg |
486 | mov sp, r4 @ Restore sp | ||
487 | msr spsr_cxsf, r5 @ Restore spsr | ||
488 | mov lr, r6 @ Restore lr | ||
489 | |||
490 | ldmia r3!, {r4-r7} | ||
491 | mcr p15, 0, r4, c1, c0, 2 @ Coprocessor access Control Register | ||
492 | mcr p15, 0, r5, c2, c0, 0 @ TTBR0 | ||
493 | mcr p15, 0, r6, c2, c0, 1 @ TTBR1 | ||
494 | mcr p15, 0, r7, c2, c0, 2 @ TTBCR | ||
495 | |||
496 | ldmia r3!,{r4-r6} | ||
497 | mcr p15, 0, r4, c3, c0, 0 @ Domain access Control Register | ||
498 | mcr p15, 0, r5, c10, c2, 0 @ PRRR | ||
499 | mcr p15, 0, r6, c10, c2, 1 @ NMRR | ||
500 | |||
501 | |||
502 | ldmia r3!,{r4-r7} | ||
503 | mcr p15, 0, r4, c13, c0, 1 @ Context ID | ||
504 | mcr p15, 0, r5, c13, c0, 2 @ User r/w thread and process ID | ||
505 | mrc p15, 0, r6, c12, c0, 0 @ Secure or NS vector base address | ||
506 | msr cpsr, r7 @ store cpsr | ||
507 | |||
508 | /* Enabling MMU here */ | ||
509 | mrc p15, 0, r7, c2, c0, 2 @ Read TTBRControl | ||
510 | /* Extract N (0:2) bits and decide whether to use TTBR0 or TTBR1 */ | ||
511 | and r7, #0x7 | ||
512 | cmp r7, #0x0 | ||
513 | beq usettbr0 | ||
514 | ttbr_error: | ||
515 | /* | ||
516 | * More work needs to be done to support N[0:2] value other than 0 | ||
517 | * So looping here so that the error can be detected | ||
518 | */ | ||
519 | b ttbr_error | ||
520 | usettbr0: | ||
521 | mrc p15, 0, r2, c2, c0, 0 | ||
522 | ldr r5, ttbrbit_mask | ||
523 | and r2, r5 | ||
524 | mov r4, pc | ||
525 | ldr r5, table_index_mask | ||
526 | and r4, r5 @ r4 = 31 to 20 bits of pc | ||
527 | /* Extract the value to be written to table entry */ | ||
528 | ldr r1, table_entry | ||
529 | /* r1 has the value to be written to table entry*/ | ||
530 | add r1, r1, r4 | ||
531 | /* Getting the address of table entry to modify */ | ||
532 | lsr r4, #18 | ||
533 | /* r2 has the location which needs to be modified */ | ||
534 | add r2, r4 | ||
535 | /* Storing previous entry of location being modified */ | ||
536 | ldr r5, scratchpad_base | ||
537 | ldr r4, [r2] | ||
538 | str r4, [r5, #0xC0] | ||
539 | /* Modify the table entry */ | ||
540 | str r1, [r2] | ||
541 | /* | ||
542 | * Storing address of entry being modified | ||
543 | * - will be restored after enabling MMU | ||
544 | */ | ||
545 | ldr r5, scratchpad_base | ||
546 | str r2, [r5, #0xC4] | ||
547 | |||
548 | mov r0, #0 | ||
549 | mcr p15, 0, r0, c7, c5, 4 @ Flush prefetch buffer | ||
550 | mcr p15, 0, r0, c7, c5, 6 @ Invalidate branch predictor array | ||
551 | mcr p15, 0, r0, c8, c5, 0 @ Invalidate instruction TLB | ||
552 | mcr p15, 0, r0, c8, c6, 0 @ Invalidate data TLB | ||
553 | /* | ||
554 | * Restore control register. This enables the MMU. | ||
555 | * The caches and prediction are not enabled here, they | ||
556 | * will be enabled after restoring the MMU table entry. | ||
557 | */ | ||
558 | ldmia r3!, {r4} | ||
559 | /* Store previous value of control register in scratchpad */ | ||
560 | str r4, [r5, #0xC8] | ||
561 | ldr r2, cache_pred_disable_mask | ||
562 | and r4, r2 | ||
563 | mcr p15, 0, r4, c1, c0, 0 | ||
564 | dsb | ||
565 | isb | ||
566 | ldr r0, =restoremmu_on | ||
567 | bx r0 | ||
568 | 538 | ||
569 | /* | 539 | /* |
570 | * ============================== | 540 | * Local variables |
571 | * == Exit point from OFF mode == | ||
572 | * ============================== | ||
573 | */ | 541 | */ |
574 | restoremmu_on: | 542 | pm_prepwstst_core_p: |
575 | ldmfd sp!, {r0-r12, pc} @ restore regs and return | 543 | .word PM_PREPWSTST_CORE_P |
576 | 544 | pm_pwstctrl_mpu: | |
545 | .word PM_PWSTCTRL_MPU_P | ||
546 | scratchpad_base: | ||
547 | .word SCRATCHPAD_BASE_P | ||
548 | sram_base: | ||
549 | .word SRAM_BASE_P + 0x8000 | ||
550 | control_stat: | ||
551 | .word CONTROL_STAT | ||
552 | control_mem_rta: | ||
553 | .word CONTROL_MEM_RTA_CTRL | ||
554 | l2dis_3630: | ||
555 | .word 0 | ||
577 | 556 | ||
578 | /* | 557 | /* |
579 | * Internal functions | 558 | * Internal functions |
580 | */ | 559 | */ |
581 | 560 | ||
582 | /* This function implements the erratum ID i443 WA, applies to 34xx >= ES3.0 */ | 561 | /* |
562 | * This function implements the erratum ID i443 WA, applies to 34xx >= ES3.0 | ||
563 | * Copied to and run from SRAM in order to reconfigure the SDRC parameters. | ||
564 | */ | ||
583 | .text | 565 | .text |
584 | .align 3 | 566 | .align 3 |
585 | ENTRY(es3_sdrc_fix) | 567 | ENTRY(es3_sdrc_fix) |
@@ -609,6 +591,9 @@ ENTRY(es3_sdrc_fix) | |||
609 | str r5, [r4] @ kick off refreshes | 591 | str r5, [r4] @ kick off refreshes |
610 | bx lr | 592 | bx lr |
611 | 593 | ||
594 | /* | ||
595 | * Local variables | ||
596 | */ | ||
612 | .align | 597 | .align |
613 | sdrc_syscfg: | 598 | sdrc_syscfg: |
614 | .word SDRC_SYSCONFIG_P | 599 | .word SDRC_SYSCONFIG_P |
@@ -627,128 +612,3 @@ sdrc_manual_1: | |||
627 | ENDPROC(es3_sdrc_fix) | 612 | ENDPROC(es3_sdrc_fix) |
628 | ENTRY(es3_sdrc_fix_sz) | 613 | ENTRY(es3_sdrc_fix_sz) |
629 | .word . - es3_sdrc_fix | 614 | .word . - es3_sdrc_fix |
630 | |||
631 | /* | ||
632 | * This function implements the erratum ID i581 WA: | ||
633 | * SDRC state restore before accessing the SDRAM | ||
634 | * | ||
635 | * Only used at return from non-OFF mode. For OFF | ||
636 | * mode the ROM code configures the SDRC and | ||
637 | * the DPLL before calling the restore code directly | ||
638 | * from DDR. | ||
639 | */ | ||
640 | |||
641 | /* Make sure SDRC accesses are ok */ | ||
642 | wait_sdrc_ok: | ||
643 | |||
644 | /* DPLL3 must be locked before accessing the SDRC. Maybe the HW ensures this */ | ||
645 | ldr r4, cm_idlest_ckgen | ||
646 | wait_dpll3_lock: | ||
647 | ldr r5, [r4] | ||
648 | tst r5, #1 | ||
649 | beq wait_dpll3_lock | ||
650 | |||
651 | ldr r4, cm_idlest1_core | ||
652 | wait_sdrc_ready: | ||
653 | ldr r5, [r4] | ||
654 | tst r5, #0x2 | ||
655 | bne wait_sdrc_ready | ||
656 | /* allow DLL powerdown upon hw idle req */ | ||
657 | ldr r4, sdrc_power | ||
658 | ldr r5, [r4] | ||
659 | bic r5, r5, #0x40 | ||
660 | str r5, [r4] | ||
661 | |||
662 | /* | ||
663 | * PC-relative stores lead to undefined behaviour in Thumb-2: use a r7 as a | ||
664 | * base instead. | ||
665 | * Be careful not to clobber r7 when maintaing this code. | ||
666 | */ | ||
667 | |||
668 | is_dll_in_lock_mode: | ||
669 | /* Is dll in lock mode? */ | ||
670 | ldr r4, sdrc_dlla_ctrl | ||
671 | ldr r5, [r4] | ||
672 | tst r5, #0x4 | ||
673 | bxne lr @ Return if locked | ||
674 | /* wait till dll locks */ | ||
675 | adr r7, kick_counter | ||
676 | wait_dll_lock_timed: | ||
677 | ldr r4, wait_dll_lock_counter | ||
678 | add r4, r4, #1 | ||
679 | str r4, [r7, #wait_dll_lock_counter - kick_counter] | ||
680 | ldr r4, sdrc_dlla_status | ||
681 | /* Wait 20uS for lock */ | ||
682 | mov r6, #8 | ||
683 | wait_dll_lock: | ||
684 | subs r6, r6, #0x1 | ||
685 | beq kick_dll | ||
686 | ldr r5, [r4] | ||
687 | and r5, r5, #0x4 | ||
688 | cmp r5, #0x4 | ||
689 | bne wait_dll_lock | ||
690 | bx lr @ Return when locked | ||
691 | |||
692 | /* disable/reenable DLL if not locked */ | ||
693 | kick_dll: | ||
694 | ldr r4, sdrc_dlla_ctrl | ||
695 | ldr r5, [r4] | ||
696 | mov r6, r5 | ||
697 | bic r6, #(1<<3) @ disable dll | ||
698 | str r6, [r4] | ||
699 | dsb | ||
700 | orr r6, r6, #(1<<3) @ enable dll | ||
701 | str r6, [r4] | ||
702 | dsb | ||
703 | ldr r4, kick_counter | ||
704 | add r4, r4, #1 | ||
705 | str r4, [r7] @ kick_counter | ||
706 | b wait_dll_lock_timed | ||
707 | |||
708 | .align | ||
709 | cm_idlest1_core: | ||
710 | .word CM_IDLEST1_CORE_V | ||
711 | cm_idlest_ckgen: | ||
712 | .word CM_IDLEST_CKGEN_V | ||
713 | sdrc_dlla_status: | ||
714 | .word SDRC_DLLA_STATUS_V | ||
715 | sdrc_dlla_ctrl: | ||
716 | .word SDRC_DLLA_CTRL_V | ||
717 | pm_prepwstst_core_p: | ||
718 | .word PM_PREPWSTST_CORE_P | ||
719 | pm_pwstctrl_mpu: | ||
720 | .word PM_PWSTCTRL_MPU_P | ||
721 | scratchpad_base: | ||
722 | .word SCRATCHPAD_BASE_P | ||
723 | sram_base: | ||
724 | .word SRAM_BASE_P + 0x8000 | ||
725 | sdrc_power: | ||
726 | .word SDRC_POWER_V | ||
727 | ttbrbit_mask: | ||
728 | .word 0xFFFFC000 | ||
729 | table_index_mask: | ||
730 | .word 0xFFF00000 | ||
731 | table_entry: | ||
732 | .word 0x00000C02 | ||
733 | cache_pred_disable_mask: | ||
734 | .word 0xFFFFE7FB | ||
735 | control_stat: | ||
736 | .word CONTROL_STAT | ||
737 | control_mem_rta: | ||
738 | .word CONTROL_MEM_RTA_CTRL | ||
739 | kernel_flush: | ||
740 | .word v7_flush_dcache_all | ||
741 | l2dis_3630: | ||
742 | .word 0 | ||
743 | /* | ||
744 | * When exporting to userspace while the counters are in SRAM, | ||
745 | * these 2 words need to be at the end to facilitate retrival! | ||
746 | */ | ||
747 | kick_counter: | ||
748 | .word 0 | ||
749 | wait_dll_lock_counter: | ||
750 | .word 0 | ||
751 | ENDPROC(omap34xx_cpu_suspend) | ||
752 | |||
753 | ENTRY(omap34xx_cpu_suspend_sz) | ||
754 | .word . - omap34xx_cpu_suspend | ||
diff --git a/arch/arm/mach-pnx4008/include/mach/entry-macro.S b/arch/arm/mach-pnx4008/include/mach/entry-macro.S index 8003037578ed..db7eeebf30d7 100644 --- a/arch/arm/mach-pnx4008/include/mach/entry-macro.S +++ b/arch/arm/mach-pnx4008/include/mach/entry-macro.S | |||
@@ -120,8 +120,3 @@ | |||
120 | 1003: | 120 | 1003: |
121 | .endm | 121 | .endm |
122 | 122 | ||
123 | |||
124 | .macro irq_prio_table | ||
125 | .endm | ||
126 | |||
127 | |||
diff --git a/arch/arm/mach-pxa/include/mach/pm.h b/arch/arm/mach-pxa/include/mach/pm.h index f15afe012995..51558bcee999 100644 --- a/arch/arm/mach-pxa/include/mach/pm.h +++ b/arch/arm/mach-pxa/include/mach/pm.h | |||
@@ -22,8 +22,8 @@ struct pxa_cpu_pm_fns { | |||
22 | extern struct pxa_cpu_pm_fns *pxa_cpu_pm_fns; | 22 | extern struct pxa_cpu_pm_fns *pxa_cpu_pm_fns; |
23 | 23 | ||
24 | /* sleep.S */ | 24 | /* sleep.S */ |
25 | extern void pxa25x_cpu_suspend(unsigned int, long); | 25 | extern int pxa25x_finish_suspend(unsigned long); |
26 | extern void pxa27x_cpu_suspend(unsigned int, long); | 26 | extern int pxa27x_finish_suspend(unsigned long); |
27 | 27 | ||
28 | extern int pxa_pm_enter(suspend_state_t state); | 28 | extern int pxa_pm_enter(suspend_state_t state); |
29 | extern int pxa_pm_prepare(void); | 29 | extern int pxa_pm_prepare(void); |
diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c index 87ae3129f4f7..b27544bcafcb 100644 --- a/arch/arm/mach-pxa/mfp-pxa2xx.c +++ b/arch/arm/mach-pxa/mfp-pxa2xx.c | |||
@@ -347,9 +347,9 @@ static int pxa2xx_mfp_suspend(void) | |||
347 | if ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) && | 347 | if ((gpio_desc[i].config & MFP_LPM_KEEP_OUTPUT) && |
348 | (GPDR(i) & GPIO_bit(i))) { | 348 | (GPDR(i) & GPIO_bit(i))) { |
349 | if (GPLR(i) & GPIO_bit(i)) | 349 | if (GPLR(i) & GPIO_bit(i)) |
350 | PGSR(i) |= GPIO_bit(i); | 350 | PGSR(gpio_to_bank(i)) |= GPIO_bit(i); |
351 | else | 351 | else |
352 | PGSR(i) &= ~GPIO_bit(i); | 352 | PGSR(gpio_to_bank(i)) &= ~GPIO_bit(i); |
353 | } | 353 | } |
354 | } | 354 | } |
355 | 355 | ||
diff --git a/arch/arm/mach-pxa/palmz72.c b/arch/arm/mach-pxa/palmz72.c index 65f24f0b77e8..5a5329bc33f1 100644 --- a/arch/arm/mach-pxa/palmz72.c +++ b/arch/arm/mach-pxa/palmz72.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/i2c-gpio.h> | 33 | #include <linux/i2c-gpio.h> |
34 | 34 | ||
35 | #include <asm/mach-types.h> | 35 | #include <asm/mach-types.h> |
36 | #include <asm/suspend.h> | ||
36 | #include <asm/mach/arch.h> | 37 | #include <asm/mach/arch.h> |
37 | #include <asm/mach/map.h> | 38 | #include <asm/mach/map.h> |
38 | 39 | ||
diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index 51e1583265b2..37178a8559b1 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c | |||
@@ -42,7 +42,6 @@ int pxa_pm_enter(suspend_state_t state) | |||
42 | 42 | ||
43 | /* *** go zzz *** */ | 43 | /* *** go zzz *** */ |
44 | pxa_cpu_pm_fns->enter(state); | 44 | pxa_cpu_pm_fns->enter(state); |
45 | cpu_init(); | ||
46 | 45 | ||
47 | if (state != PM_SUSPEND_STANDBY && pxa_cpu_pm_fns->restore) { | 46 | if (state != PM_SUSPEND_STANDBY && pxa_cpu_pm_fns->restore) { |
48 | /* after sleeping, validate the checksum */ | 47 | /* after sleeping, validate the checksum */ |
diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index fed363cec9c6..9c434d21a271 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/irq.h> | 25 | #include <linux/irq.h> |
26 | 26 | ||
27 | #include <asm/mach/map.h> | 27 | #include <asm/mach/map.h> |
28 | #include <asm/suspend.h> | ||
28 | #include <mach/hardware.h> | 29 | #include <mach/hardware.h> |
29 | #include <mach/irqs.h> | 30 | #include <mach/irqs.h> |
30 | #include <mach/gpio.h> | 31 | #include <mach/gpio.h> |
@@ -244,7 +245,7 @@ static void pxa25x_cpu_pm_enter(suspend_state_t state) | |||
244 | 245 | ||
245 | switch (state) { | 246 | switch (state) { |
246 | case PM_SUSPEND_MEM: | 247 | case PM_SUSPEND_MEM: |
247 | pxa25x_cpu_suspend(PWRMODE_SLEEP, PLAT_PHYS_OFFSET - PAGE_OFFSET); | 248 | cpu_suspend(PWRMODE_SLEEP, pxa25x_finish_suspend); |
248 | break; | 249 | break; |
249 | } | 250 | } |
250 | } | 251 | } |
diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 2fecbec58d88..9d2400b5f503 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <asm/mach/map.h> | 24 | #include <asm/mach/map.h> |
25 | #include <mach/hardware.h> | 25 | #include <mach/hardware.h> |
26 | #include <asm/irq.h> | 26 | #include <asm/irq.h> |
27 | #include <asm/suspend.h> | ||
27 | #include <mach/irqs.h> | 28 | #include <mach/irqs.h> |
28 | #include <mach/gpio.h> | 29 | #include <mach/gpio.h> |
29 | #include <mach/pxa27x.h> | 30 | #include <mach/pxa27x.h> |
@@ -284,6 +285,11 @@ void pxa27x_cpu_pm_restore(unsigned long *sleep_save) | |||
284 | void pxa27x_cpu_pm_enter(suspend_state_t state) | 285 | void pxa27x_cpu_pm_enter(suspend_state_t state) |
285 | { | 286 | { |
286 | extern void pxa_cpu_standby(void); | 287 | extern void pxa_cpu_standby(void); |
288 | #ifndef CONFIG_IWMMXT | ||
289 | u64 acc0; | ||
290 | |||
291 | asm volatile("mra %Q0, %R0, acc0" : "=r" (acc0)); | ||
292 | #endif | ||
287 | 293 | ||
288 | /* ensure voltage-change sequencer not initiated, which hangs */ | 294 | /* ensure voltage-change sequencer not initiated, which hangs */ |
289 | PCFR &= ~PCFR_FVC; | 295 | PCFR &= ~PCFR_FVC; |
@@ -299,7 +305,10 @@ void pxa27x_cpu_pm_enter(suspend_state_t state) | |||
299 | pxa_cpu_standby(); | 305 | pxa_cpu_standby(); |
300 | break; | 306 | break; |
301 | case PM_SUSPEND_MEM: | 307 | case PM_SUSPEND_MEM: |
302 | pxa27x_cpu_suspend(pwrmode, PLAT_PHYS_OFFSET - PAGE_OFFSET); | 308 | cpu_suspend(pwrmode, pxa27x_finish_suspend); |
309 | #ifndef CONFIG_IWMMXT | ||
310 | asm volatile("mar acc0, %Q0, %R0" : "=r" (acc0)); | ||
311 | #endif | ||
303 | break; | 312 | break; |
304 | } | 313 | } |
305 | } | 314 | } |
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 8521d7d6f1da..ef1c56a67afc 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/i2c/pxa-i2c.h> | 24 | #include <linux/i2c/pxa-i2c.h> |
25 | 25 | ||
26 | #include <asm/mach/map.h> | 26 | #include <asm/mach/map.h> |
27 | #include <asm/suspend.h> | ||
27 | #include <mach/hardware.h> | 28 | #include <mach/hardware.h> |
28 | #include <mach/gpio.h> | 29 | #include <mach/gpio.h> |
29 | #include <mach/pxa3xx-regs.h> | 30 | #include <mach/pxa3xx-regs.h> |
@@ -141,8 +142,13 @@ static void pxa3xx_cpu_pm_suspend(void) | |||
141 | { | 142 | { |
142 | volatile unsigned long *p = (volatile void *)0xc0000000; | 143 | volatile unsigned long *p = (volatile void *)0xc0000000; |
143 | unsigned long saved_data = *p; | 144 | unsigned long saved_data = *p; |
145 | #ifndef CONFIG_IWMMXT | ||
146 | u64 acc0; | ||
144 | 147 | ||
145 | extern void pxa3xx_cpu_suspend(long); | 148 | asm volatile("mra %Q0, %R0, acc0" : "=r" (acc0)); |
149 | #endif | ||
150 | |||
151 | extern int pxa3xx_finish_suspend(unsigned long); | ||
146 | 152 | ||
147 | /* resuming from D2 requires the HSIO2/BOOT/TPM clocks enabled */ | 153 | /* resuming from D2 requires the HSIO2/BOOT/TPM clocks enabled */ |
148 | CKENA |= (1 << CKEN_BOOT) | (1 << CKEN_TPM); | 154 | CKENA |= (1 << CKEN_BOOT) | (1 << CKEN_TPM); |
@@ -162,11 +168,15 @@ static void pxa3xx_cpu_pm_suspend(void) | |||
162 | /* overwrite with the resume address */ | 168 | /* overwrite with the resume address */ |
163 | *p = virt_to_phys(cpu_resume); | 169 | *p = virt_to_phys(cpu_resume); |
164 | 170 | ||
165 | pxa3xx_cpu_suspend(PLAT_PHYS_OFFSET - PAGE_OFFSET); | 171 | cpu_suspend(0, pxa3xx_finish_suspend); |
166 | 172 | ||
167 | *p = saved_data; | 173 | *p = saved_data; |
168 | 174 | ||
169 | AD3ER = 0; | 175 | AD3ER = 0; |
176 | |||
177 | #ifndef CONFIG_IWMMXT | ||
178 | asm volatile("mar acc0, %Q0, %R0" : "=r" (acc0)); | ||
179 | #endif | ||
170 | } | 180 | } |
171 | 181 | ||
172 | static void pxa3xx_cpu_pm_enter(suspend_state_t state) | 182 | static void pxa3xx_cpu_pm_enter(suspend_state_t state) |
diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index d130f77b6d11..2f37d43f51b6 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c | |||
@@ -573,10 +573,10 @@ static struct pxafb_mode_info sharp_lq043t3dx02_mode = { | |||
573 | .xres = 480, | 573 | .xres = 480, |
574 | .yres = 272, | 574 | .yres = 272, |
575 | .bpp = 16, | 575 | .bpp = 16, |
576 | .hsync_len = 4, | 576 | .hsync_len = 41, |
577 | .left_margin = 2, | 577 | .left_margin = 2, |
578 | .right_margin = 1, | 578 | .right_margin = 1, |
579 | .vsync_len = 1, | 579 | .vsync_len = 10, |
580 | .upper_margin = 3, | 580 | .upper_margin = 3, |
581 | .lower_margin = 1, | 581 | .lower_margin = 1, |
582 | .sync = 0, | 582 | .sync = 0, |
@@ -596,29 +596,31 @@ static void __init raumfeld_lcd_init(void) | |||
596 | { | 596 | { |
597 | int ret; | 597 | int ret; |
598 | 598 | ||
599 | pxa_set_fb_info(NULL, &raumfeld_sharp_lcd_info); | ||
600 | |||
601 | /* Earlier devices had the backlight regulator controlled | ||
602 | * via PWM, later versions use another controller for that */ | ||
603 | if ((system_rev & 0xff) < 2) { | ||
604 | mfp_cfg_t raumfeld_pwm_pin_config = GPIO17_PWM0_OUT; | ||
605 | pxa3xx_mfp_config(&raumfeld_pwm_pin_config, 1); | ||
606 | platform_device_register(&raumfeld_pwm_backlight_device); | ||
607 | } else | ||
608 | platform_device_register(&raumfeld_lt3593_device); | ||
609 | |||
610 | ret = gpio_request(GPIO_TFT_VA_EN, "display VA enable"); | 599 | ret = gpio_request(GPIO_TFT_VA_EN, "display VA enable"); |
611 | if (ret < 0) | 600 | if (ret < 0) |
612 | pr_warning("Unable to request GPIO_TFT_VA_EN\n"); | 601 | pr_warning("Unable to request GPIO_TFT_VA_EN\n"); |
613 | else | 602 | else |
614 | gpio_direction_output(GPIO_TFT_VA_EN, 1); | 603 | gpio_direction_output(GPIO_TFT_VA_EN, 1); |
615 | 604 | ||
605 | msleep(100); | ||
606 | |||
616 | ret = gpio_request(GPIO_DISPLAY_ENABLE, "display enable"); | 607 | ret = gpio_request(GPIO_DISPLAY_ENABLE, "display enable"); |
617 | if (ret < 0) | 608 | if (ret < 0) |
618 | pr_warning("Unable to request GPIO_DISPLAY_ENABLE\n"); | 609 | pr_warning("Unable to request GPIO_DISPLAY_ENABLE\n"); |
619 | else | 610 | else |
620 | gpio_direction_output(GPIO_DISPLAY_ENABLE, 1); | 611 | gpio_direction_output(GPIO_DISPLAY_ENABLE, 1); |
621 | 612 | ||
613 | /* Hardware revision 2 has the backlight regulator controlled | ||
614 | * by an LT3593, earlier and later devices use PWM for that. */ | ||
615 | if ((system_rev & 0xff) == 2) { | ||
616 | platform_device_register(&raumfeld_lt3593_device); | ||
617 | } else { | ||
618 | mfp_cfg_t raumfeld_pwm_pin_config = GPIO17_PWM0_OUT; | ||
619 | pxa3xx_mfp_config(&raumfeld_pwm_pin_config, 1); | ||
620 | platform_device_register(&raumfeld_pwm_backlight_device); | ||
621 | } | ||
622 | |||
623 | pxa_set_fb_info(NULL, &raumfeld_sharp_lcd_info); | ||
622 | platform_device_register(&pxa3xx_device_gcu); | 624 | platform_device_register(&pxa3xx_device_gcu); |
623 | } | 625 | } |
624 | 626 | ||
@@ -657,10 +659,10 @@ static struct lis3lv02d_platform_data lis3_pdata = { | |||
657 | 659 | ||
658 | #define SPI_AK4104 \ | 660 | #define SPI_AK4104 \ |
659 | { \ | 661 | { \ |
660 | .modalias = "ak4104", \ | 662 | .modalias = "ak4104-codec", \ |
661 | .max_speed_hz = 10000, \ | 663 | .max_speed_hz = 10000, \ |
662 | .bus_num = 0, \ | 664 | .bus_num = 0, \ |
663 | .chip_select = 0, \ | 665 | .chip_select = 0, \ |
664 | .controller_data = (void *) GPIO_SPDIF_CS, \ | 666 | .controller_data = (void *) GPIO_SPDIF_CS, \ |
665 | } | 667 | } |
666 | 668 | ||
diff --git a/arch/arm/mach-pxa/sleep.S b/arch/arm/mach-pxa/sleep.S index 6f5368899d84..1e544be9905d 100644 --- a/arch/arm/mach-pxa/sleep.S +++ b/arch/arm/mach-pxa/sleep.S | |||
@@ -24,20 +24,9 @@ | |||
24 | 24 | ||
25 | #ifdef CONFIG_PXA3xx | 25 | #ifdef CONFIG_PXA3xx |
26 | /* | 26 | /* |
27 | * pxa3xx_cpu_suspend() - forces CPU into sleep state (S2D3C4) | 27 | * pxa3xx_finish_suspend() - forces CPU into sleep state (S2D3C4) |
28 | * | ||
29 | * r0 = v:p offset | ||
30 | */ | 28 | */ |
31 | ENTRY(pxa3xx_cpu_suspend) | 29 | ENTRY(pxa3xx_finish_suspend) |
32 | |||
33 | #ifndef CONFIG_IWMMXT | ||
34 | mra r2, r3, acc0 | ||
35 | #endif | ||
36 | stmfd sp!, {r2 - r12, lr} @ save registers on stack | ||
37 | mov r1, r0 | ||
38 | ldr r3, =pxa_cpu_resume @ resume function | ||
39 | bl cpu_suspend | ||
40 | |||
41 | mov r0, #0x06 @ S2D3C4 mode | 30 | mov r0, #0x06 @ S2D3C4 mode |
42 | mcr p14, 0, r0, c7, c0, 0 @ enter sleep | 31 | mcr p14, 0, r0, c7, c0, 0 @ enter sleep |
43 | 32 | ||
@@ -46,28 +35,18 @@ ENTRY(pxa3xx_cpu_suspend) | |||
46 | 35 | ||
47 | #ifdef CONFIG_PXA27x | 36 | #ifdef CONFIG_PXA27x |
48 | /* | 37 | /* |
49 | * pxa27x_cpu_suspend() | 38 | * pxa27x_finish_suspend() |
50 | * | 39 | * |
51 | * Forces CPU into sleep state. | 40 | * Forces CPU into sleep state. |
52 | * | 41 | * |
53 | * r0 = value for PWRMODE M field for desired sleep state | 42 | * r0 = value for PWRMODE M field for desired sleep state |
54 | * r1 = v:p offset | ||
55 | */ | 43 | */ |
56 | ENTRY(pxa27x_cpu_suspend) | 44 | ENTRY(pxa27x_finish_suspend) |
57 | |||
58 | #ifndef CONFIG_IWMMXT | ||
59 | mra r2, r3, acc0 | ||
60 | #endif | ||
61 | stmfd sp!, {r2 - r12, lr} @ save registers on stack | ||
62 | mov r4, r0 @ save sleep mode | ||
63 | ldr r3, =pxa_cpu_resume @ resume function | ||
64 | bl cpu_suspend | ||
65 | |||
66 | @ Put the processor to sleep | 45 | @ Put the processor to sleep |
67 | @ (also workaround for sighting 28071) | 46 | @ (also workaround for sighting 28071) |
68 | 47 | ||
69 | @ prepare value for sleep mode | 48 | @ prepare value for sleep mode |
70 | mov r1, r4 @ sleep mode | 49 | mov r1, r0 @ sleep mode |
71 | 50 | ||
72 | @ prepare pointer to physical address 0 (virtual mapping in generic.c) | 51 | @ prepare pointer to physical address 0 (virtual mapping in generic.c) |
73 | mov r2, #UNCACHED_PHYS_0 | 52 | mov r2, #UNCACHED_PHYS_0 |
@@ -99,21 +78,16 @@ ENTRY(pxa27x_cpu_suspend) | |||
99 | 78 | ||
100 | #ifdef CONFIG_PXA25x | 79 | #ifdef CONFIG_PXA25x |
101 | /* | 80 | /* |
102 | * pxa25x_cpu_suspend() | 81 | * pxa25x_finish_suspend() |
103 | * | 82 | * |
104 | * Forces CPU into sleep state. | 83 | * Forces CPU into sleep state. |
105 | * | 84 | * |
106 | * r0 = value for PWRMODE M field for desired sleep state | 85 | * r0 = value for PWRMODE M field for desired sleep state |
107 | * r1 = v:p offset | ||
108 | */ | 86 | */ |
109 | 87 | ||
110 | ENTRY(pxa25x_cpu_suspend) | 88 | ENTRY(pxa25x_finish_suspend) |
111 | stmfd sp!, {r2 - r12, lr} @ save registers on stack | ||
112 | mov r4, r0 @ save sleep mode | ||
113 | ldr r3, =pxa_cpu_resume @ resume function | ||
114 | bl cpu_suspend | ||
115 | @ prepare value for sleep mode | 89 | @ prepare value for sleep mode |
116 | mov r1, r4 @ sleep mode | 90 | mov r1, r0 @ sleep mode |
117 | 91 | ||
118 | @ prepare pointer to physical address 0 (virtual mapping in generic.c) | 92 | @ prepare pointer to physical address 0 (virtual mapping in generic.c) |
119 | mov r2, #UNCACHED_PHYS_0 | 93 | mov r2, #UNCACHED_PHYS_0 |
@@ -195,16 +169,3 @@ pxa_cpu_do_suspend: | |||
195 | mcr p14, 0, r1, c7, c0, 0 @ PWRMODE | 169 | mcr p14, 0, r1, c7, c0, 0 @ PWRMODE |
196 | 170 | ||
197 | 20: b 20b @ loop waiting for sleep | 171 | 20: b 20b @ loop waiting for sleep |
198 | |||
199 | /* | ||
200 | * pxa_cpu_resume() | ||
201 | * | ||
202 | * entry point from bootloader into kernel during resume | ||
203 | */ | ||
204 | .align 5 | ||
205 | pxa_cpu_resume: | ||
206 | ldmfd sp!, {r2, r3} | ||
207 | #ifndef CONFIG_IWMMXT | ||
208 | mar acc0, r2, r3 | ||
209 | #endif | ||
210 | ldmfd sp!, {r4 - r12, pc} @ return to caller | ||
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c index 00363c7ac182..9b99cc164de5 100644 --- a/arch/arm/mach-pxa/zeus.c +++ b/arch/arm/mach-pxa/zeus.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/can/platform/mcp251x.h> | 31 | #include <linux/can/platform/mcp251x.h> |
32 | 32 | ||
33 | #include <asm/mach-types.h> | 33 | #include <asm/mach-types.h> |
34 | #include <asm/suspend.h> | ||
34 | #include <asm/mach/arch.h> | 35 | #include <asm/mach/arch.h> |
35 | #include <asm/mach/map.h> | 36 | #include <asm/mach/map.h> |
36 | 37 | ||
@@ -676,7 +677,7 @@ static struct pxa2xx_udc_mach_info zeus_udc_info = { | |||
676 | static void zeus_power_off(void) | 677 | static void zeus_power_off(void) |
677 | { | 678 | { |
678 | local_irq_disable(); | 679 | local_irq_disable(); |
679 | pxa27x_cpu_suspend(PWRMODE_DEEPSLEEP, PLAT_PHYS_OFFSET - PAGE_OFFSET); | 680 | cpu_suspend(PWRMODE_DEEPSLEEP, pxa27x_finish_suspend); |
680 | } | 681 | } |
681 | #else | 682 | #else |
682 | #define zeus_power_off NULL | 683 | #define zeus_power_off NULL |
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig index b9a9805e4828..dba6d0c1fc17 100644 --- a/arch/arm/mach-realview/Kconfig +++ b/arch/arm/mach-realview/Kconfig | |||
@@ -50,6 +50,7 @@ config MACH_REALVIEW_PB1176 | |||
50 | bool "Support RealView(R) Platform Baseboard for ARM1176JZF-S" | 50 | bool "Support RealView(R) Platform Baseboard for ARM1176JZF-S" |
51 | select CPU_V6 | 51 | select CPU_V6 |
52 | select ARM_GIC | 52 | select ARM_GIC |
53 | select HAVE_TCM | ||
53 | help | 54 | help |
54 | Include support for the ARM(R) RealView(R) Platform Baseboard for | 55 | Include support for the ARM(R) RealView(R) Platform Baseboard for |
55 | ARM1176JZF-S. | 56 | ARM1176JZF-S. |
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c index 963bf0d8119a..4ae943bafa92 100644 --- a/arch/arm/mach-realview/platsmp.c +++ b/arch/arm/mach-realview/platsmp.c | |||
@@ -68,14 +68,6 @@ void __init smp_init_cpus(void) | |||
68 | 68 | ||
69 | void __init platform_smp_prepare_cpus(unsigned int max_cpus) | 69 | void __init platform_smp_prepare_cpus(unsigned int max_cpus) |
70 | { | 70 | { |
71 | int i; | ||
72 | |||
73 | /* | ||
74 | * Initialise the present map, which describes the set of CPUs | ||
75 | * actually populated at the present time. | ||
76 | */ | ||
77 | for (i = 0; i < max_cpus; i++) | ||
78 | set_cpu_present(i, true); | ||
79 | 71 | ||
80 | scu_enable(scu_base_addr()); | 72 | scu_enable(scu_base_addr()); |
81 | 73 | ||
diff --git a/arch/arm/mach-s3c2412/pm.c b/arch/arm/mach-s3c2412/pm.c index 752b13a7b3db..f4077efa51fa 100644 --- a/arch/arm/mach-s3c2412/pm.c +++ b/arch/arm/mach-s3c2412/pm.c | |||
@@ -37,12 +37,10 @@ | |||
37 | 37 | ||
38 | extern void s3c2412_sleep_enter(void); | 38 | extern void s3c2412_sleep_enter(void); |
39 | 39 | ||
40 | static void s3c2412_cpu_suspend(void) | 40 | static int s3c2412_cpu_suspend(unsigned long arg) |
41 | { | 41 | { |
42 | unsigned long tmp; | 42 | unsigned long tmp; |
43 | 43 | ||
44 | flush_cache_all(); | ||
45 | |||
46 | /* set our standby method to sleep */ | 44 | /* set our standby method to sleep */ |
47 | 45 | ||
48 | tmp = __raw_readl(S3C2412_PWRCFG); | 46 | tmp = __raw_readl(S3C2412_PWRCFG); |
@@ -50,6 +48,8 @@ static void s3c2412_cpu_suspend(void) | |||
50 | __raw_writel(tmp, S3C2412_PWRCFG); | 48 | __raw_writel(tmp, S3C2412_PWRCFG); |
51 | 49 | ||
52 | s3c2412_sleep_enter(); | 50 | s3c2412_sleep_enter(); |
51 | |||
52 | panic("sleep resumed to originator?"); | ||
53 | } | 53 | } |
54 | 54 | ||
55 | static void s3c2412_pm_prepare(void) | 55 | static void s3c2412_pm_prepare(void) |
diff --git a/arch/arm/mach-s3c2416/pm.c b/arch/arm/mach-s3c2416/pm.c index 41db2b21e213..9ec54f1d8e75 100644 --- a/arch/arm/mach-s3c2416/pm.c +++ b/arch/arm/mach-s3c2416/pm.c | |||
@@ -24,10 +24,8 @@ | |||
24 | 24 | ||
25 | extern void s3c2412_sleep_enter(void); | 25 | extern void s3c2412_sleep_enter(void); |
26 | 26 | ||
27 | static void s3c2416_cpu_suspend(void) | 27 | static int s3c2416_cpu_suspend(unsigned long arg) |
28 | { | 28 | { |
29 | flush_cache_all(); | ||
30 | |||
31 | /* enable wakeup sources regardless of battery state */ | 29 | /* enable wakeup sources regardless of battery state */ |
32 | __raw_writel(S3C2443_PWRCFG_SLEEP, S3C2443_PWRCFG); | 30 | __raw_writel(S3C2443_PWRCFG_SLEEP, S3C2443_PWRCFG); |
33 | 31 | ||
@@ -35,6 +33,8 @@ static void s3c2416_cpu_suspend(void) | |||
35 | __raw_writel(0x2BED, S3C2443_PWRMODE); | 33 | __raw_writel(0x2BED, S3C2443_PWRMODE); |
36 | 34 | ||
37 | s3c2412_sleep_enter(); | 35 | s3c2412_sleep_enter(); |
36 | |||
37 | panic("sleep resumed to originator?"); | ||
38 | } | 38 | } |
39 | 39 | ||
40 | static void s3c2416_pm_prepare(void) | 40 | static void s3c2416_pm_prepare(void) |
diff --git a/arch/arm/mach-s3c2440/mach-mini2440.c b/arch/arm/mach-s3c2440/mach-mini2440.c index dd3120df09fe..fc2dc0b3d4fe 100644 --- a/arch/arm/mach-s3c2440/mach-mini2440.c +++ b/arch/arm/mach-s3c2440/mach-mini2440.c | |||
@@ -552,7 +552,7 @@ struct mini2440_features_t { | |||
552 | struct platform_device *optional[8]; | 552 | struct platform_device *optional[8]; |
553 | }; | 553 | }; |
554 | 554 | ||
555 | static void mini2440_parse_features( | 555 | static void __init mini2440_parse_features( |
556 | struct mini2440_features_t * features, | 556 | struct mini2440_features_t * features, |
557 | const char * features_str ) | 557 | const char * features_str ) |
558 | { | 558 | { |
diff --git a/arch/arm/mach-s3c64xx/dev-spi.c b/arch/arm/mach-s3c64xx/dev-spi.c index 82db072cb836..5e6b42089eb4 100644 --- a/arch/arm/mach-s3c64xx/dev-spi.c +++ b/arch/arm/mach-s3c64xx/dev-spi.c | |||
@@ -88,6 +88,7 @@ static struct s3c64xx_spi_info s3c64xx_spi0_pdata = { | |||
88 | .cfg_gpio = s3c64xx_spi_cfg_gpio, | 88 | .cfg_gpio = s3c64xx_spi_cfg_gpio, |
89 | .fifo_lvl_mask = 0x7f, | 89 | .fifo_lvl_mask = 0x7f, |
90 | .rx_lvl_offset = 13, | 90 | .rx_lvl_offset = 13, |
91 | .tx_st_done = 21, | ||
91 | }; | 92 | }; |
92 | 93 | ||
93 | static u64 spi_dmamask = DMA_BIT_MASK(32); | 94 | static u64 spi_dmamask = DMA_BIT_MASK(32); |
@@ -132,6 +133,7 @@ static struct s3c64xx_spi_info s3c64xx_spi1_pdata = { | |||
132 | .cfg_gpio = s3c64xx_spi_cfg_gpio, | 133 | .cfg_gpio = s3c64xx_spi_cfg_gpio, |
133 | .fifo_lvl_mask = 0x7f, | 134 | .fifo_lvl_mask = 0x7f, |
134 | .rx_lvl_offset = 13, | 135 | .rx_lvl_offset = 13, |
136 | .tx_st_done = 21, | ||
135 | }; | 137 | }; |
136 | 138 | ||
137 | struct platform_device s3c64xx_device_spi1 = { | 139 | struct platform_device s3c64xx_device_spi1 = { |
diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c index b197171e7d03..204bfafe4bfc 100644 --- a/arch/arm/mach-s3c64xx/dma.c +++ b/arch/arm/mach-s3c64xx/dma.c | |||
@@ -113,7 +113,7 @@ found: | |||
113 | return chan; | 113 | return chan; |
114 | } | 114 | } |
115 | 115 | ||
116 | int s3c2410_dma_config(unsigned int channel, int xferunit) | 116 | int s3c2410_dma_config(enum dma_ch channel, int xferunit) |
117 | { | 117 | { |
118 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); | 118 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); |
119 | 119 | ||
@@ -297,7 +297,7 @@ static int s3c64xx_dma_flush(struct s3c2410_dma_chan *chan) | |||
297 | return 0; | 297 | return 0; |
298 | } | 298 | } |
299 | 299 | ||
300 | int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op) | 300 | int s3c2410_dma_ctrl(enum dma_ch channel, enum s3c2410_chan_op op) |
301 | { | 301 | { |
302 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); | 302 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); |
303 | 303 | ||
@@ -331,7 +331,7 @@ EXPORT_SYMBOL(s3c2410_dma_ctrl); | |||
331 | * | 331 | * |
332 | */ | 332 | */ |
333 | 333 | ||
334 | int s3c2410_dma_enqueue(unsigned int channel, void *id, | 334 | int s3c2410_dma_enqueue(enum dma_ch channel, void *id, |
335 | dma_addr_t data, int size) | 335 | dma_addr_t data, int size) |
336 | { | 336 | { |
337 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); | 337 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); |
@@ -415,7 +415,7 @@ err_buff: | |||
415 | EXPORT_SYMBOL(s3c2410_dma_enqueue); | 415 | EXPORT_SYMBOL(s3c2410_dma_enqueue); |
416 | 416 | ||
417 | 417 | ||
418 | int s3c2410_dma_devconfig(unsigned int channel, | 418 | int s3c2410_dma_devconfig(enum dma_ch channel, |
419 | enum s3c2410_dmasrc source, | 419 | enum s3c2410_dmasrc source, |
420 | unsigned long devaddr) | 420 | unsigned long devaddr) |
421 | { | 421 | { |
@@ -463,7 +463,7 @@ int s3c2410_dma_devconfig(unsigned int channel, | |||
463 | EXPORT_SYMBOL(s3c2410_dma_devconfig); | 463 | EXPORT_SYMBOL(s3c2410_dma_devconfig); |
464 | 464 | ||
465 | 465 | ||
466 | int s3c2410_dma_getposition(unsigned int channel, | 466 | int s3c2410_dma_getposition(enum dma_ch channel, |
467 | dma_addr_t *src, dma_addr_t *dst) | 467 | dma_addr_t *src, dma_addr_t *dst) |
468 | { | 468 | { |
469 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); | 469 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); |
@@ -487,7 +487,7 @@ EXPORT_SYMBOL(s3c2410_dma_getposition); | |||
487 | * get control of an dma channel | 487 | * get control of an dma channel |
488 | */ | 488 | */ |
489 | 489 | ||
490 | int s3c2410_dma_request(unsigned int channel, | 490 | int s3c2410_dma_request(enum dma_ch channel, |
491 | struct s3c2410_dma_client *client, | 491 | struct s3c2410_dma_client *client, |
492 | void *dev) | 492 | void *dev) |
493 | { | 493 | { |
@@ -533,7 +533,7 @@ EXPORT_SYMBOL(s3c2410_dma_request); | |||
533 | * allowed to go through. | 533 | * allowed to go through. |
534 | */ | 534 | */ |
535 | 535 | ||
536 | int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client) | 536 | int s3c2410_dma_free(enum dma_ch channel, struct s3c2410_dma_client *client) |
537 | { | 537 | { |
538 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); | 538 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); |
539 | unsigned long flags; | 539 | unsigned long flags; |
diff --git a/arch/arm/mach-s3c64xx/pm.c b/arch/arm/mach-s3c64xx/pm.c index bc1c470b7de6..8bad64370689 100644 --- a/arch/arm/mach-s3c64xx/pm.c +++ b/arch/arm/mach-s3c64xx/pm.c | |||
@@ -112,7 +112,7 @@ void s3c_pm_save_core(void) | |||
112 | * this. | 112 | * this. |
113 | */ | 113 | */ |
114 | 114 | ||
115 | static void s3c64xx_cpu_suspend(void) | 115 | static int s3c64xx_cpu_suspend(unsigned long arg) |
116 | { | 116 | { |
117 | unsigned long tmp; | 117 | unsigned long tmp; |
118 | 118 | ||
diff --git a/arch/arm/mach-s3c64xx/sleep.S b/arch/arm/mach-s3c64xx/sleep.S index 1f87732b2320..34313f9c8792 100644 --- a/arch/arm/mach-s3c64xx/sleep.S +++ b/arch/arm/mach-s3c64xx/sleep.S | |||
@@ -25,29 +25,6 @@ | |||
25 | 25 | ||
26 | .text | 26 | .text |
27 | 27 | ||
28 | /* s3c_cpu_save | ||
29 | * | ||
30 | * Save enough processor state to allow the restart of the pm.c | ||
31 | * code after resume. | ||
32 | * | ||
33 | * entry: | ||
34 | * r1 = v:p offset | ||
35 | */ | ||
36 | |||
37 | ENTRY(s3c_cpu_save) | ||
38 | stmfd sp!, { r4 - r12, lr } | ||
39 | ldr r3, =resume_with_mmu | ||
40 | bl cpu_suspend | ||
41 | |||
42 | @@ call final suspend code | ||
43 | ldr r0, =pm_cpu_sleep | ||
44 | ldr pc, [r0] | ||
45 | |||
46 | @@ return to the caller, after the MMU is turned on. | ||
47 | @@ restore the last bits of the stack and return. | ||
48 | resume_with_mmu: | ||
49 | ldmfd sp!, { r4 - r12, pc } @ return, from sp from s3c_cpu_save | ||
50 | |||
51 | /* Sleep magic, the word before the resume entry point so that the | 28 | /* Sleep magic, the word before the resume entry point so that the |
52 | * bootloader can check for a resumeable image. */ | 29 | * bootloader can check for a resumeable image. */ |
53 | 30 | ||
diff --git a/arch/arm/mach-s5p64x0/dev-spi.c b/arch/arm/mach-s5p64x0/dev-spi.c index e78ee18c76e3..ac825e826326 100644 --- a/arch/arm/mach-s5p64x0/dev-spi.c +++ b/arch/arm/mach-s5p64x0/dev-spi.c | |||
@@ -112,12 +112,14 @@ static struct s3c64xx_spi_info s5p6440_spi0_pdata = { | |||
112 | .cfg_gpio = s5p6440_spi_cfg_gpio, | 112 | .cfg_gpio = s5p6440_spi_cfg_gpio, |
113 | .fifo_lvl_mask = 0x1ff, | 113 | .fifo_lvl_mask = 0x1ff, |
114 | .rx_lvl_offset = 15, | 114 | .rx_lvl_offset = 15, |
115 | .tx_st_done = 25, | ||
115 | }; | 116 | }; |
116 | 117 | ||
117 | static struct s3c64xx_spi_info s5p6450_spi0_pdata = { | 118 | static struct s3c64xx_spi_info s5p6450_spi0_pdata = { |
118 | .cfg_gpio = s5p6450_spi_cfg_gpio, | 119 | .cfg_gpio = s5p6450_spi_cfg_gpio, |
119 | .fifo_lvl_mask = 0x1ff, | 120 | .fifo_lvl_mask = 0x1ff, |
120 | .rx_lvl_offset = 15, | 121 | .rx_lvl_offset = 15, |
122 | .tx_st_done = 25, | ||
121 | }; | 123 | }; |
122 | 124 | ||
123 | static u64 spi_dmamask = DMA_BIT_MASK(32); | 125 | static u64 spi_dmamask = DMA_BIT_MASK(32); |
@@ -160,12 +162,14 @@ static struct s3c64xx_spi_info s5p6440_spi1_pdata = { | |||
160 | .cfg_gpio = s5p6440_spi_cfg_gpio, | 162 | .cfg_gpio = s5p6440_spi_cfg_gpio, |
161 | .fifo_lvl_mask = 0x7f, | 163 | .fifo_lvl_mask = 0x7f, |
162 | .rx_lvl_offset = 15, | 164 | .rx_lvl_offset = 15, |
165 | .tx_st_done = 25, | ||
163 | }; | 166 | }; |
164 | 167 | ||
165 | static struct s3c64xx_spi_info s5p6450_spi1_pdata = { | 168 | static struct s3c64xx_spi_info s5p6450_spi1_pdata = { |
166 | .cfg_gpio = s5p6450_spi_cfg_gpio, | 169 | .cfg_gpio = s5p6450_spi_cfg_gpio, |
167 | .fifo_lvl_mask = 0x7f, | 170 | .fifo_lvl_mask = 0x7f, |
168 | .rx_lvl_offset = 15, | 171 | .rx_lvl_offset = 15, |
172 | .tx_st_done = 25, | ||
169 | }; | 173 | }; |
170 | 174 | ||
171 | struct platform_device s5p64x0_device_spi1 = { | 175 | struct platform_device s5p64x0_device_spi1 = { |
diff --git a/arch/arm/mach-s5pc100/dev-spi.c b/arch/arm/mach-s5pc100/dev-spi.c index 57b19794d9bb..e5d6c4dceb56 100644 --- a/arch/arm/mach-s5pc100/dev-spi.c +++ b/arch/arm/mach-s5pc100/dev-spi.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <mach/dma.h> | 15 | #include <mach/dma.h> |
16 | #include <mach/map.h> | 16 | #include <mach/map.h> |
17 | #include <mach/spi-clocks.h> | 17 | #include <mach/spi-clocks.h> |
18 | #include <mach/irqs.h> | ||
18 | 19 | ||
19 | #include <plat/s3c64xx-spi.h> | 20 | #include <plat/s3c64xx-spi.h> |
20 | #include <plat/gpio-cfg.h> | 21 | #include <plat/gpio-cfg.h> |
@@ -90,6 +91,7 @@ static struct s3c64xx_spi_info s5pc100_spi0_pdata = { | |||
90 | .fifo_lvl_mask = 0x7f, | 91 | .fifo_lvl_mask = 0x7f, |
91 | .rx_lvl_offset = 13, | 92 | .rx_lvl_offset = 13, |
92 | .high_speed = 1, | 93 | .high_speed = 1, |
94 | .tx_st_done = 21, | ||
93 | }; | 95 | }; |
94 | 96 | ||
95 | static u64 spi_dmamask = DMA_BIT_MASK(32); | 97 | static u64 spi_dmamask = DMA_BIT_MASK(32); |
@@ -134,6 +136,7 @@ static struct s3c64xx_spi_info s5pc100_spi1_pdata = { | |||
134 | .fifo_lvl_mask = 0x7f, | 136 | .fifo_lvl_mask = 0x7f, |
135 | .rx_lvl_offset = 13, | 137 | .rx_lvl_offset = 13, |
136 | .high_speed = 1, | 138 | .high_speed = 1, |
139 | .tx_st_done = 21, | ||
137 | }; | 140 | }; |
138 | 141 | ||
139 | struct platform_device s5pc100_device_spi1 = { | 142 | struct platform_device s5pc100_device_spi1 = { |
@@ -176,6 +179,7 @@ static struct s3c64xx_spi_info s5pc100_spi2_pdata = { | |||
176 | .fifo_lvl_mask = 0x7f, | 179 | .fifo_lvl_mask = 0x7f, |
177 | .rx_lvl_offset = 13, | 180 | .rx_lvl_offset = 13, |
178 | .high_speed = 1, | 181 | .high_speed = 1, |
182 | .tx_st_done = 21, | ||
179 | }; | 183 | }; |
180 | 184 | ||
181 | struct platform_device s5pc100_device_spi2 = { | 185 | struct platform_device s5pc100_device_spi2 = { |
diff --git a/arch/arm/mach-s5pv210/dev-spi.c b/arch/arm/mach-s5pv210/dev-spi.c index e3249a47e3b1..eaf9a7bff7a0 100644 --- a/arch/arm/mach-s5pv210/dev-spi.c +++ b/arch/arm/mach-s5pv210/dev-spi.c | |||
@@ -85,6 +85,7 @@ static struct s3c64xx_spi_info s5pv210_spi0_pdata = { | |||
85 | .fifo_lvl_mask = 0x1ff, | 85 | .fifo_lvl_mask = 0x1ff, |
86 | .rx_lvl_offset = 15, | 86 | .rx_lvl_offset = 15, |
87 | .high_speed = 1, | 87 | .high_speed = 1, |
88 | .tx_st_done = 25, | ||
88 | }; | 89 | }; |
89 | 90 | ||
90 | static u64 spi_dmamask = DMA_BIT_MASK(32); | 91 | static u64 spi_dmamask = DMA_BIT_MASK(32); |
@@ -129,6 +130,7 @@ static struct s3c64xx_spi_info s5pv210_spi1_pdata = { | |||
129 | .fifo_lvl_mask = 0x7f, | 130 | .fifo_lvl_mask = 0x7f, |
130 | .rx_lvl_offset = 15, | 131 | .rx_lvl_offset = 15, |
131 | .high_speed = 1, | 132 | .high_speed = 1, |
133 | .tx_st_done = 25, | ||
132 | }; | 134 | }; |
133 | 135 | ||
134 | struct platform_device s5pv210_device_spi1 = { | 136 | struct platform_device s5pv210_device_spi1 = { |
diff --git a/arch/arm/mach-s5pv210/pm.c b/arch/arm/mach-s5pv210/pm.c index 24febae3d4c0..309e388a8a83 100644 --- a/arch/arm/mach-s5pv210/pm.c +++ b/arch/arm/mach-s5pv210/pm.c | |||
@@ -88,7 +88,7 @@ static struct sleep_save s5pv210_core_save[] = { | |||
88 | SAVE_ITEM(S3C2410_TCNTO(0)), | 88 | SAVE_ITEM(S3C2410_TCNTO(0)), |
89 | }; | 89 | }; |
90 | 90 | ||
91 | void s5pv210_cpu_suspend(void) | 91 | void s5pv210_cpu_suspend(unsigned long arg) |
92 | { | 92 | { |
93 | unsigned long tmp; | 93 | unsigned long tmp; |
94 | 94 | ||
diff --git a/arch/arm/mach-s5pv210/sleep.S b/arch/arm/mach-s5pv210/sleep.S index a3d649466fb1..e3452ccd4b08 100644 --- a/arch/arm/mach-s5pv210/sleep.S +++ b/arch/arm/mach-s5pv210/sleep.S | |||
@@ -32,27 +32,6 @@ | |||
32 | 32 | ||
33 | .text | 33 | .text |
34 | 34 | ||
35 | /* s3c_cpu_save | ||
36 | * | ||
37 | * entry: | ||
38 | * r1 = v:p offset | ||
39 | */ | ||
40 | |||
41 | ENTRY(s3c_cpu_save) | ||
42 | |||
43 | stmfd sp!, { r3 - r12, lr } | ||
44 | ldr r3, =resume_with_mmu | ||
45 | bl cpu_suspend | ||
46 | |||
47 | ldr r0, =pm_cpu_sleep | ||
48 | ldr r0, [ r0 ] | ||
49 | mov pc, r0 | ||
50 | |||
51 | resume_with_mmu: | ||
52 | ldmfd sp!, { r3 - r12, pc } | ||
53 | |||
54 | .ltorg | ||
55 | |||
56 | /* sleep magic, to allow the bootloader to check for an valid | 35 | /* sleep magic, to allow the bootloader to check for an valid |
57 | * image to resume to. Must be the first word before the | 36 | * image to resume to. Must be the first word before the |
58 | * s3c_cpu_resume entry. | 37 | * s3c_cpu_resume entry. |
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c index c4661aab22fb..bf85b8b259d5 100644 --- a/arch/arm/mach-sa1100/pm.c +++ b/arch/arm/mach-sa1100/pm.c | |||
@@ -29,10 +29,11 @@ | |||
29 | 29 | ||
30 | #include <mach/hardware.h> | 30 | #include <mach/hardware.h> |
31 | #include <asm/memory.h> | 31 | #include <asm/memory.h> |
32 | #include <asm/suspend.h> | ||
32 | #include <asm/system.h> | 33 | #include <asm/system.h> |
33 | #include <asm/mach/time.h> | 34 | #include <asm/mach/time.h> |
34 | 35 | ||
35 | extern void sa1100_cpu_suspend(long); | 36 | extern int sa1100_finish_suspend(unsigned long); |
36 | 37 | ||
37 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x | 38 | #define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x |
38 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] | 39 | #define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x] |
@@ -75,9 +76,7 @@ static int sa11x0_pm_enter(suspend_state_t state) | |||
75 | PSPR = virt_to_phys(cpu_resume); | 76 | PSPR = virt_to_phys(cpu_resume); |
76 | 77 | ||
77 | /* go zzz */ | 78 | /* go zzz */ |
78 | sa1100_cpu_suspend(PLAT_PHYS_OFFSET - PAGE_OFFSET); | 79 | cpu_suspend(0, sa1100_finish_suspend); |
79 | |||
80 | cpu_init(); | ||
81 | 80 | ||
82 | /* | 81 | /* |
83 | * Ensure not to come back here if it wasn't intended | 82 | * Ensure not to come back here if it wasn't intended |
diff --git a/arch/arm/mach-sa1100/sleep.S b/arch/arm/mach-sa1100/sleep.S index 04f2a618d4ef..e8223315b442 100644 --- a/arch/arm/mach-sa1100/sleep.S +++ b/arch/arm/mach-sa1100/sleep.S | |||
@@ -22,18 +22,13 @@ | |||
22 | 22 | ||
23 | .text | 23 | .text |
24 | /* | 24 | /* |
25 | * sa1100_cpu_suspend() | 25 | * sa1100_finish_suspend() |
26 | * | 26 | * |
27 | * Causes sa11x0 to enter sleep state | 27 | * Causes sa11x0 to enter sleep state |
28 | * | 28 | * |
29 | */ | 29 | */ |
30 | 30 | ||
31 | ENTRY(sa1100_cpu_suspend) | 31 | ENTRY(sa1100_finish_suspend) |
32 | stmfd sp!, {r4 - r12, lr} @ save registers on stack | ||
33 | mov r1, r0 | ||
34 | ldr r3, =sa1100_cpu_resume @ return function | ||
35 | bl cpu_suspend | ||
36 | |||
37 | @ disable clock switching | 32 | @ disable clock switching |
38 | mcr p15, 0, r1, c15, c2, 2 | 33 | mcr p15, 0, r1, c15, c2, 2 |
39 | 34 | ||
@@ -139,13 +134,3 @@ sa1110_sdram_controller_fix: | |||
139 | str r13, [r12] | 134 | str r13, [r12] |
140 | 135 | ||
141 | 20: b 20b @ loop waiting for sleep | 136 | 20: b 20b @ loop waiting for sleep |
142 | |||
143 | /* | ||
144 | * cpu_sa1100_resume() | ||
145 | * | ||
146 | * entry point from bootloader into kernel during resume | ||
147 | */ | ||
148 | .align 5 | ||
149 | sa1100_cpu_resume: | ||
150 | mcr p15, 0, r1, c15, c1, 2 @ enable clock switching | ||
151 | ldmfd sp!, {r4 - r12, pc} @ return to caller | ||
diff --git a/arch/arm/mach-shark/include/mach/entry-macro.S b/arch/arm/mach-shark/include/mach/entry-macro.S index e2853c0a3333..0bb6cc626eb7 100644 --- a/arch/arm/mach-shark/include/mach/entry-macro.S +++ b/arch/arm/mach-shark/include/mach/entry-macro.S | |||
@@ -11,17 +11,17 @@ | |||
11 | .endm | 11 | .endm |
12 | 12 | ||
13 | .macro get_irqnr_preamble, base, tmp | 13 | .macro get_irqnr_preamble, base, tmp |
14 | mov \base, #0xe0000000 | ||
14 | .endm | 15 | .endm |
15 | 16 | ||
16 | .macro arch_ret_to_user, tmp1, tmp2 | 17 | .macro arch_ret_to_user, tmp1, tmp2 |
17 | .endm | 18 | .endm |
18 | 19 | ||
19 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp | 20 | .macro get_irqnr_and_base, irqnr, irqstat, base, tmp |
20 | mov r4, #0xe0000000 | ||
21 | 21 | ||
22 | mov \irqstat, #0x0C | 22 | mov \irqstat, #0x0C |
23 | strb \irqstat, [r4, #0x20] @outb(0x0C, 0x20) /* Poll command */ | 23 | strb \irqstat, [\base, #0x20] @outb(0x0C, 0x20) /* Poll command */ |
24 | ldrb \irqnr, [r4, #0x20] @irq = inb(0x20) & 7 | 24 | ldrb \irqnr, [\base, #0x20] @irq = inb(0x20) & 7 |
25 | and \irqstat, \irqnr, #0x80 | 25 | and \irqstat, \irqnr, #0x80 |
26 | teq \irqstat, #0 | 26 | teq \irqstat, #0 |
27 | beq 43f | 27 | beq 43f |
@@ -29,8 +29,8 @@ | |||
29 | teq \irqnr, #2 | 29 | teq \irqnr, #2 |
30 | bne 44f | 30 | bne 44f |
31 | 43: mov \irqstat, #0x0C | 31 | 43: mov \irqstat, #0x0C |
32 | strb \irqstat, [r4, #0xa0] @outb(0x0C, 0xA0) /* Poll command */ | 32 | strb \irqstat, [\base, #0xa0] @outb(0x0C, 0xA0) /* Poll command */ |
33 | ldrb \irqnr, [r4, #0xa0] @irq = (inb(0xA0) & 7) + 8 | 33 | ldrb \irqnr, [\base, #0xa0] @irq = (inb(0xA0) & 7) + 8 |
34 | and \irqstat, \irqnr, #0x80 | 34 | and \irqstat, \irqnr, #0x80 |
35 | teq \irqstat, #0 | 35 | teq \irqstat, #0 |
36 | beq 44f | 36 | beq 44f |
diff --git a/arch/arm/mach-shmobile/include/mach/sdhi-sh7372.h b/arch/arm/mach-shmobile/include/mach/sdhi-sh7372.h new file mode 100644 index 000000000000..4a81b01f1e8f --- /dev/null +++ b/arch/arm/mach-shmobile/include/mach/sdhi-sh7372.h | |||
@@ -0,0 +1,21 @@ | |||
1 | #ifndef SDHI_SH7372_H | ||
2 | #define SDHI_SH7372_H | ||
3 | |||
4 | #define SDGENCNTA 0xfe40009c | ||
5 | |||
6 | /* The countdown of SDGENCNTA is controlled by | ||
7 | * ZB3D2CLK which runs at 149.5MHz. | ||
8 | * That is 149.5ticks/us. Approximate this as 150ticks/us. | ||
9 | */ | ||
10 | static void udelay(int us) | ||
11 | { | ||
12 | __raw_writel(us * 150, SDGENCNTA); | ||
13 | while(__raw_readl(SDGENCNTA)) ; | ||
14 | } | ||
15 | |||
16 | static void msleep(int ms) | ||
17 | { | ||
18 | udelay(ms * 1000); | ||
19 | } | ||
20 | |||
21 | #endif | ||
diff --git a/arch/arm/mach-shmobile/include/mach/sdhi.h b/arch/arm/mach-shmobile/include/mach/sdhi.h new file mode 100644 index 000000000000..0ec9e69f2c3b --- /dev/null +++ b/arch/arm/mach-shmobile/include/mach/sdhi.h | |||
@@ -0,0 +1,16 @@ | |||
1 | #ifndef SDHI_H | ||
2 | #define SDHI_H | ||
3 | |||
4 | /************************************************** | ||
5 | * | ||
6 | * CPU specific settings | ||
7 | * | ||
8 | **************************************************/ | ||
9 | |||
10 | #ifdef CONFIG_ARCH_SH7372 | ||
11 | #include "mach/sdhi-sh7372.h" | ||
12 | #else | ||
13 | #error "unsupported CPU." | ||
14 | #endif | ||
15 | |||
16 | #endif /* SDHI_H */ | ||
diff --git a/arch/arm/mach-shmobile/platsmp.c b/arch/arm/mach-shmobile/platsmp.c index f3888feb1c68..66f980625a33 100644 --- a/arch/arm/mach-shmobile/platsmp.c +++ b/arch/arm/mach-shmobile/platsmp.c | |||
@@ -64,10 +64,5 @@ void __init smp_init_cpus(void) | |||
64 | 64 | ||
65 | void __init platform_smp_prepare_cpus(unsigned int max_cpus) | 65 | void __init platform_smp_prepare_cpus(unsigned int max_cpus) |
66 | { | 66 | { |
67 | int i; | ||
68 | |||
69 | for (i = 0; i < max_cpus; i++) | ||
70 | set_cpu_present(i, true); | ||
71 | |||
72 | shmobile_smp_prepare_cpus(); | 67 | shmobile_smp_prepare_cpus(); |
73 | } | 68 | } |
diff --git a/arch/arm/mach-tegra/platsmp.c b/arch/arm/mach-tegra/platsmp.c index b8ae3c978dee..1a594dce8fbc 100644 --- a/arch/arm/mach-tegra/platsmp.c +++ b/arch/arm/mach-tegra/platsmp.c | |||
@@ -129,14 +129,6 @@ void __init smp_init_cpus(void) | |||
129 | 129 | ||
130 | void __init platform_smp_prepare_cpus(unsigned int max_cpus) | 130 | void __init platform_smp_prepare_cpus(unsigned int max_cpus) |
131 | { | 131 | { |
132 | int i; | ||
133 | |||
134 | /* | ||
135 | * Initialise the present map, which describes the set of CPUs | ||
136 | * actually populated at the present time. | ||
137 | */ | ||
138 | for (i = 0; i < max_cpus; i++) | ||
139 | set_cpu_present(i, true); | ||
140 | 132 | ||
141 | scu_enable(scu_base); | 133 | scu_enable(scu_base); |
142 | } | 134 | } |
diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index 0c527fe2cebb..a33df5f4c27a 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c | |||
@@ -172,14 +172,6 @@ void __init smp_init_cpus(void) | |||
172 | 172 | ||
173 | void __init platform_smp_prepare_cpus(unsigned int max_cpus) | 173 | void __init platform_smp_prepare_cpus(unsigned int max_cpus) |
174 | { | 174 | { |
175 | int i; | ||
176 | |||
177 | /* | ||
178 | * Initialise the present map, which describes the set of CPUs | ||
179 | * actually populated at the present time. | ||
180 | */ | ||
181 | for (i = 0; i < max_cpus; i++) | ||
182 | set_cpu_present(i, true); | ||
183 | 175 | ||
184 | scu_enable(scu_base_addr()); | 176 | scu_enable(scu_base_addr()); |
185 | wakeup_secondary(); | 177 | wakeup_secondary(); |
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c index 765a71ff7f3b..bfd32f52c2db 100644 --- a/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/arch/arm/mach-vexpress/ct-ca9x4.c | |||
@@ -229,10 +229,6 @@ static void ct_ca9x4_init_cpu_map(void) | |||
229 | 229 | ||
230 | static void ct_ca9x4_smp_enable(unsigned int max_cpus) | 230 | static void ct_ca9x4_smp_enable(unsigned int max_cpus) |
231 | { | 231 | { |
232 | int i; | ||
233 | for (i = 0; i < max_cpus; i++) | ||
234 | set_cpu_present(i, true); | ||
235 | |||
236 | scu_enable(MMIO_P2V(A9_MPCORE_SCU)); | 232 | scu_enable(MMIO_P2V(A9_MPCORE_SCU)); |
237 | } | 233 | } |
238 | #endif | 234 | #endif |
diff --git a/arch/arm/mach-vt8500/irq.c b/arch/arm/mach-vt8500/irq.c index 245140c0df10..642de0408f25 100644 --- a/arch/arm/mach-vt8500/irq.c +++ b/arch/arm/mach-vt8500/irq.c | |||
@@ -39,9 +39,10 @@ | |||
39 | static void __iomem *ic_regbase; | 39 | static void __iomem *ic_regbase; |
40 | static void __iomem *sic_regbase; | 40 | static void __iomem *sic_regbase; |
41 | 41 | ||
42 | static void vt8500_irq_mask(unsigned int irq) | 42 | static void vt8500_irq_mask(struct irq_data *d) |
43 | { | 43 | { |
44 | void __iomem *base = ic_regbase; | 44 | void __iomem *base = ic_regbase; |
45 | unsigned irq = d->irq; | ||
45 | u8 edge; | 46 | u8 edge; |
46 | 47 | ||
47 | if (irq >= 64) { | 48 | if (irq >= 64) { |
@@ -64,9 +65,10 @@ static void vt8500_irq_mask(unsigned int irq) | |||
64 | } | 65 | } |
65 | } | 66 | } |
66 | 67 | ||
67 | static void vt8500_irq_unmask(unsigned int irq) | 68 | static void vt8500_irq_unmask(struct irq_data *d) |
68 | { | 69 | { |
69 | void __iomem *base = ic_regbase; | 70 | void __iomem *base = ic_regbase; |
71 | unsigned irq = d->irq; | ||
70 | u8 dctr; | 72 | u8 dctr; |
71 | 73 | ||
72 | if (irq >= 64) { | 74 | if (irq >= 64) { |
@@ -78,10 +80,11 @@ static void vt8500_irq_unmask(unsigned int irq) | |||
78 | writeb(dctr, base + VT8500_IC_DCTR + irq); | 80 | writeb(dctr, base + VT8500_IC_DCTR + irq); |
79 | } | 81 | } |
80 | 82 | ||
81 | static int vt8500_irq_set_type(unsigned int irq, unsigned int flow_type) | 83 | static int vt8500_irq_set_type(struct irq_data *d, unsigned int flow_type) |
82 | { | 84 | { |
83 | void __iomem *base = ic_regbase; | 85 | void __iomem *base = ic_regbase; |
84 | unsigned int orig_irq = irq; | 86 | unsigned irq = d->irq; |
87 | unsigned orig_irq = irq; | ||
85 | u8 dctr; | 88 | u8 dctr; |
86 | 89 | ||
87 | if (irq >= 64) { | 90 | if (irq >= 64) { |
@@ -114,11 +117,11 @@ static int vt8500_irq_set_type(unsigned int irq, unsigned int flow_type) | |||
114 | } | 117 | } |
115 | 118 | ||
116 | static struct irq_chip vt8500_irq_chip = { | 119 | static struct irq_chip vt8500_irq_chip = { |
117 | .name = "vt8500", | 120 | .name = "vt8500", |
118 | .ack = vt8500_irq_mask, | 121 | .irq_ack = vt8500_irq_mask, |
119 | .mask = vt8500_irq_mask, | 122 | .irq_mask = vt8500_irq_mask, |
120 | .unmask = vt8500_irq_unmask, | 123 | .irq_unmask = vt8500_irq_unmask, |
121 | .set_type = vt8500_irq_set_type, | 124 | .irq_set_type = vt8500_irq_set_type, |
122 | }; | 125 | }; |
123 | 126 | ||
124 | void __init vt8500_init_irq(void) | 127 | void __init vt8500_init_irq(void) |
diff --git a/arch/arm/mm/abort-ev4.S b/arch/arm/mm/abort-ev4.S index 4f18f9e87bae..54473cd4aba9 100644 --- a/arch/arm/mm/abort-ev4.S +++ b/arch/arm/mm/abort-ev4.S | |||
@@ -3,14 +3,11 @@ | |||
3 | /* | 3 | /* |
4 | * Function: v4_early_abort | 4 | * Function: v4_early_abort |
5 | * | 5 | * |
6 | * Params : r2 = address of aborted instruction | 6 | * Params : r2 = pt_regs |
7 | * : r3 = saved SPSR | 7 | * : r4 = aborted context pc |
8 | * : r5 = aborted context psr | ||
8 | * | 9 | * |
9 | * Returns : r0 = address of abort | 10 | * Returns : r4 - r11, r13 preserved |
10 | * : r1 = FSR, bit 11 = write | ||
11 | * : r2-r8 = corrupted | ||
12 | * : r9 = preserved | ||
13 | * : sp = pointer to registers | ||
14 | * | 11 | * |
15 | * Purpose : obtain information about current aborted instruction. | 12 | * Purpose : obtain information about current aborted instruction. |
16 | * Note: we read user space. This means we might cause a data | 13 | * Note: we read user space. This means we might cause a data |
@@ -21,10 +18,8 @@ | |||
21 | ENTRY(v4_early_abort) | 18 | ENTRY(v4_early_abort) |
22 | mrc p15, 0, r1, c5, c0, 0 @ get FSR | 19 | mrc p15, 0, r1, c5, c0, 0 @ get FSR |
23 | mrc p15, 0, r0, c6, c0, 0 @ get FAR | 20 | mrc p15, 0, r0, c6, c0, 0 @ get FAR |
24 | ldr r3, [r2] @ read aborted ARM instruction | 21 | ldr r3, [r4] @ read aborted ARM instruction |
25 | bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR | 22 | bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR |
26 | tst r3, #1 << 20 @ L = 1 -> write? | 23 | tst r3, #1 << 20 @ L = 1 -> write? |
27 | orreq r1, r1, #1 << 11 @ yes. | 24 | orreq r1, r1, #1 << 11 @ yes. |
28 | mov pc, lr | 25 | b do_DataAbort |
29 | |||
30 | |||
diff --git a/arch/arm/mm/abort-ev4t.S b/arch/arm/mm/abort-ev4t.S index b6282548f922..9da704e7b86e 100644 --- a/arch/arm/mm/abort-ev4t.S +++ b/arch/arm/mm/abort-ev4t.S | |||
@@ -4,14 +4,11 @@ | |||
4 | /* | 4 | /* |
5 | * Function: v4t_early_abort | 5 | * Function: v4t_early_abort |
6 | * | 6 | * |
7 | * Params : r2 = address of aborted instruction | 7 | * Params : r2 = pt_regs |
8 | * : r3 = saved SPSR | 8 | * : r4 = aborted context pc |
9 | * : r5 = aborted context psr | ||
9 | * | 10 | * |
10 | * Returns : r0 = address of abort | 11 | * Returns : r4 - r11, r13 preserved |
11 | * : r1 = FSR, bit 11 = write | ||
12 | * : r2-r8 = corrupted | ||
13 | * : r9 = preserved | ||
14 | * : sp = pointer to registers | ||
15 | * | 12 | * |
16 | * Purpose : obtain information about current aborted instruction. | 13 | * Purpose : obtain information about current aborted instruction. |
17 | * Note: we read user space. This means we might cause a data | 14 | * Note: we read user space. This means we might cause a data |
@@ -22,9 +19,9 @@ | |||
22 | ENTRY(v4t_early_abort) | 19 | ENTRY(v4t_early_abort) |
23 | mrc p15, 0, r1, c5, c0, 0 @ get FSR | 20 | mrc p15, 0, r1, c5, c0, 0 @ get FSR |
24 | mrc p15, 0, r0, c6, c0, 0 @ get FAR | 21 | mrc p15, 0, r0, c6, c0, 0 @ get FAR |
25 | do_thumb_abort | 22 | do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3 |
26 | ldreq r3, [r2] @ read aborted ARM instruction | 23 | ldreq r3, [r4] @ read aborted ARM instruction |
27 | bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR | 24 | bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR |
28 | tst r3, #1 << 20 @ check write | 25 | tst r3, #1 << 20 @ check write |
29 | orreq r1, r1, #1 << 11 | 26 | orreq r1, r1, #1 << 11 |
30 | mov pc, lr | 27 | b do_DataAbort |
diff --git a/arch/arm/mm/abort-ev5t.S b/arch/arm/mm/abort-ev5t.S index 02251b526c0d..a0908d4653a3 100644 --- a/arch/arm/mm/abort-ev5t.S +++ b/arch/arm/mm/abort-ev5t.S | |||
@@ -4,14 +4,11 @@ | |||
4 | /* | 4 | /* |
5 | * Function: v5t_early_abort | 5 | * Function: v5t_early_abort |
6 | * | 6 | * |
7 | * Params : r2 = address of aborted instruction | 7 | * Params : r2 = pt_regs |
8 | * : r3 = saved SPSR | 8 | * : r4 = aborted context pc |
9 | * : r5 = aborted context psr | ||
9 | * | 10 | * |
10 | * Returns : r0 = address of abort | 11 | * Returns : r4 - r11, r13 preserved |
11 | * : r1 = FSR, bit 11 = write | ||
12 | * : r2-r8 = corrupted | ||
13 | * : r9 = preserved | ||
14 | * : sp = pointer to registers | ||
15 | * | 12 | * |
16 | * Purpose : obtain information about current aborted instruction. | 13 | * Purpose : obtain information about current aborted instruction. |
17 | * Note: we read user space. This means we might cause a data | 14 | * Note: we read user space. This means we might cause a data |
@@ -22,10 +19,10 @@ | |||
22 | ENTRY(v5t_early_abort) | 19 | ENTRY(v5t_early_abort) |
23 | mrc p15, 0, r1, c5, c0, 0 @ get FSR | 20 | mrc p15, 0, r1, c5, c0, 0 @ get FSR |
24 | mrc p15, 0, r0, c6, c0, 0 @ get FAR | 21 | mrc p15, 0, r0, c6, c0, 0 @ get FAR |
25 | do_thumb_abort | 22 | do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3 |
26 | ldreq r3, [r2] @ read aborted ARM instruction | 23 | ldreq r3, [r4] @ read aborted ARM instruction |
27 | bic r1, r1, #1 << 11 @ clear bits 11 of FSR | 24 | bic r1, r1, #1 << 11 @ clear bits 11 of FSR |
28 | do_ldrd_abort | 25 | do_ldrd_abort tmp=ip, insn=r3 |
29 | tst r3, #1 << 20 @ check write | 26 | tst r3, #1 << 20 @ check write |
30 | orreq r1, r1, #1 << 11 | 27 | orreq r1, r1, #1 << 11 |
31 | mov pc, lr | 28 | b do_DataAbort |
diff --git a/arch/arm/mm/abort-ev5tj.S b/arch/arm/mm/abort-ev5tj.S index bce68d601c8b..4006b7a61264 100644 --- a/arch/arm/mm/abort-ev5tj.S +++ b/arch/arm/mm/abort-ev5tj.S | |||
@@ -4,14 +4,11 @@ | |||
4 | /* | 4 | /* |
5 | * Function: v5tj_early_abort | 5 | * Function: v5tj_early_abort |
6 | * | 6 | * |
7 | * Params : r2 = address of aborted instruction | 7 | * Params : r2 = pt_regs |
8 | * : r3 = saved SPSR | 8 | * : r4 = aborted context pc |
9 | * : r5 = aborted context psr | ||
9 | * | 10 | * |
10 | * Returns : r0 = address of abort | 11 | * Returns : r4 - r11, r13 preserved |
11 | * : r1 = FSR, bit 11 = write | ||
12 | * : r2-r8 = corrupted | ||
13 | * : r9 = preserved | ||
14 | * : sp = pointer to registers | ||
15 | * | 12 | * |
16 | * Purpose : obtain information about current aborted instruction. | 13 | * Purpose : obtain information about current aborted instruction. |
17 | * Note: we read user space. This means we might cause a data | 14 | * Note: we read user space. This means we might cause a data |
@@ -23,13 +20,11 @@ ENTRY(v5tj_early_abort) | |||
23 | mrc p15, 0, r1, c5, c0, 0 @ get FSR | 20 | mrc p15, 0, r1, c5, c0, 0 @ get FSR |
24 | mrc p15, 0, r0, c6, c0, 0 @ get FAR | 21 | mrc p15, 0, r0, c6, c0, 0 @ get FAR |
25 | bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR | 22 | bic r1, r1, #1 << 11 | 1 << 10 @ clear bits 11 and 10 of FSR |
26 | tst r3, #PSR_J_BIT @ Java? | 23 | tst r5, #PSR_J_BIT @ Java? |
27 | movne pc, lr | 24 | bne do_DataAbort |
28 | do_thumb_abort | 25 | do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3 |
29 | ldreq r3, [r2] @ read aborted ARM instruction | 26 | ldreq r3, [r4] @ read aborted ARM instruction |
30 | do_ldrd_abort | 27 | do_ldrd_abort tmp=ip, insn=r3 |
31 | tst r3, #1 << 20 @ L = 0 -> write | 28 | tst r3, #1 << 20 @ L = 0 -> write |
32 | orreq r1, r1, #1 << 11 @ yes. | 29 | orreq r1, r1, #1 << 11 @ yes. |
33 | mov pc, lr | 30 | b do_DataAbort |
34 | |||
35 | |||
diff --git a/arch/arm/mm/abort-ev6.S b/arch/arm/mm/abort-ev6.S index 1478aa522144..ff1f7cc11f87 100644 --- a/arch/arm/mm/abort-ev6.S +++ b/arch/arm/mm/abort-ev6.S | |||
@@ -4,14 +4,11 @@ | |||
4 | /* | 4 | /* |
5 | * Function: v6_early_abort | 5 | * Function: v6_early_abort |
6 | * | 6 | * |
7 | * Params : r2 = address of aborted instruction | 7 | * Params : r2 = pt_regs |
8 | * : r3 = saved SPSR | 8 | * : r4 = aborted context pc |
9 | * : r5 = aborted context psr | ||
9 | * | 10 | * |
10 | * Returns : r0 = address of abort | 11 | * Returns : r4 - r11, r13 preserved |
11 | * : r1 = FSR, bit 11 = write | ||
12 | * : r2-r8 = corrupted | ||
13 | * : r9 = preserved | ||
14 | * : sp = pointer to registers | ||
15 | * | 12 | * |
16 | * Purpose : obtain information about current aborted instruction. | 13 | * Purpose : obtain information about current aborted instruction. |
17 | * Note: we read user space. This means we might cause a data | 14 | * Note: we read user space. This means we might cause a data |
@@ -33,16 +30,14 @@ ENTRY(v6_early_abort) | |||
33 | * The test below covers all the write situations, including Java bytecodes | 30 | * The test below covers all the write situations, including Java bytecodes |
34 | */ | 31 | */ |
35 | bic r1, r1, #1 << 11 @ clear bit 11 of FSR | 32 | bic r1, r1, #1 << 11 @ clear bit 11 of FSR |
36 | tst r3, #PSR_J_BIT @ Java? | 33 | tst r5, #PSR_J_BIT @ Java? |
37 | movne pc, lr | 34 | bne do_DataAbort |
38 | do_thumb_abort | 35 | do_thumb_abort fsr=r1, pc=r4, psr=r5, tmp=r3 |
39 | ldreq r3, [r2] @ read aborted ARM instruction | 36 | ldreq r3, [r4] @ read aborted ARM instruction |
40 | #ifdef CONFIG_CPU_ENDIAN_BE8 | 37 | #ifdef CONFIG_CPU_ENDIAN_BE8 |
41 | reveq r3, r3 | 38 | reveq r3, r3 |
42 | #endif | 39 | #endif |
43 | do_ldrd_abort | 40 | do_ldrd_abort tmp=ip, insn=r3 |
44 | tst r3, #1 << 20 @ L = 0 -> write | 41 | tst r3, #1 << 20 @ L = 0 -> write |
45 | orreq r1, r1, #1 << 11 @ yes. | 42 | orreq r1, r1, #1 << 11 @ yes. |
46 | mov pc, lr | 43 | b do_DataAbort |
47 | |||
48 | |||
diff --git a/arch/arm/mm/abort-ev7.S b/arch/arm/mm/abort-ev7.S index ec88b157d3bb..703375277ba6 100644 --- a/arch/arm/mm/abort-ev7.S +++ b/arch/arm/mm/abort-ev7.S | |||
@@ -3,14 +3,11 @@ | |||
3 | /* | 3 | /* |
4 | * Function: v7_early_abort | 4 | * Function: v7_early_abort |
5 | * | 5 | * |
6 | * Params : r2 = address of aborted instruction | 6 | * Params : r2 = pt_regs |
7 | * : r3 = saved SPSR | 7 | * : r4 = aborted context pc |
8 | * : r5 = aborted context psr | ||
8 | * | 9 | * |
9 | * Returns : r0 = address of abort | 10 | * Returns : r4 - r11, r13 preserved |
10 | * : r1 = FSR, bit 11 = write | ||
11 | * : r2-r8 = corrupted | ||
12 | * : r9 = preserved | ||
13 | * : sp = pointer to registers | ||
14 | * | 11 | * |
15 | * Purpose : obtain information about current aborted instruction. | 12 | * Purpose : obtain information about current aborted instruction. |
16 | */ | 13 | */ |
@@ -37,18 +34,18 @@ ENTRY(v7_early_abort) | |||
37 | ldr r3, =0x40d @ On permission fault | 34 | ldr r3, =0x40d @ On permission fault |
38 | and r3, r1, r3 | 35 | and r3, r1, r3 |
39 | cmp r3, #0x0d | 36 | cmp r3, #0x0d |
40 | movne pc, lr | 37 | bne do_DataAbort |
41 | 38 | ||
42 | mcr p15, 0, r0, c7, c8, 0 @ Retranslate FAR | 39 | mcr p15, 0, r0, c7, c8, 0 @ Retranslate FAR |
43 | isb | 40 | isb |
44 | mrc p15, 0, r2, c7, c4, 0 @ Read the PAR | 41 | mrc p15, 0, ip, c7, c4, 0 @ Read the PAR |
45 | and r3, r2, #0x7b @ On translation fault | 42 | and r3, ip, #0x7b @ On translation fault |
46 | cmp r3, #0x0b | 43 | cmp r3, #0x0b |
47 | movne pc, lr | 44 | bne do_DataAbort |
48 | bic r1, r1, #0xf @ Fix up FSR FS[5:0] | 45 | bic r1, r1, #0xf @ Fix up FSR FS[5:0] |
49 | and r2, r2, #0x7e | 46 | and ip, ip, #0x7e |
50 | orr r1, r1, r2, LSR #1 | 47 | orr r1, r1, ip, LSR #1 |
51 | #endif | 48 | #endif |
52 | 49 | ||
53 | mov pc, lr | 50 | b do_DataAbort |
54 | ENDPROC(v7_early_abort) | 51 | ENDPROC(v7_early_abort) |
diff --git a/arch/arm/mm/abort-lv4t.S b/arch/arm/mm/abort-lv4t.S index 9fb7b0e25ea1..f3982580c273 100644 --- a/arch/arm/mm/abort-lv4t.S +++ b/arch/arm/mm/abort-lv4t.S | |||
@@ -3,14 +3,11 @@ | |||
3 | /* | 3 | /* |
4 | * Function: v4t_late_abort | 4 | * Function: v4t_late_abort |
5 | * | 5 | * |
6 | * Params : r2 = address of aborted instruction | 6 | * Params : r2 = pt_regs |
7 | * : r3 = saved SPSR | 7 | * : r4 = aborted context pc |
8 | * : r5 = aborted context psr | ||
8 | * | 9 | * |
9 | * Returns : r0 = address of abort | 10 | * Returns : r4-r5, r10-r11, r13 preserved |
10 | * : r1 = FSR, bit 11 = write | ||
11 | * : r2-r8 = corrupted | ||
12 | * : r9 = preserved | ||
13 | * : sp = pointer to registers | ||
14 | * | 11 | * |
15 | * Purpose : obtain information about current aborted instruction. | 12 | * Purpose : obtain information about current aborted instruction. |
16 | * Note: we read user space. This means we might cause a data | 13 | * Note: we read user space. This means we might cause a data |
@@ -18,7 +15,7 @@ | |||
18 | * picture. Unfortunately, this does happen. We live with it. | 15 | * picture. Unfortunately, this does happen. We live with it. |
19 | */ | 16 | */ |
20 | ENTRY(v4t_late_abort) | 17 | ENTRY(v4t_late_abort) |
21 | tst r3, #PSR_T_BIT @ check for thumb mode | 18 | tst r5, #PSR_T_BIT @ check for thumb mode |
22 | #ifdef CONFIG_CPU_CP15_MMU | 19 | #ifdef CONFIG_CPU_CP15_MMU |
23 | mrc p15, 0, r1, c5, c0, 0 @ get FSR | 20 | mrc p15, 0, r1, c5, c0, 0 @ get FSR |
24 | mrc p15, 0, r0, c6, c0, 0 @ get FAR | 21 | mrc p15, 0, r0, c6, c0, 0 @ get FAR |
@@ -28,7 +25,7 @@ ENTRY(v4t_late_abort) | |||
28 | mov r1, #0 | 25 | mov r1, #0 |
29 | #endif | 26 | #endif |
30 | bne .data_thumb_abort | 27 | bne .data_thumb_abort |
31 | ldr r8, [r2] @ read arm instruction | 28 | ldr r8, [r4] @ read arm instruction |
32 | tst r8, #1 << 20 @ L = 1 -> write? | 29 | tst r8, #1 << 20 @ L = 1 -> write? |
33 | orreq r1, r1, #1 << 11 @ yes. | 30 | orreq r1, r1, #1 << 11 @ yes. |
34 | and r7, r8, #15 << 24 | 31 | and r7, r8, #15 << 24 |
@@ -47,86 +44,84 @@ ENTRY(v4t_late_abort) | |||
47 | /* 9 */ b .data_arm_ldmstm @ ldm*b rn, <rlist> | 44 | /* 9 */ b .data_arm_ldmstm @ ldm*b rn, <rlist> |
48 | /* a */ b .data_unknown | 45 | /* a */ b .data_unknown |
49 | /* b */ b .data_unknown | 46 | /* b */ b .data_unknown |
50 | /* c */ mov pc, lr @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m | 47 | /* c */ b do_DataAbort @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m |
51 | /* d */ mov pc, lr @ ldc rd, [rn, #m] | 48 | /* d */ b do_DataAbort @ ldc rd, [rn, #m] |
52 | /* e */ b .data_unknown | 49 | /* e */ b .data_unknown |
53 | /* f */ | 50 | /* f */ |
54 | .data_unknown: @ Part of jumptable | 51 | .data_unknown: @ Part of jumptable |
55 | mov r0, r2 | 52 | mov r0, r4 |
56 | mov r1, r8 | 53 | mov r1, r8 |
57 | mov r2, sp | 54 | b baddataabort |
58 | bl baddataabort | ||
59 | b ret_from_exception | ||
60 | 55 | ||
61 | .data_arm_ldmstm: | 56 | .data_arm_ldmstm: |
62 | tst r8, #1 << 21 @ check writeback bit | 57 | tst r8, #1 << 21 @ check writeback bit |
63 | moveq pc, lr @ no writeback -> no fixup | 58 | beq do_DataAbort @ no writeback -> no fixup |
64 | mov r7, #0x11 | 59 | mov r7, #0x11 |
65 | orr r7, r7, #0x1100 | 60 | orr r7, r7, #0x1100 |
66 | and r6, r8, r7 | 61 | and r6, r8, r7 |
67 | and r2, r8, r7, lsl #1 | 62 | and r9, r8, r7, lsl #1 |
68 | add r6, r6, r2, lsr #1 | 63 | add r6, r6, r9, lsr #1 |
69 | and r2, r8, r7, lsl #2 | 64 | and r9, r8, r7, lsl #2 |
70 | add r6, r6, r2, lsr #2 | 65 | add r6, r6, r9, lsr #2 |
71 | and r2, r8, r7, lsl #3 | 66 | and r9, r8, r7, lsl #3 |
72 | add r6, r6, r2, lsr #3 | 67 | add r6, r6, r9, lsr #3 |
73 | add r6, r6, r6, lsr #8 | 68 | add r6, r6, r6, lsr #8 |
74 | add r6, r6, r6, lsr #4 | 69 | add r6, r6, r6, lsr #4 |
75 | and r6, r6, #15 @ r6 = no. of registers to transfer. | 70 | and r6, r6, #15 @ r6 = no. of registers to transfer. |
76 | and r5, r8, #15 << 16 @ Extract 'n' from instruction | 71 | and r9, r8, #15 << 16 @ Extract 'n' from instruction |
77 | ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' | 72 | ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' |
78 | tst r8, #1 << 23 @ Check U bit | 73 | tst r8, #1 << 23 @ Check U bit |
79 | subne r7, r7, r6, lsl #2 @ Undo increment | 74 | subne r7, r7, r6, lsl #2 @ Undo increment |
80 | addeq r7, r7, r6, lsl #2 @ Undo decrement | 75 | addeq r7, r7, r6, lsl #2 @ Undo decrement |
81 | str r7, [sp, r5, lsr #14] @ Put register 'Rn' | 76 | str r7, [r2, r9, lsr #14] @ Put register 'Rn' |
82 | mov pc, lr | 77 | b do_DataAbort |
83 | 78 | ||
84 | .data_arm_lateldrhpre: | 79 | .data_arm_lateldrhpre: |
85 | tst r8, #1 << 21 @ Check writeback bit | 80 | tst r8, #1 << 21 @ Check writeback bit |
86 | moveq pc, lr @ No writeback -> no fixup | 81 | beq do_DataAbort @ No writeback -> no fixup |
87 | .data_arm_lateldrhpost: | 82 | .data_arm_lateldrhpost: |
88 | and r5, r8, #0x00f @ get Rm / low nibble of immediate value | 83 | and r9, r8, #0x00f @ get Rm / low nibble of immediate value |
89 | tst r8, #1 << 22 @ if (immediate offset) | 84 | tst r8, #1 << 22 @ if (immediate offset) |
90 | andne r6, r8, #0xf00 @ { immediate high nibble | 85 | andne r6, r8, #0xf00 @ { immediate high nibble |
91 | orrne r6, r5, r6, lsr #4 @ combine nibbles } else | 86 | orrne r6, r9, r6, lsr #4 @ combine nibbles } else |
92 | ldreq r6, [sp, r5, lsl #2] @ { load Rm value } | 87 | ldreq r6, [r2, r9, lsl #2] @ { load Rm value } |
93 | .data_arm_apply_r6_and_rn: | 88 | .data_arm_apply_r6_and_rn: |
94 | and r5, r8, #15 << 16 @ Extract 'n' from instruction | 89 | and r9, r8, #15 << 16 @ Extract 'n' from instruction |
95 | ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' | 90 | ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' |
96 | tst r8, #1 << 23 @ Check U bit | 91 | tst r8, #1 << 23 @ Check U bit |
97 | subne r7, r7, r6 @ Undo incrmenet | 92 | subne r7, r7, r6 @ Undo incrmenet |
98 | addeq r7, r7, r6 @ Undo decrement | 93 | addeq r7, r7, r6 @ Undo decrement |
99 | str r7, [sp, r5, lsr #14] @ Put register 'Rn' | 94 | str r7, [r2, r9, lsr #14] @ Put register 'Rn' |
100 | mov pc, lr | 95 | b do_DataAbort |
101 | 96 | ||
102 | .data_arm_lateldrpreconst: | 97 | .data_arm_lateldrpreconst: |
103 | tst r8, #1 << 21 @ check writeback bit | 98 | tst r8, #1 << 21 @ check writeback bit |
104 | moveq pc, lr @ no writeback -> no fixup | 99 | beq do_DataAbort @ no writeback -> no fixup |
105 | .data_arm_lateldrpostconst: | 100 | .data_arm_lateldrpostconst: |
106 | movs r2, r8, lsl #20 @ Get offset | 101 | movs r6, r8, lsl #20 @ Get offset |
107 | moveq pc, lr @ zero -> no fixup | 102 | beq do_DataAbort @ zero -> no fixup |
108 | and r5, r8, #15 << 16 @ Extract 'n' from instruction | 103 | and r9, r8, #15 << 16 @ Extract 'n' from instruction |
109 | ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' | 104 | ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' |
110 | tst r8, #1 << 23 @ Check U bit | 105 | tst r8, #1 << 23 @ Check U bit |
111 | subne r7, r7, r2, lsr #20 @ Undo increment | 106 | subne r7, r7, r6, lsr #20 @ Undo increment |
112 | addeq r7, r7, r2, lsr #20 @ Undo decrement | 107 | addeq r7, r7, r6, lsr #20 @ Undo decrement |
113 | str r7, [sp, r5, lsr #14] @ Put register 'Rn' | 108 | str r7, [r2, r9, lsr #14] @ Put register 'Rn' |
114 | mov pc, lr | 109 | b do_DataAbort |
115 | 110 | ||
116 | .data_arm_lateldrprereg: | 111 | .data_arm_lateldrprereg: |
117 | tst r8, #1 << 21 @ check writeback bit | 112 | tst r8, #1 << 21 @ check writeback bit |
118 | moveq pc, lr @ no writeback -> no fixup | 113 | beq do_DataAbort @ no writeback -> no fixup |
119 | .data_arm_lateldrpostreg: | 114 | .data_arm_lateldrpostreg: |
120 | and r7, r8, #15 @ Extract 'm' from instruction | 115 | and r7, r8, #15 @ Extract 'm' from instruction |
121 | ldr r6, [sp, r7, lsl #2] @ Get register 'Rm' | 116 | ldr r6, [r2, r7, lsl #2] @ Get register 'Rm' |
122 | mov r5, r8, lsr #7 @ get shift count | 117 | mov r9, r8, lsr #7 @ get shift count |
123 | ands r5, r5, #31 | 118 | ands r9, r9, #31 |
124 | and r7, r8, #0x70 @ get shift type | 119 | and r7, r8, #0x70 @ get shift type |
125 | orreq r7, r7, #8 @ shift count = 0 | 120 | orreq r7, r7, #8 @ shift count = 0 |
126 | add pc, pc, r7 | 121 | add pc, pc, r7 |
127 | nop | 122 | nop |
128 | 123 | ||
129 | mov r6, r6, lsl r5 @ 0: LSL #!0 | 124 | mov r6, r6, lsl r9 @ 0: LSL #!0 |
130 | b .data_arm_apply_r6_and_rn | 125 | b .data_arm_apply_r6_and_rn |
131 | b .data_arm_apply_r6_and_rn @ 1: LSL #0 | 126 | b .data_arm_apply_r6_and_rn @ 1: LSL #0 |
132 | nop | 127 | nop |
@@ -134,7 +129,7 @@ ENTRY(v4t_late_abort) | |||
134 | nop | 129 | nop |
135 | b .data_unknown @ 3: MUL? | 130 | b .data_unknown @ 3: MUL? |
136 | nop | 131 | nop |
137 | mov r6, r6, lsr r5 @ 4: LSR #!0 | 132 | mov r6, r6, lsr r9 @ 4: LSR #!0 |
138 | b .data_arm_apply_r6_and_rn | 133 | b .data_arm_apply_r6_and_rn |
139 | mov r6, r6, lsr #32 @ 5: LSR #32 | 134 | mov r6, r6, lsr #32 @ 5: LSR #32 |
140 | b .data_arm_apply_r6_and_rn | 135 | b .data_arm_apply_r6_and_rn |
@@ -142,7 +137,7 @@ ENTRY(v4t_late_abort) | |||
142 | nop | 137 | nop |
143 | b .data_unknown @ 7: MUL? | 138 | b .data_unknown @ 7: MUL? |
144 | nop | 139 | nop |
145 | mov r6, r6, asr r5 @ 8: ASR #!0 | 140 | mov r6, r6, asr r9 @ 8: ASR #!0 |
146 | b .data_arm_apply_r6_and_rn | 141 | b .data_arm_apply_r6_and_rn |
147 | mov r6, r6, asr #32 @ 9: ASR #32 | 142 | mov r6, r6, asr #32 @ 9: ASR #32 |
148 | b .data_arm_apply_r6_and_rn | 143 | b .data_arm_apply_r6_and_rn |
@@ -150,7 +145,7 @@ ENTRY(v4t_late_abort) | |||
150 | nop | 145 | nop |
151 | b .data_unknown @ B: MUL? | 146 | b .data_unknown @ B: MUL? |
152 | nop | 147 | nop |
153 | mov r6, r6, ror r5 @ C: ROR #!0 | 148 | mov r6, r6, ror r9 @ C: ROR #!0 |
154 | b .data_arm_apply_r6_and_rn | 149 | b .data_arm_apply_r6_and_rn |
155 | mov r6, r6, rrx @ D: RRX | 150 | mov r6, r6, rrx @ D: RRX |
156 | b .data_arm_apply_r6_and_rn | 151 | b .data_arm_apply_r6_and_rn |
@@ -159,7 +154,7 @@ ENTRY(v4t_late_abort) | |||
159 | b .data_unknown @ F: MUL? | 154 | b .data_unknown @ F: MUL? |
160 | 155 | ||
161 | .data_thumb_abort: | 156 | .data_thumb_abort: |
162 | ldrh r8, [r2] @ read instruction | 157 | ldrh r8, [r4] @ read instruction |
163 | tst r8, #1 << 11 @ L = 1 -> write? | 158 | tst r8, #1 << 11 @ L = 1 -> write? |
164 | orreq r1, r1, #1 << 8 @ yes | 159 | orreq r1, r1, #1 << 8 @ yes |
165 | and r7, r8, #15 << 12 | 160 | and r7, r8, #15 << 12 |
@@ -172,10 +167,10 @@ ENTRY(v4t_late_abort) | |||
172 | /* 3 */ b .data_unknown | 167 | /* 3 */ b .data_unknown |
173 | /* 4 */ b .data_unknown | 168 | /* 4 */ b .data_unknown |
174 | /* 5 */ b .data_thumb_reg | 169 | /* 5 */ b .data_thumb_reg |
175 | /* 6 */ mov pc, lr | 170 | /* 6 */ b do_DataAbort |
176 | /* 7 */ mov pc, lr | 171 | /* 7 */ b do_DataAbort |
177 | /* 8 */ mov pc, lr | 172 | /* 8 */ b do_DataAbort |
178 | /* 9 */ mov pc, lr | 173 | /* 9 */ b do_DataAbort |
179 | /* A */ b .data_unknown | 174 | /* A */ b .data_unknown |
180 | /* B */ b .data_thumb_pushpop | 175 | /* B */ b .data_thumb_pushpop |
181 | /* C */ b .data_thumb_ldmstm | 176 | /* C */ b .data_thumb_ldmstm |
@@ -185,41 +180,41 @@ ENTRY(v4t_late_abort) | |||
185 | 180 | ||
186 | .data_thumb_reg: | 181 | .data_thumb_reg: |
187 | tst r8, #1 << 9 | 182 | tst r8, #1 << 9 |
188 | moveq pc, lr | 183 | beq do_DataAbort |
189 | tst r8, #1 << 10 @ If 'S' (signed) bit is set | 184 | tst r8, #1 << 10 @ If 'S' (signed) bit is set |
190 | movne r1, #0 @ it must be a load instr | 185 | movne r1, #0 @ it must be a load instr |
191 | mov pc, lr | 186 | b do_DataAbort |
192 | 187 | ||
193 | .data_thumb_pushpop: | 188 | .data_thumb_pushpop: |
194 | tst r8, #1 << 10 | 189 | tst r8, #1 << 10 |
195 | beq .data_unknown | 190 | beq .data_unknown |
196 | and r6, r8, #0x55 @ hweight8(r8) + R bit | 191 | and r6, r8, #0x55 @ hweight8(r8) + R bit |
197 | and r2, r8, #0xaa | 192 | and r9, r8, #0xaa |
198 | add r6, r6, r2, lsr #1 | 193 | add r6, r6, r9, lsr #1 |
199 | and r2, r6, #0xcc | 194 | and r9, r6, #0xcc |
200 | and r6, r6, #0x33 | 195 | and r6, r6, #0x33 |
201 | add r6, r6, r2, lsr #2 | 196 | add r6, r6, r9, lsr #2 |
202 | movs r7, r8, lsr #9 @ C = r8 bit 8 (R bit) | 197 | movs r7, r8, lsr #9 @ C = r8 bit 8 (R bit) |
203 | adc r6, r6, r6, lsr #4 @ high + low nibble + R bit | 198 | adc r6, r6, r6, lsr #4 @ high + low nibble + R bit |
204 | and r6, r6, #15 @ number of regs to transfer | 199 | and r6, r6, #15 @ number of regs to transfer |
205 | ldr r7, [sp, #13 << 2] | 200 | ldr r7, [r2, #13 << 2] |
206 | tst r8, #1 << 11 | 201 | tst r8, #1 << 11 |
207 | addeq r7, r7, r6, lsl #2 @ increment SP if PUSH | 202 | addeq r7, r7, r6, lsl #2 @ increment SP if PUSH |
208 | subne r7, r7, r6, lsl #2 @ decrement SP if POP | 203 | subne r7, r7, r6, lsl #2 @ decrement SP if POP |
209 | str r7, [sp, #13 << 2] | 204 | str r7, [r2, #13 << 2] |
210 | mov pc, lr | 205 | b do_DataAbort |
211 | 206 | ||
212 | .data_thumb_ldmstm: | 207 | .data_thumb_ldmstm: |
213 | and r6, r8, #0x55 @ hweight8(r8) | 208 | and r6, r8, #0x55 @ hweight8(r8) |
214 | and r2, r8, #0xaa | 209 | and r9, r8, #0xaa |
215 | add r6, r6, r2, lsr #1 | 210 | add r6, r6, r9, lsr #1 |
216 | and r2, r6, #0xcc | 211 | and r9, r6, #0xcc |
217 | and r6, r6, #0x33 | 212 | and r6, r6, #0x33 |
218 | add r6, r6, r2, lsr #2 | 213 | add r6, r6, r9, lsr #2 |
219 | add r6, r6, r6, lsr #4 | 214 | add r6, r6, r6, lsr #4 |
220 | and r5, r8, #7 << 8 | 215 | and r9, r8, #7 << 8 |
221 | ldr r7, [sp, r5, lsr #6] | 216 | ldr r7, [r2, r9, lsr #6] |
222 | and r6, r6, #15 @ number of regs to transfer | 217 | and r6, r6, #15 @ number of regs to transfer |
223 | sub r7, r7, r6, lsl #2 @ always decrement | 218 | sub r7, r7, r6, lsl #2 @ always decrement |
224 | str r7, [sp, r5, lsr #6] | 219 | str r7, [r2, r9, lsr #6] |
225 | mov pc, lr | 220 | b do_DataAbort |
diff --git a/arch/arm/mm/abort-macro.S b/arch/arm/mm/abort-macro.S index d7cb1bfa51a4..52162d59407a 100644 --- a/arch/arm/mm/abort-macro.S +++ b/arch/arm/mm/abort-macro.S | |||
@@ -9,34 +9,32 @@ | |||
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
12 | .macro do_thumb_abort | 12 | .macro do_thumb_abort, fsr, pc, psr, tmp |
13 | tst r3, #PSR_T_BIT | 13 | tst \psr, #PSR_T_BIT |
14 | beq not_thumb | 14 | beq not_thumb |
15 | ldrh r3, [r2] @ Read aborted Thumb instruction | 15 | ldrh \tmp, [\pc] @ Read aborted Thumb instruction |
16 | and r3, r3, # 0xfe00 @ Mask opcode field | 16 | and \tmp, \tmp, # 0xfe00 @ Mask opcode field |
17 | cmp r3, # 0x5600 @ Is it ldrsb? | 17 | cmp \tmp, # 0x5600 @ Is it ldrsb? |
18 | orreq r3, r3, #1 << 11 @ Set L-bit if yes | 18 | orreq \tmp, \tmp, #1 << 11 @ Set L-bit if yes |
19 | tst r3, #1 << 11 @ L = 0 -> write | 19 | tst \tmp, #1 << 11 @ L = 0 -> write |
20 | orreq r1, r1, #1 << 11 @ yes. | 20 | orreq \psr, \psr, #1 << 11 @ yes. |
21 | mov pc, lr | 21 | b do_DataAbort |
22 | not_thumb: | 22 | not_thumb: |
23 | .endm | 23 | .endm |
24 | 24 | ||
25 | /* | 25 | /* |
26 | * We check for the following insturction encoding for LDRD. | 26 | * We check for the following instruction encoding for LDRD. |
27 | * | 27 | * |
28 | * [27:25] == 0 | 28 | * [27:25] == 000 |
29 | * [7:4] == 1101 | 29 | * [7:4] == 1101 |
30 | * [20] == 0 | 30 | * [20] == 0 |
31 | */ | 31 | */ |
32 | .macro do_ldrd_abort | 32 | .macro do_ldrd_abort, tmp, insn |
33 | tst r3, #0x0e000000 @ [27:25] == 0 | 33 | tst \insn, #0x0e100000 @ [27:25,20] == 0 |
34 | bne not_ldrd | 34 | bne not_ldrd |
35 | and r2, r3, #0x000000f0 @ [7:4] == 1101 | 35 | and \tmp, \insn, #0x000000f0 @ [7:4] == 1101 |
36 | cmp r2, #0x000000d0 | 36 | cmp \tmp, #0x000000d0 |
37 | bne not_ldrd | 37 | beq do_DataAbort |
38 | tst r3, #1 << 20 @ [20] == 0 | ||
39 | moveq pc, lr | ||
40 | not_ldrd: | 38 | not_ldrd: |
41 | .endm | 39 | .endm |
42 | 40 | ||
diff --git a/arch/arm/mm/abort-nommu.S b/arch/arm/mm/abort-nommu.S index 625e580945b5..119cb479c2ab 100644 --- a/arch/arm/mm/abort-nommu.S +++ b/arch/arm/mm/abort-nommu.S | |||
@@ -3,11 +3,11 @@ | |||
3 | /* | 3 | /* |
4 | * Function: nommu_early_abort | 4 | * Function: nommu_early_abort |
5 | * | 5 | * |
6 | * Params : r2 = address of aborted instruction | 6 | * Params : r2 = pt_regs |
7 | * : r3 = saved SPSR | 7 | * : r4 = aborted context pc |
8 | * : r5 = aborted context psr | ||
8 | * | 9 | * |
9 | * Returns : r0 = 0 (abort address) | 10 | * Returns : r4 - r11, r13 preserved |
10 | * : r1 = 0 (FSR) | ||
11 | * | 11 | * |
12 | * Note: There is no FSR/FAR on !CPU_CP15_MMU cores. | 12 | * Note: There is no FSR/FAR on !CPU_CP15_MMU cores. |
13 | * Just fill zero into the registers. | 13 | * Just fill zero into the registers. |
@@ -16,5 +16,5 @@ | |||
16 | ENTRY(nommu_early_abort) | 16 | ENTRY(nommu_early_abort) |
17 | mov r0, #0 @ clear r0, r1 (no FSR/FAR) | 17 | mov r0, #0 @ clear r0, r1 (no FSR/FAR) |
18 | mov r1, #0 | 18 | mov r1, #0 |
19 | mov pc, lr | 19 | b do_DataAbort |
20 | ENDPROC(nommu_early_abort) | 20 | ENDPROC(nommu_early_abort) |
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 724ba3bce72c..be7c638b648b 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c | |||
@@ -727,6 +727,9 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
727 | int isize = 4; | 727 | int isize = 4; |
728 | int thumb2_32b = 0; | 728 | int thumb2_32b = 0; |
729 | 729 | ||
730 | if (interrupts_enabled(regs)) | ||
731 | local_irq_enable(); | ||
732 | |||
730 | instrptr = instruction_pointer(regs); | 733 | instrptr = instruction_pointer(regs); |
731 | 734 | ||
732 | fs = get_fs(); | 735 | fs = get_fs(); |
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c index ef59099a5463..44c086710d2b 100644 --- a/arch/arm/mm/cache-l2x0.c +++ b/arch/arm/mm/cache-l2x0.c | |||
@@ -120,17 +120,22 @@ static void l2x0_cache_sync(void) | |||
120 | spin_unlock_irqrestore(&l2x0_lock, flags); | 120 | spin_unlock_irqrestore(&l2x0_lock, flags); |
121 | } | 121 | } |
122 | 122 | ||
123 | static void l2x0_flush_all(void) | 123 | static void __l2x0_flush_all(void) |
124 | { | 124 | { |
125 | unsigned long flags; | ||
126 | |||
127 | /* clean all ways */ | ||
128 | spin_lock_irqsave(&l2x0_lock, flags); | ||
129 | debug_writel(0x03); | 125 | debug_writel(0x03); |
130 | writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY); | 126 | writel_relaxed(l2x0_way_mask, l2x0_base + L2X0_CLEAN_INV_WAY); |
131 | cache_wait_way(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask); | 127 | cache_wait_way(l2x0_base + L2X0_CLEAN_INV_WAY, l2x0_way_mask); |
132 | cache_sync(); | 128 | cache_sync(); |
133 | debug_writel(0x00); | 129 | debug_writel(0x00); |
130 | } | ||
131 | |||
132 | static void l2x0_flush_all(void) | ||
133 | { | ||
134 | unsigned long flags; | ||
135 | |||
136 | /* clean all ways */ | ||
137 | spin_lock_irqsave(&l2x0_lock, flags); | ||
138 | __l2x0_flush_all(); | ||
134 | spin_unlock_irqrestore(&l2x0_lock, flags); | 139 | spin_unlock_irqrestore(&l2x0_lock, flags); |
135 | } | 140 | } |
136 | 141 | ||
@@ -266,7 +271,9 @@ static void l2x0_disable(void) | |||
266 | unsigned long flags; | 271 | unsigned long flags; |
267 | 272 | ||
268 | spin_lock_irqsave(&l2x0_lock, flags); | 273 | spin_lock_irqsave(&l2x0_lock, flags); |
269 | writel(0, l2x0_base + L2X0_CTRL); | 274 | __l2x0_flush_all(); |
275 | writel_relaxed(0, l2x0_base + L2X0_CTRL); | ||
276 | dsb(); | ||
270 | spin_unlock_irqrestore(&l2x0_lock, flags); | 277 | spin_unlock_irqrestore(&l2x0_lock, flags); |
271 | } | 278 | } |
272 | 279 | ||
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c index bdba6c65c901..63cca0097130 100644 --- a/arch/arm/mm/copypage-v6.c +++ b/arch/arm/mm/copypage-v6.c | |||
@@ -41,7 +41,6 @@ static void v6_copy_user_highpage_nonaliasing(struct page *to, | |||
41 | kfrom = kmap_atomic(from, KM_USER0); | 41 | kfrom = kmap_atomic(from, KM_USER0); |
42 | kto = kmap_atomic(to, KM_USER1); | 42 | kto = kmap_atomic(to, KM_USER1); |
43 | copy_page(kto, kfrom); | 43 | copy_page(kto, kfrom); |
44 | __cpuc_flush_dcache_area(kto, PAGE_SIZE); | ||
45 | kunmap_atomic(kto, KM_USER1); | 44 | kunmap_atomic(kto, KM_USER1); |
46 | kunmap_atomic(kfrom, KM_USER0); | 45 | kunmap_atomic(kfrom, KM_USER0); |
47 | } | 46 | } |
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 82a093cee09a..0a0a1e7c20d2 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
@@ -25,9 +25,11 @@ | |||
25 | #include <asm/tlbflush.h> | 25 | #include <asm/tlbflush.h> |
26 | #include <asm/sizes.h> | 26 | #include <asm/sizes.h> |
27 | 27 | ||
28 | #include "mm.h" | ||
29 | |||
28 | static u64 get_coherent_dma_mask(struct device *dev) | 30 | static u64 get_coherent_dma_mask(struct device *dev) |
29 | { | 31 | { |
30 | u64 mask = ISA_DMA_THRESHOLD; | 32 | u64 mask = (u64)arm_dma_limit; |
31 | 33 | ||
32 | if (dev) { | 34 | if (dev) { |
33 | mask = dev->coherent_dma_mask; | 35 | mask = dev->coherent_dma_mask; |
@@ -41,10 +43,10 @@ static u64 get_coherent_dma_mask(struct device *dev) | |||
41 | return 0; | 43 | return 0; |
42 | } | 44 | } |
43 | 45 | ||
44 | if ((~mask) & ISA_DMA_THRESHOLD) { | 46 | if ((~mask) & (u64)arm_dma_limit) { |
45 | dev_warn(dev, "coherent DMA mask %#llx is smaller " | 47 | dev_warn(dev, "coherent DMA mask %#llx is smaller " |
46 | "than system GFP_DMA mask %#llx\n", | 48 | "than system GFP_DMA mask %#llx\n", |
47 | mask, (unsigned long long)ISA_DMA_THRESHOLD); | 49 | mask, (u64)arm_dma_limit); |
48 | return 0; | 50 | return 0; |
49 | } | 51 | } |
50 | } | 52 | } |
@@ -657,6 +659,33 @@ void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, | |||
657 | } | 659 | } |
658 | EXPORT_SYMBOL(dma_sync_sg_for_device); | 660 | EXPORT_SYMBOL(dma_sync_sg_for_device); |
659 | 661 | ||
662 | /* | ||
663 | * Return whether the given device DMA address mask can be supported | ||
664 | * properly. For example, if your device can only drive the low 24-bits | ||
665 | * during bus mastering, then you would pass 0x00ffffff as the mask | ||
666 | * to this function. | ||
667 | */ | ||
668 | int dma_supported(struct device *dev, u64 mask) | ||
669 | { | ||
670 | if (mask < (u64)arm_dma_limit) | ||
671 | return 0; | ||
672 | return 1; | ||
673 | } | ||
674 | EXPORT_SYMBOL(dma_supported); | ||
675 | |||
676 | int dma_set_mask(struct device *dev, u64 dma_mask) | ||
677 | { | ||
678 | if (!dev->dma_mask || !dma_supported(dev, dma_mask)) | ||
679 | return -EIO; | ||
680 | |||
681 | #ifndef CONFIG_DMABOUNCE | ||
682 | *dev->dma_mask = dma_mask; | ||
683 | #endif | ||
684 | |||
685 | return 0; | ||
686 | } | ||
687 | EXPORT_SYMBOL(dma_set_mask); | ||
688 | |||
660 | #define PREALLOC_DMA_DEBUG_ENTRIES 4096 | 689 | #define PREALLOC_DMA_DEBUG_ENTRIES 4096 |
661 | 690 | ||
662 | static int __init dma_debug_do_init(void) | 691 | static int __init dma_debug_do_init(void) |
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index bc0e1d88fd3b..55657c222d7c 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c | |||
@@ -94,7 +94,7 @@ void show_pte(struct mm_struct *mm, unsigned long addr) | |||
94 | 94 | ||
95 | pud = pud_offset(pgd, addr); | 95 | pud = pud_offset(pgd, addr); |
96 | if (PTRS_PER_PUD != 1) | 96 | if (PTRS_PER_PUD != 1) |
97 | printk(", *pud=%08lx", pud_val(*pud)); | 97 | printk(", *pud=%08llx", (long long)pud_val(*pud)); |
98 | 98 | ||
99 | if (pud_none(*pud)) | 99 | if (pud_none(*pud)) |
100 | break; | 100 | break; |
@@ -285,6 +285,10 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) | |||
285 | tsk = current; | 285 | tsk = current; |
286 | mm = tsk->mm; | 286 | mm = tsk->mm; |
287 | 287 | ||
288 | /* Enable interrupts if they were enabled in the parent context. */ | ||
289 | if (interrupts_enabled(regs)) | ||
290 | local_irq_enable(); | ||
291 | |||
288 | /* | 292 | /* |
289 | * If we're in an interrupt or have no user | 293 | * If we're in an interrupt or have no user |
290 | * context, we must not take the fault.. | 294 | * context, we must not take the fault.. |
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c index c19571c40a21..e5ab4362322f 100644 --- a/arch/arm/mm/init.c +++ b/arch/arm/mm/init.c | |||
@@ -212,6 +212,14 @@ static void __init arm_bootmem_init(unsigned long start_pfn, | |||
212 | } | 212 | } |
213 | 213 | ||
214 | #ifdef CONFIG_ZONE_DMA | 214 | #ifdef CONFIG_ZONE_DMA |
215 | /* | ||
216 | * The DMA mask corresponding to the maximum bus address allocatable | ||
217 | * using GFP_DMA. The default here places no restriction on DMA | ||
218 | * allocations. This must be the smallest DMA mask in the system, | ||
219 | * so a successful GFP_DMA allocation will always satisfy this. | ||
220 | */ | ||
221 | u32 arm_dma_limit; | ||
222 | |||
215 | static void __init arm_adjust_dma_zone(unsigned long *size, unsigned long *hole, | 223 | static void __init arm_adjust_dma_zone(unsigned long *size, unsigned long *hole, |
216 | unsigned long dma_size) | 224 | unsigned long dma_size) |
217 | { | 225 | { |
@@ -278,6 +286,8 @@ static void __init arm_bootmem_free(unsigned long min, unsigned long max_low, | |||
278 | */ | 286 | */ |
279 | arm_adjust_dma_zone(zone_size, zhole_size, | 287 | arm_adjust_dma_zone(zone_size, zhole_size, |
280 | ARM_DMA_ZONE_SIZE >> PAGE_SHIFT); | 288 | ARM_DMA_ZONE_SIZE >> PAGE_SHIFT); |
289 | |||
290 | arm_dma_limit = PHYS_OFFSET + ARM_DMA_ZONE_SIZE - 1; | ||
281 | #endif | 291 | #endif |
282 | 292 | ||
283 | free_area_init_node(0, zone_size, min, zhole_size); | 293 | free_area_init_node(0, zone_size, min, zhole_size); |
@@ -422,6 +432,17 @@ static inline int free_area(unsigned long pfn, unsigned long end, char *s) | |||
422 | return pages; | 432 | return pages; |
423 | } | 433 | } |
424 | 434 | ||
435 | /* | ||
436 | * Poison init memory with an undefined instruction (ARM) or a branch to an | ||
437 | * undefined instruction (Thumb). | ||
438 | */ | ||
439 | static inline void poison_init_mem(void *s, size_t count) | ||
440 | { | ||
441 | u32 *p = (u32 *)s; | ||
442 | while ((count = count - 4)) | ||
443 | *p++ = 0xe7fddef0; | ||
444 | } | ||
445 | |||
425 | static inline void | 446 | static inline void |
426 | free_memmap(unsigned long start_pfn, unsigned long end_pfn) | 447 | free_memmap(unsigned long start_pfn, unsigned long end_pfn) |
427 | { | 448 | { |
@@ -639,8 +660,8 @@ void __init mem_init(void) | |||
639 | " pkmap : 0x%08lx - 0x%08lx (%4ld MB)\n" | 660 | " pkmap : 0x%08lx - 0x%08lx (%4ld MB)\n" |
640 | #endif | 661 | #endif |
641 | " modules : 0x%08lx - 0x%08lx (%4ld MB)\n" | 662 | " modules : 0x%08lx - 0x%08lx (%4ld MB)\n" |
642 | " .init : 0x%p" " - 0x%p" " (%4d kB)\n" | ||
643 | " .text : 0x%p" " - 0x%p" " (%4d kB)\n" | 663 | " .text : 0x%p" " - 0x%p" " (%4d kB)\n" |
664 | " .init : 0x%p" " - 0x%p" " (%4d kB)\n" | ||
644 | " .data : 0x%p" " - 0x%p" " (%4d kB)\n" | 665 | " .data : 0x%p" " - 0x%p" " (%4d kB)\n" |
645 | " .bss : 0x%p" " - 0x%p" " (%4d kB)\n", | 666 | " .bss : 0x%p" " - 0x%p" " (%4d kB)\n", |
646 | 667 | ||
@@ -662,8 +683,8 @@ void __init mem_init(void) | |||
662 | #endif | 683 | #endif |
663 | MLM(MODULES_VADDR, MODULES_END), | 684 | MLM(MODULES_VADDR, MODULES_END), |
664 | 685 | ||
665 | MLK_ROUNDUP(__init_begin, __init_end), | ||
666 | MLK_ROUNDUP(_text, _etext), | 686 | MLK_ROUNDUP(_text, _etext), |
687 | MLK_ROUNDUP(__init_begin, __init_end), | ||
667 | MLK_ROUNDUP(_sdata, _edata), | 688 | MLK_ROUNDUP(_sdata, _edata), |
668 | MLK_ROUNDUP(__bss_start, __bss_stop)); | 689 | MLK_ROUNDUP(__bss_start, __bss_stop)); |
669 | 690 | ||
@@ -704,11 +725,13 @@ void free_initmem(void) | |||
704 | #ifdef CONFIG_HAVE_TCM | 725 | #ifdef CONFIG_HAVE_TCM |
705 | extern char __tcm_start, __tcm_end; | 726 | extern char __tcm_start, __tcm_end; |
706 | 727 | ||
728 | poison_init_mem(&__tcm_start, &__tcm_end - &__tcm_start); | ||
707 | totalram_pages += free_area(__phys_to_pfn(__pa(&__tcm_start)), | 729 | totalram_pages += free_area(__phys_to_pfn(__pa(&__tcm_start)), |
708 | __phys_to_pfn(__pa(&__tcm_end)), | 730 | __phys_to_pfn(__pa(&__tcm_end)), |
709 | "TCM link"); | 731 | "TCM link"); |
710 | #endif | 732 | #endif |
711 | 733 | ||
734 | poison_init_mem(__init_begin, __init_end - __init_begin); | ||
712 | if (!machine_is_integrator() && !machine_is_cintegrator()) | 735 | if (!machine_is_integrator() && !machine_is_cintegrator()) |
713 | totalram_pages += free_area(__phys_to_pfn(__pa(__init_begin)), | 736 | totalram_pages += free_area(__phys_to_pfn(__pa(__init_begin)), |
714 | __phys_to_pfn(__pa(__init_end)), | 737 | __phys_to_pfn(__pa(__init_end)), |
@@ -721,10 +744,12 @@ static int keep_initrd; | |||
721 | 744 | ||
722 | void free_initrd_mem(unsigned long start, unsigned long end) | 745 | void free_initrd_mem(unsigned long start, unsigned long end) |
723 | { | 746 | { |
724 | if (!keep_initrd) | 747 | if (!keep_initrd) { |
748 | poison_init_mem((void *)start, PAGE_ALIGN(end) - start); | ||
725 | totalram_pages += free_area(__phys_to_pfn(__pa(start)), | 749 | totalram_pages += free_area(__phys_to_pfn(__pa(start)), |
726 | __phys_to_pfn(__pa(end)), | 750 | __phys_to_pfn(__pa(end)), |
727 | "initrd"); | 751 | "initrd"); |
752 | } | ||
728 | } | 753 | } |
729 | 754 | ||
730 | static int __init keepinitrd_setup(char *__unused) | 755 | static int __init keepinitrd_setup(char *__unused) |
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h index 5b3d7d543659..010566799c80 100644 --- a/arch/arm/mm/mm.h +++ b/arch/arm/mm/mm.h | |||
@@ -23,5 +23,11 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page | |||
23 | 23 | ||
24 | #endif | 24 | #endif |
25 | 25 | ||
26 | #ifdef CONFIG_ZONE_DMA | ||
27 | extern u32 arm_dma_limit; | ||
28 | #else | ||
29 | #define arm_dma_limit ((u32)~0) | ||
30 | #endif | ||
31 | |||
26 | void __init bootmem_init(void); | 32 | void __init bootmem_init(void); |
27 | void arm_mm_memblock_reserve(void); | 33 | void arm_mm_memblock_reserve(void); |
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 9d9e736c2b4f..594d677b92c8 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c | |||
@@ -759,7 +759,7 @@ early_param("vmalloc", early_vmalloc); | |||
759 | 759 | ||
760 | static phys_addr_t lowmem_limit __initdata = 0; | 760 | static phys_addr_t lowmem_limit __initdata = 0; |
761 | 761 | ||
762 | static void __init sanity_check_meminfo(void) | 762 | void __init sanity_check_meminfo(void) |
763 | { | 763 | { |
764 | int i, j, highmem = 0; | 764 | int i, j, highmem = 0; |
765 | 765 | ||
@@ -1032,8 +1032,9 @@ void __init paging_init(struct machine_desc *mdesc) | |||
1032 | { | 1032 | { |
1033 | void *zero_page; | 1033 | void *zero_page; |
1034 | 1034 | ||
1035 | memblock_set_current_limit(lowmem_limit); | ||
1036 | |||
1035 | build_mem_type_table(); | 1037 | build_mem_type_table(); |
1036 | sanity_check_meminfo(); | ||
1037 | prepare_page_table(); | 1038 | prepare_page_table(); |
1038 | map_lowmem(); | 1039 | map_lowmem(); |
1039 | devicemaps_init(mdesc); | 1040 | devicemaps_init(mdesc); |
diff --git a/arch/arm/mm/nommu.c b/arch/arm/mm/nommu.c index 687d02319a41..941a98c9e8aa 100644 --- a/arch/arm/mm/nommu.c +++ b/arch/arm/mm/nommu.c | |||
@@ -27,6 +27,10 @@ void __init arm_mm_memblock_reserve(void) | |||
27 | memblock_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE); | 27 | memblock_reserve(CONFIG_VECTORS_BASE, PAGE_SIZE); |
28 | } | 28 | } |
29 | 29 | ||
30 | void __init sanity_check_meminfo(void) | ||
31 | { | ||
32 | } | ||
33 | |||
30 | /* | 34 | /* |
31 | * paging_init() sets up the page tables, initialises the zone memory | 35 | * paging_init() sets up the page tables, initialises the zone memory |
32 | * maps, and sets up the zero page, bad page and bad page tables. | 36 | * maps, and sets up the zero page, bad page and bad page tables. |
diff --git a/arch/arm/mm/pabort-legacy.S b/arch/arm/mm/pabort-legacy.S index 87970eba88ea..8bbff025269a 100644 --- a/arch/arm/mm/pabort-legacy.S +++ b/arch/arm/mm/pabort-legacy.S | |||
@@ -4,16 +4,18 @@ | |||
4 | /* | 4 | /* |
5 | * Function: legacy_pabort | 5 | * Function: legacy_pabort |
6 | * | 6 | * |
7 | * Params : r0 = address of aborted instruction | 7 | * Params : r2 = pt_regs |
8 | * : r4 = address of aborted instruction | ||
9 | * : r5 = psr for parent context | ||
8 | * | 10 | * |
9 | * Returns : r0 = address of abort | 11 | * Returns : r4 - r11, r13 preserved |
10 | * : r1 = Simulated IFSR with section translation fault status | ||
11 | * | 12 | * |
12 | * Purpose : obtain information about current prefetch abort. | 13 | * Purpose : obtain information about current prefetch abort. |
13 | */ | 14 | */ |
14 | 15 | ||
15 | .align 5 | 16 | .align 5 |
16 | ENTRY(legacy_pabort) | 17 | ENTRY(legacy_pabort) |
18 | mov r0, r4 | ||
17 | mov r1, #5 | 19 | mov r1, #5 |
18 | mov pc, lr | 20 | b do_PrefetchAbort |
19 | ENDPROC(legacy_pabort) | 21 | ENDPROC(legacy_pabort) |
diff --git a/arch/arm/mm/pabort-v6.S b/arch/arm/mm/pabort-v6.S index 06e3d1ef2115..9627646ce783 100644 --- a/arch/arm/mm/pabort-v6.S +++ b/arch/arm/mm/pabort-v6.S | |||
@@ -4,16 +4,18 @@ | |||
4 | /* | 4 | /* |
5 | * Function: v6_pabort | 5 | * Function: v6_pabort |
6 | * | 6 | * |
7 | * Params : r0 = address of aborted instruction | 7 | * Params : r2 = pt_regs |
8 | * : r4 = address of aborted instruction | ||
9 | * : r5 = psr for parent context | ||
8 | * | 10 | * |
9 | * Returns : r0 = address of abort | 11 | * Returns : r4 - r11, r13 preserved |
10 | * : r1 = IFSR | ||
11 | * | 12 | * |
12 | * Purpose : obtain information about current prefetch abort. | 13 | * Purpose : obtain information about current prefetch abort. |
13 | */ | 14 | */ |
14 | 15 | ||
15 | .align 5 | 16 | .align 5 |
16 | ENTRY(v6_pabort) | 17 | ENTRY(v6_pabort) |
18 | mov r0, r4 | ||
17 | mrc p15, 0, r1, c5, c0, 1 @ get IFSR | 19 | mrc p15, 0, r1, c5, c0, 1 @ get IFSR |
18 | mov pc, lr | 20 | b do_PrefetchAbort |
19 | ENDPROC(v6_pabort) | 21 | ENDPROC(v6_pabort) |
diff --git a/arch/arm/mm/pabort-v7.S b/arch/arm/mm/pabort-v7.S index a8b3b300a18d..875761f44f3b 100644 --- a/arch/arm/mm/pabort-v7.S +++ b/arch/arm/mm/pabort-v7.S | |||
@@ -2,12 +2,13 @@ | |||
2 | #include <asm/assembler.h> | 2 | #include <asm/assembler.h> |
3 | 3 | ||
4 | /* | 4 | /* |
5 | * Function: v6_pabort | 5 | * Function: v7_pabort |
6 | * | 6 | * |
7 | * Params : r0 = address of aborted instruction | 7 | * Params : r2 = pt_regs |
8 | * : r4 = address of aborted instruction | ||
9 | * : r5 = psr for parent context | ||
8 | * | 10 | * |
9 | * Returns : r0 = address of abort | 11 | * Returns : r4 - r11, r13 preserved |
10 | * : r1 = IFSR | ||
11 | * | 12 | * |
12 | * Purpose : obtain information about current prefetch abort. | 13 | * Purpose : obtain information about current prefetch abort. |
13 | */ | 14 | */ |
@@ -16,5 +17,5 @@ | |||
16 | ENTRY(v7_pabort) | 17 | ENTRY(v7_pabort) |
17 | mrc p15, 0, r0, c6, c0, 2 @ get IFAR | 18 | mrc p15, 0, r0, c6, c0, 2 @ get IFAR |
18 | mrc p15, 0, r1, c5, c0, 1 @ get IFSR | 19 | mrc p15, 0, r1, c5, c0, 1 @ get IFSR |
19 | mov pc, lr | 20 | b do_PrefetchAbort |
20 | ENDPROC(v7_pabort) | 21 | ENDPROC(v7_pabort) |
diff --git a/arch/arm/mm/proc-arm6_7.S b/arch/arm/mm/proc-arm6_7.S index 5f79dc4ce3fb..50e3543d03bf 100644 --- a/arch/arm/mm/proc-arm6_7.S +++ b/arch/arm/mm/proc-arm6_7.S | |||
@@ -29,19 +29,19 @@ ENTRY(cpu_arm7_dcache_clean_area) | |||
29 | /* | 29 | /* |
30 | * Function: arm6_7_data_abort () | 30 | * Function: arm6_7_data_abort () |
31 | * | 31 | * |
32 | * Params : r2 = address of aborted instruction | 32 | * Params : r2 = pt_regs |
33 | * : sp = pointer to registers | 33 | * : r4 = aborted context pc |
34 | * : r5 = aborted context psr | ||
34 | * | 35 | * |
35 | * Purpose : obtain information about current aborted instruction | 36 | * Purpose : obtain information about current aborted instruction |
36 | * | 37 | * |
37 | * Returns : r0 = address of abort | 38 | * Returns : r4-r5, r10-r11, r13 preserved |
38 | * : r1 = FSR | ||
39 | */ | 39 | */ |
40 | 40 | ||
41 | ENTRY(cpu_arm7_data_abort) | 41 | ENTRY(cpu_arm7_data_abort) |
42 | mrc p15, 0, r1, c5, c0, 0 @ get FSR | 42 | mrc p15, 0, r1, c5, c0, 0 @ get FSR |
43 | mrc p15, 0, r0, c6, c0, 0 @ get FAR | 43 | mrc p15, 0, r0, c6, c0, 0 @ get FAR |
44 | ldr r8, [r2] @ read arm instruction | 44 | ldr r8, [r4] @ read arm instruction |
45 | tst r8, #1 << 20 @ L = 0 -> write? | 45 | tst r8, #1 << 20 @ L = 0 -> write? |
46 | orreq r1, r1, #1 << 11 @ yes. | 46 | orreq r1, r1, #1 << 11 @ yes. |
47 | and r7, r8, #15 << 24 | 47 | and r7, r8, #15 << 24 |
@@ -49,7 +49,7 @@ ENTRY(cpu_arm7_data_abort) | |||
49 | nop | 49 | nop |
50 | 50 | ||
51 | /* 0 */ b .data_unknown | 51 | /* 0 */ b .data_unknown |
52 | /* 1 */ mov pc, lr @ swp | 52 | /* 1 */ b do_DataAbort @ swp |
53 | /* 2 */ b .data_unknown | 53 | /* 2 */ b .data_unknown |
54 | /* 3 */ b .data_unknown | 54 | /* 3 */ b .data_unknown |
55 | /* 4 */ b .data_arm_lateldrpostconst @ ldr rd, [rn], #m | 55 | /* 4 */ b .data_arm_lateldrpostconst @ ldr rd, [rn], #m |
@@ -60,87 +60,85 @@ ENTRY(cpu_arm7_data_abort) | |||
60 | /* 9 */ b .data_arm_ldmstm @ ldm*b rn, <rlist> | 60 | /* 9 */ b .data_arm_ldmstm @ ldm*b rn, <rlist> |
61 | /* a */ b .data_unknown | 61 | /* a */ b .data_unknown |
62 | /* b */ b .data_unknown | 62 | /* b */ b .data_unknown |
63 | /* c */ mov pc, lr @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m | 63 | /* c */ b do_DataAbort @ ldc rd, [rn], #m @ Same as ldr rd, [rn], #m |
64 | /* d */ mov pc, lr @ ldc rd, [rn, #m] | 64 | /* d */ b do_DataAbort @ ldc rd, [rn, #m] |
65 | /* e */ b .data_unknown | 65 | /* e */ b .data_unknown |
66 | /* f */ | 66 | /* f */ |
67 | .data_unknown: @ Part of jumptable | 67 | .data_unknown: @ Part of jumptable |
68 | mov r0, r2 | 68 | mov r0, r4 |
69 | mov r1, r8 | 69 | mov r1, r8 |
70 | mov r2, sp | 70 | b baddataabort |
71 | bl baddataabort | ||
72 | b ret_from_exception | ||
73 | 71 | ||
74 | ENTRY(cpu_arm6_data_abort) | 72 | ENTRY(cpu_arm6_data_abort) |
75 | mrc p15, 0, r1, c5, c0, 0 @ get FSR | 73 | mrc p15, 0, r1, c5, c0, 0 @ get FSR |
76 | mrc p15, 0, r0, c6, c0, 0 @ get FAR | 74 | mrc p15, 0, r0, c6, c0, 0 @ get FAR |
77 | ldr r8, [r2] @ read arm instruction | 75 | ldr r8, [r4] @ read arm instruction |
78 | tst r8, #1 << 20 @ L = 0 -> write? | 76 | tst r8, #1 << 20 @ L = 0 -> write? |
79 | orreq r1, r1, #1 << 11 @ yes. | 77 | orreq r1, r1, #1 << 11 @ yes. |
80 | and r7, r8, #14 << 24 | 78 | and r7, r8, #14 << 24 |
81 | teq r7, #8 << 24 @ was it ldm/stm | 79 | teq r7, #8 << 24 @ was it ldm/stm |
82 | movne pc, lr | 80 | bne do_DataAbort |
83 | 81 | ||
84 | .data_arm_ldmstm: | 82 | .data_arm_ldmstm: |
85 | tst r8, #1 << 21 @ check writeback bit | 83 | tst r8, #1 << 21 @ check writeback bit |
86 | moveq pc, lr @ no writeback -> no fixup | 84 | beq do_DataAbort @ no writeback -> no fixup |
87 | mov r7, #0x11 | 85 | mov r7, #0x11 |
88 | orr r7, r7, #0x1100 | 86 | orr r7, r7, #0x1100 |
89 | and r6, r8, r7 | 87 | and r6, r8, r7 |
90 | and r2, r8, r7, lsl #1 | 88 | and r9, r8, r7, lsl #1 |
91 | add r6, r6, r2, lsr #1 | 89 | add r6, r6, r9, lsr #1 |
92 | and r2, r8, r7, lsl #2 | 90 | and r9, r8, r7, lsl #2 |
93 | add r6, r6, r2, lsr #2 | 91 | add r6, r6, r9, lsr #2 |
94 | and r2, r8, r7, lsl #3 | 92 | and r9, r8, r7, lsl #3 |
95 | add r6, r6, r2, lsr #3 | 93 | add r6, r6, r9, lsr #3 |
96 | add r6, r6, r6, lsr #8 | 94 | add r6, r6, r6, lsr #8 |
97 | add r6, r6, r6, lsr #4 | 95 | add r6, r6, r6, lsr #4 |
98 | and r6, r6, #15 @ r6 = no. of registers to transfer. | 96 | and r6, r6, #15 @ r6 = no. of registers to transfer. |
99 | and r5, r8, #15 << 16 @ Extract 'n' from instruction | 97 | and r9, r8, #15 << 16 @ Extract 'n' from instruction |
100 | ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' | 98 | ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' |
101 | tst r8, #1 << 23 @ Check U bit | 99 | tst r8, #1 << 23 @ Check U bit |
102 | subne r7, r7, r6, lsl #2 @ Undo increment | 100 | subne r7, r7, r6, lsl #2 @ Undo increment |
103 | addeq r7, r7, r6, lsl #2 @ Undo decrement | 101 | addeq r7, r7, r6, lsl #2 @ Undo decrement |
104 | str r7, [sp, r5, lsr #14] @ Put register 'Rn' | 102 | str r7, [r2, r9, lsr #14] @ Put register 'Rn' |
105 | mov pc, lr | 103 | b do_DataAbort |
106 | 104 | ||
107 | .data_arm_apply_r6_and_rn: | 105 | .data_arm_apply_r6_and_rn: |
108 | and r5, r8, #15 << 16 @ Extract 'n' from instruction | 106 | and r9, r8, #15 << 16 @ Extract 'n' from instruction |
109 | ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' | 107 | ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' |
110 | tst r8, #1 << 23 @ Check U bit | 108 | tst r8, #1 << 23 @ Check U bit |
111 | subne r7, r7, r6 @ Undo incrmenet | 109 | subne r7, r7, r6 @ Undo incrmenet |
112 | addeq r7, r7, r6 @ Undo decrement | 110 | addeq r7, r7, r6 @ Undo decrement |
113 | str r7, [sp, r5, lsr #14] @ Put register 'Rn' | 111 | str r7, [r2, r9, lsr #14] @ Put register 'Rn' |
114 | mov pc, lr | 112 | b do_DataAbort |
115 | 113 | ||
116 | .data_arm_lateldrpreconst: | 114 | .data_arm_lateldrpreconst: |
117 | tst r8, #1 << 21 @ check writeback bit | 115 | tst r8, #1 << 21 @ check writeback bit |
118 | moveq pc, lr @ no writeback -> no fixup | 116 | beq do_DataAbort @ no writeback -> no fixup |
119 | .data_arm_lateldrpostconst: | 117 | .data_arm_lateldrpostconst: |
120 | movs r2, r8, lsl #20 @ Get offset | 118 | movs r6, r8, lsl #20 @ Get offset |
121 | moveq pc, lr @ zero -> no fixup | 119 | beq do_DataAbort @ zero -> no fixup |
122 | and r5, r8, #15 << 16 @ Extract 'n' from instruction | 120 | and r9, r8, #15 << 16 @ Extract 'n' from instruction |
123 | ldr r7, [sp, r5, lsr #14] @ Get register 'Rn' | 121 | ldr r7, [r2, r9, lsr #14] @ Get register 'Rn' |
124 | tst r8, #1 << 23 @ Check U bit | 122 | tst r8, #1 << 23 @ Check U bit |
125 | subne r7, r7, r2, lsr #20 @ Undo increment | 123 | subne r7, r7, r6, lsr #20 @ Undo increment |
126 | addeq r7, r7, r2, lsr #20 @ Undo decrement | 124 | addeq r7, r7, r6, lsr #20 @ Undo decrement |
127 | str r7, [sp, r5, lsr #14] @ Put register 'Rn' | 125 | str r7, [r2, r9, lsr #14] @ Put register 'Rn' |
128 | mov pc, lr | 126 | b do_DataAbort |
129 | 127 | ||
130 | .data_arm_lateldrprereg: | 128 | .data_arm_lateldrprereg: |
131 | tst r8, #1 << 21 @ check writeback bit | 129 | tst r8, #1 << 21 @ check writeback bit |
132 | moveq pc, lr @ no writeback -> no fixup | 130 | beq do_DataAbort @ no writeback -> no fixup |
133 | .data_arm_lateldrpostreg: | 131 | .data_arm_lateldrpostreg: |
134 | and r7, r8, #15 @ Extract 'm' from instruction | 132 | and r7, r8, #15 @ Extract 'm' from instruction |
135 | ldr r6, [sp, r7, lsl #2] @ Get register 'Rm' | 133 | ldr r6, [r2, r7, lsl #2] @ Get register 'Rm' |
136 | mov r5, r8, lsr #7 @ get shift count | 134 | mov r9, r8, lsr #7 @ get shift count |
137 | ands r5, r5, #31 | 135 | ands r9, r9, #31 |
138 | and r7, r8, #0x70 @ get shift type | 136 | and r7, r8, #0x70 @ get shift type |
139 | orreq r7, r7, #8 @ shift count = 0 | 137 | orreq r7, r7, #8 @ shift count = 0 |
140 | add pc, pc, r7 | 138 | add pc, pc, r7 |
141 | nop | 139 | nop |
142 | 140 | ||
143 | mov r6, r6, lsl r5 @ 0: LSL #!0 | 141 | mov r6, r6, lsl r9 @ 0: LSL #!0 |
144 | b .data_arm_apply_r6_and_rn | 142 | b .data_arm_apply_r6_and_rn |
145 | b .data_arm_apply_r6_and_rn @ 1: LSL #0 | 143 | b .data_arm_apply_r6_and_rn @ 1: LSL #0 |
146 | nop | 144 | nop |
@@ -148,7 +146,7 @@ ENTRY(cpu_arm6_data_abort) | |||
148 | nop | 146 | nop |
149 | b .data_unknown @ 3: MUL? | 147 | b .data_unknown @ 3: MUL? |
150 | nop | 148 | nop |
151 | mov r6, r6, lsr r5 @ 4: LSR #!0 | 149 | mov r6, r6, lsr r9 @ 4: LSR #!0 |
152 | b .data_arm_apply_r6_and_rn | 150 | b .data_arm_apply_r6_and_rn |
153 | mov r6, r6, lsr #32 @ 5: LSR #32 | 151 | mov r6, r6, lsr #32 @ 5: LSR #32 |
154 | b .data_arm_apply_r6_and_rn | 152 | b .data_arm_apply_r6_and_rn |
@@ -156,7 +154,7 @@ ENTRY(cpu_arm6_data_abort) | |||
156 | nop | 154 | nop |
157 | b .data_unknown @ 7: MUL? | 155 | b .data_unknown @ 7: MUL? |
158 | nop | 156 | nop |
159 | mov r6, r6, asr r5 @ 8: ASR #!0 | 157 | mov r6, r6, asr r9 @ 8: ASR #!0 |
160 | b .data_arm_apply_r6_and_rn | 158 | b .data_arm_apply_r6_and_rn |
161 | mov r6, r6, asr #32 @ 9: ASR #32 | 159 | mov r6, r6, asr #32 @ 9: ASR #32 |
162 | b .data_arm_apply_r6_and_rn | 160 | b .data_arm_apply_r6_and_rn |
@@ -164,7 +162,7 @@ ENTRY(cpu_arm6_data_abort) | |||
164 | nop | 162 | nop |
165 | b .data_unknown @ B: MUL? | 163 | b .data_unknown @ B: MUL? |
166 | nop | 164 | nop |
167 | mov r6, r6, ror r5 @ C: ROR #!0 | 165 | mov r6, r6, ror r9 @ C: ROR #!0 |
168 | b .data_arm_apply_r6_and_rn | 166 | b .data_arm_apply_r6_and_rn |
169 | mov r6, r6, rrx @ D: RRX | 167 | mov r6, r6, rrx @ D: RRX |
170 | b .data_arm_apply_r6_and_rn | 168 | b .data_arm_apply_r6_and_rn |
diff --git a/arch/arm/mm/proc-sa1100.S b/arch/arm/mm/proc-sa1100.S index 184a9c997e36..e9c47271732d 100644 --- a/arch/arm/mm/proc-sa1100.S +++ b/arch/arm/mm/proc-sa1100.S | |||
@@ -34,7 +34,7 @@ | |||
34 | */ | 34 | */ |
35 | #define DCACHELINESIZE 32 | 35 | #define DCACHELINESIZE 32 |
36 | 36 | ||
37 | __INIT | 37 | .section .text |
38 | 38 | ||
39 | /* | 39 | /* |
40 | * cpu_sa1100_proc_init() | 40 | * cpu_sa1100_proc_init() |
@@ -45,8 +45,6 @@ ENTRY(cpu_sa1100_proc_init) | |||
45 | mcr p15, 0, r0, c9, c0, 5 @ Allow read-buffer operations from userland | 45 | mcr p15, 0, r0, c9, c0, 5 @ Allow read-buffer operations from userland |
46 | mov pc, lr | 46 | mov pc, lr |
47 | 47 | ||
48 | .section .text | ||
49 | |||
50 | /* | 48 | /* |
51 | * cpu_sa1100_proc_fin() | 49 | * cpu_sa1100_proc_fin() |
52 | * | 50 | * |
diff --git a/arch/arm/mm/tlb-fa.S b/arch/arm/mm/tlb-fa.S index 9694f1f6f485..d887a31faaae 100644 --- a/arch/arm/mm/tlb-fa.S +++ b/arch/arm/mm/tlb-fa.S | |||
@@ -46,7 +46,6 @@ ENTRY(fa_flush_user_tlb_range) | |||
46 | add r0, r0, #PAGE_SZ | 46 | add r0, r0, #PAGE_SZ |
47 | cmp r0, r1 | 47 | cmp r0, r1 |
48 | blo 1b | 48 | blo 1b |
49 | mcr p15, 0, r3, c7, c5, 6 @ invalidate BTB | ||
50 | mcr p15, 0, r3, c7, c10, 4 @ data write barrier | 49 | mcr p15, 0, r3, c7, c10, 4 @ data write barrier |
51 | mov pc, lr | 50 | mov pc, lr |
52 | 51 | ||
@@ -60,9 +59,8 @@ ENTRY(fa_flush_kern_tlb_range) | |||
60 | add r0, r0, #PAGE_SZ | 59 | add r0, r0, #PAGE_SZ |
61 | cmp r0, r1 | 60 | cmp r0, r1 |
62 | blo 1b | 61 | blo 1b |
63 | mcr p15, 0, r3, c7, c5, 6 @ invalidate BTB | ||
64 | mcr p15, 0, r3, c7, c10, 4 @ data write barrier | 62 | mcr p15, 0, r3, c7, c10, 4 @ data write barrier |
65 | mcr p15, 0, r3, c7, c5, 4 @ prefetch flush | 63 | mcr p15, 0, r3, c7, c5, 4 @ prefetch flush (isb) |
66 | mov pc, lr | 64 | mov pc, lr |
67 | 65 | ||
68 | __INITDATA | 66 | __INITDATA |
diff --git a/arch/arm/mm/tlb-v6.S b/arch/arm/mm/tlb-v6.S index 73d7d89b04c4..ffe06a69a6e5 100644 --- a/arch/arm/mm/tlb-v6.S +++ b/arch/arm/mm/tlb-v6.S | |||
@@ -54,7 +54,6 @@ ENTRY(v6wbi_flush_user_tlb_range) | |||
54 | add r0, r0, #PAGE_SZ | 54 | add r0, r0, #PAGE_SZ |
55 | cmp r0, r1 | 55 | cmp r0, r1 |
56 | blo 1b | 56 | blo 1b |
57 | mcr p15, 0, ip, c7, c5, 6 @ flush BTAC/BTB | ||
58 | mcr p15, 0, ip, c7, c10, 4 @ data synchronization barrier | 57 | mcr p15, 0, ip, c7, c10, 4 @ data synchronization barrier |
59 | mov pc, lr | 58 | mov pc, lr |
60 | 59 | ||
@@ -83,9 +82,8 @@ ENTRY(v6wbi_flush_kern_tlb_range) | |||
83 | add r0, r0, #PAGE_SZ | 82 | add r0, r0, #PAGE_SZ |
84 | cmp r0, r1 | 83 | cmp r0, r1 |
85 | blo 1b | 84 | blo 1b |
86 | mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB | ||
87 | mcr p15, 0, r2, c7, c10, 4 @ data synchronization barrier | 85 | mcr p15, 0, r2, c7, c10, 4 @ data synchronization barrier |
88 | mcr p15, 0, r2, c7, c5, 4 @ prefetch flush | 86 | mcr p15, 0, r2, c7, c5, 4 @ prefetch flush (isb) |
89 | mov pc, lr | 87 | mov pc, lr |
90 | 88 | ||
91 | __INIT | 89 | __INIT |
diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S index 53cd5b454673..86bb71664508 100644 --- a/arch/arm/mm/tlb-v7.S +++ b/arch/arm/mm/tlb-v7.S | |||
@@ -48,9 +48,6 @@ ENTRY(v7wbi_flush_user_tlb_range) | |||
48 | add r0, r0, #PAGE_SZ | 48 | add r0, r0, #PAGE_SZ |
49 | cmp r0, r1 | 49 | cmp r0, r1 |
50 | blo 1b | 50 | blo 1b |
51 | mov ip, #0 | ||
52 | ALT_SMP(mcr p15, 0, ip, c7, c1, 6) @ flush BTAC/BTB Inner Shareable | ||
53 | ALT_UP(mcr p15, 0, ip, c7, c5, 6) @ flush BTAC/BTB | ||
54 | dsb | 51 | dsb |
55 | mov pc, lr | 52 | mov pc, lr |
56 | ENDPROC(v7wbi_flush_user_tlb_range) | 53 | ENDPROC(v7wbi_flush_user_tlb_range) |
@@ -75,9 +72,6 @@ ENTRY(v7wbi_flush_kern_tlb_range) | |||
75 | add r0, r0, #PAGE_SZ | 72 | add r0, r0, #PAGE_SZ |
76 | cmp r0, r1 | 73 | cmp r0, r1 |
77 | blo 1b | 74 | blo 1b |
78 | mov r2, #0 | ||
79 | ALT_SMP(mcr p15, 0, r2, c7, c1, 6) @ flush BTAC/BTB Inner Shareable | ||
80 | ALT_UP(mcr p15, 0, r2, c7, c5, 6) @ flush BTAC/BTB | ||
81 | dsb | 75 | dsb |
82 | isb | 76 | isb |
83 | mov pc, lr | 77 | mov pc, lr |
diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S index 2e49e71b1b98..066d464d322d 100644 --- a/arch/arm/plat-mxc/include/mach/entry-macro.S +++ b/arch/arm/plat-mxc/include/mach/entry-macro.S | |||
@@ -78,7 +78,3 @@ | |||
78 | movs \irqnr, \irqnr | 78 | movs \irqnr, \irqnr |
79 | #endif | 79 | #endif |
80 | .endm | 80 | .endm |
81 | |||
82 | @ irq priority table (not used) | ||
83 | .macro irq_prio_table | ||
84 | .endm | ||
diff --git a/arch/arm/plat-omap/sram.c b/arch/arm/plat-omap/sram.c index 6af3d0b1f8d0..363c91e44efb 100644 --- a/arch/arm/plat-omap/sram.c +++ b/arch/arm/plat-omap/sram.c | |||
@@ -394,20 +394,15 @@ void omap3_sram_restore_context(void) | |||
394 | } | 394 | } |
395 | #endif /* CONFIG_PM */ | 395 | #endif /* CONFIG_PM */ |
396 | 396 | ||
397 | static int __init omap34xx_sram_init(void) | 397 | #endif /* CONFIG_ARCH_OMAP3 */ |
398 | { | 398 | |
399 | _omap3_sram_configure_core_dpll = | ||
400 | omap_sram_push(omap3_sram_configure_core_dpll, | ||
401 | omap3_sram_configure_core_dpll_sz); | ||
402 | omap_push_sram_idle(); | ||
403 | return 0; | ||
404 | } | ||
405 | #else | ||
406 | static inline int omap34xx_sram_init(void) | 399 | static inline int omap34xx_sram_init(void) |
407 | { | 400 | { |
401 | #if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) | ||
402 | omap3_sram_restore_context(); | ||
403 | #endif | ||
408 | return 0; | 404 | return 0; |
409 | } | 405 | } |
410 | #endif | ||
411 | 406 | ||
412 | int __init omap_sram_init(void) | 407 | int __init omap_sram_init(void) |
413 | { | 408 | { |
diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c index 5b4fffab1eb4..41ab97ebe4cf 100644 --- a/arch/arm/plat-orion/gpio.c +++ b/arch/arm/plat-orion/gpio.c | |||
@@ -432,7 +432,7 @@ void __init orion_gpio_init(int gpio_base, int ngpio, | |||
432 | ct->regs.mask = ochip->mask_offset + GPIO_EDGE_MASK_OFF; | 432 | ct->regs.mask = ochip->mask_offset + GPIO_EDGE_MASK_OFF; |
433 | ct->regs.ack = GPIO_EDGE_CAUSE_OFF; | 433 | ct->regs.ack = GPIO_EDGE_CAUSE_OFF; |
434 | ct->type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; | 434 | ct->type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING; |
435 | ct->chip.irq_ack = irq_gc_ack; | 435 | ct->chip.irq_ack = irq_gc_ack_clr_bit; |
436 | ct->chip.irq_mask = irq_gc_mask_clr_bit; | 436 | ct->chip.irq_mask = irq_gc_mask_clr_bit; |
437 | ct->chip.irq_unmask = irq_gc_mask_set_bit; | 437 | ct->chip.irq_unmask = irq_gc_mask_set_bit; |
438 | ct->chip.irq_set_type = gpio_irq_set_type; | 438 | ct->chip.irq_set_type = gpio_irq_set_type; |
diff --git a/arch/arm/plat-pxa/gpio.c b/arch/arm/plat-pxa/gpio.c index 48ebb9479b61..a11dc3670505 100644 --- a/arch/arm/plat-pxa/gpio.c +++ b/arch/arm/plat-pxa/gpio.c | |||
@@ -50,7 +50,7 @@ static inline void __iomem *gpio_chip_base(struct gpio_chip *c) | |||
50 | return container_of(c, struct pxa_gpio_chip, chip)->regbase; | 50 | return container_of(c, struct pxa_gpio_chip, chip)->regbase; |
51 | } | 51 | } |
52 | 52 | ||
53 | static inline struct pxa_gpio_chip *gpio_to_chip(unsigned gpio) | 53 | static inline struct pxa_gpio_chip *gpio_to_pxachip(unsigned gpio) |
54 | { | 54 | { |
55 | return &pxa_gpio_chips[gpio_to_bank(gpio)]; | 55 | return &pxa_gpio_chips[gpio_to_bank(gpio)]; |
56 | } | 56 | } |
@@ -161,7 +161,7 @@ static int pxa_gpio_irq_type(struct irq_data *d, unsigned int type) | |||
161 | int gpio = irq_to_gpio(d->irq); | 161 | int gpio = irq_to_gpio(d->irq); |
162 | unsigned long gpdr, mask = GPIO_bit(gpio); | 162 | unsigned long gpdr, mask = GPIO_bit(gpio); |
163 | 163 | ||
164 | c = gpio_to_chip(gpio); | 164 | c = gpio_to_pxachip(gpio); |
165 | 165 | ||
166 | if (type == IRQ_TYPE_PROBE) { | 166 | if (type == IRQ_TYPE_PROBE) { |
167 | /* Don't mess with enabled GPIOs using preconfigured edges or | 167 | /* Don't mess with enabled GPIOs using preconfigured edges or |
@@ -230,7 +230,7 @@ static void pxa_gpio_demux_handler(unsigned int irq, struct irq_desc *desc) | |||
230 | static void pxa_ack_muxed_gpio(struct irq_data *d) | 230 | static void pxa_ack_muxed_gpio(struct irq_data *d) |
231 | { | 231 | { |
232 | int gpio = irq_to_gpio(d->irq); | 232 | int gpio = irq_to_gpio(d->irq); |
233 | struct pxa_gpio_chip *c = gpio_to_chip(gpio); | 233 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); |
234 | 234 | ||
235 | __raw_writel(GPIO_bit(gpio), c->regbase + GEDR_OFFSET); | 235 | __raw_writel(GPIO_bit(gpio), c->regbase + GEDR_OFFSET); |
236 | } | 236 | } |
@@ -238,7 +238,7 @@ static void pxa_ack_muxed_gpio(struct irq_data *d) | |||
238 | static void pxa_mask_muxed_gpio(struct irq_data *d) | 238 | static void pxa_mask_muxed_gpio(struct irq_data *d) |
239 | { | 239 | { |
240 | int gpio = irq_to_gpio(d->irq); | 240 | int gpio = irq_to_gpio(d->irq); |
241 | struct pxa_gpio_chip *c = gpio_to_chip(gpio); | 241 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); |
242 | uint32_t grer, gfer; | 242 | uint32_t grer, gfer; |
243 | 243 | ||
244 | c->irq_mask &= ~GPIO_bit(gpio); | 244 | c->irq_mask &= ~GPIO_bit(gpio); |
@@ -252,7 +252,7 @@ static void pxa_mask_muxed_gpio(struct irq_data *d) | |||
252 | static void pxa_unmask_muxed_gpio(struct irq_data *d) | 252 | static void pxa_unmask_muxed_gpio(struct irq_data *d) |
253 | { | 253 | { |
254 | int gpio = irq_to_gpio(d->irq); | 254 | int gpio = irq_to_gpio(d->irq); |
255 | struct pxa_gpio_chip *c = gpio_to_chip(gpio); | 255 | struct pxa_gpio_chip *c = gpio_to_pxachip(gpio); |
256 | 256 | ||
257 | c->irq_mask |= GPIO_bit(gpio); | 257 | c->irq_mask |= GPIO_bit(gpio); |
258 | update_edge_detect(c); | 258 | update_edge_detect(c); |
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c index 2abf9660bc6c..539bd0e3defd 100644 --- a/arch/arm/plat-s3c24xx/dma.c +++ b/arch/arm/plat-s3c24xx/dma.c | |||
@@ -712,7 +712,7 @@ static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel); | |||
712 | * get control of an dma channel | 712 | * get control of an dma channel |
713 | */ | 713 | */ |
714 | 714 | ||
715 | int s3c2410_dma_request(unsigned int channel, | 715 | int s3c2410_dma_request(enum dma_ch channel, |
716 | struct s3c2410_dma_client *client, | 716 | struct s3c2410_dma_client *client, |
717 | void *dev) | 717 | void *dev) |
718 | { | 718 | { |
@@ -783,7 +783,7 @@ EXPORT_SYMBOL(s3c2410_dma_request); | |||
783 | * allowed to go through. | 783 | * allowed to go through. |
784 | */ | 784 | */ |
785 | 785 | ||
786 | int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *client) | 786 | int s3c2410_dma_free(enum dma_ch channel, struct s3c2410_dma_client *client) |
787 | { | 787 | { |
788 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); | 788 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); |
789 | unsigned long flags; | 789 | unsigned long flags; |
@@ -974,7 +974,7 @@ static int s3c2410_dma_started(struct s3c2410_dma_chan *chan) | |||
974 | } | 974 | } |
975 | 975 | ||
976 | int | 976 | int |
977 | s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op) | 977 | s3c2410_dma_ctrl(enum dma_ch channel, enum s3c2410_chan_op op) |
978 | { | 978 | { |
979 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); | 979 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); |
980 | 980 | ||
@@ -1021,23 +1021,19 @@ EXPORT_SYMBOL(s3c2410_dma_ctrl); | |||
1021 | * xfersize: size of unit in bytes (1,2,4) | 1021 | * xfersize: size of unit in bytes (1,2,4) |
1022 | */ | 1022 | */ |
1023 | 1023 | ||
1024 | int s3c2410_dma_config(unsigned int channel, | 1024 | int s3c2410_dma_config(enum dma_ch channel, |
1025 | int xferunit) | 1025 | int xferunit) |
1026 | { | 1026 | { |
1027 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); | 1027 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); |
1028 | unsigned int dcon; | 1028 | unsigned int dcon; |
1029 | 1029 | ||
1030 | pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n", | 1030 | pr_debug("%s: chan=%d, xfer_unit=%d\n", __func__, channel, xferunit); |
1031 | __func__, channel, xferunit, dcon); | ||
1032 | 1031 | ||
1033 | if (chan == NULL) | 1032 | if (chan == NULL) |
1034 | return -EINVAL; | 1033 | return -EINVAL; |
1035 | 1034 | ||
1036 | pr_debug("%s: Initial dcon is %08x\n", __func__, dcon); | ||
1037 | |||
1038 | dcon = chan->dcon & dma_sel.dcon_mask; | 1035 | dcon = chan->dcon & dma_sel.dcon_mask; |
1039 | 1036 | pr_debug("%s: dcon is %08x\n", __func__, dcon); | |
1040 | pr_debug("%s: New dcon is %08x\n", __func__, dcon); | ||
1041 | 1037 | ||
1042 | switch (chan->req_ch) { | 1038 | switch (chan->req_ch) { |
1043 | case DMACH_I2S_IN: | 1039 | case DMACH_I2S_IN: |
@@ -1104,7 +1100,7 @@ EXPORT_SYMBOL(s3c2410_dma_config); | |||
1104 | * devaddr: physical address of the source | 1100 | * devaddr: physical address of the source |
1105 | */ | 1101 | */ |
1106 | 1102 | ||
1107 | int s3c2410_dma_devconfig(unsigned int channel, | 1103 | int s3c2410_dma_devconfig(enum dma_ch channel, |
1108 | enum s3c2410_dmasrc source, | 1104 | enum s3c2410_dmasrc source, |
1109 | unsigned long devaddr) | 1105 | unsigned long devaddr) |
1110 | { | 1106 | { |
@@ -1177,7 +1173,7 @@ EXPORT_SYMBOL(s3c2410_dma_devconfig); | |||
1177 | * returns the current transfer points for the dma source and destination | 1173 | * returns the current transfer points for the dma source and destination |
1178 | */ | 1174 | */ |
1179 | 1175 | ||
1180 | int s3c2410_dma_getposition(unsigned int channel, dma_addr_t *src, dma_addr_t *dst) | 1176 | int s3c2410_dma_getposition(enum dma_ch channel, dma_addr_t *src, dma_addr_t *dst) |
1181 | { | 1177 | { |
1182 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); | 1178 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); |
1183 | 1179 | ||
@@ -1235,7 +1231,7 @@ static void s3c2410_dma_resume_chan(struct s3c2410_dma_chan *cp) | |||
1235 | /* restore channel's hardware configuration */ | 1231 | /* restore channel's hardware configuration */ |
1236 | 1232 | ||
1237 | if (!cp->in_use) | 1233 | if (!cp->in_use) |
1238 | return 0; | 1234 | return; |
1239 | 1235 | ||
1240 | printk(KERN_INFO "dma%d: restoring configuration\n", cp->number); | 1236 | printk(KERN_INFO "dma%d: restoring configuration\n", cp->number); |
1241 | 1237 | ||
@@ -1246,8 +1242,6 @@ static void s3c2410_dma_resume_chan(struct s3c2410_dma_chan *cp) | |||
1246 | 1242 | ||
1247 | if (cp->map != NULL) | 1243 | if (cp->map != NULL) |
1248 | dma_sel.select(cp, cp->map); | 1244 | dma_sel.select(cp, cp->map); |
1249 | |||
1250 | return 0; | ||
1251 | } | 1245 | } |
1252 | 1246 | ||
1253 | static void s3c2410_dma_resume(void) | 1247 | static void s3c2410_dma_resume(void) |
diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/plat-s3c24xx/sleep.S index fd7032f84ae7..c56612569b40 100644 --- a/arch/arm/plat-s3c24xx/sleep.S +++ b/arch/arm/plat-s3c24xx/sleep.S | |||
@@ -41,31 +41,6 @@ | |||
41 | 41 | ||
42 | .text | 42 | .text |
43 | 43 | ||
44 | /* s3c_cpu_save | ||
45 | * | ||
46 | * entry: | ||
47 | * r1 = v:p offset | ||
48 | */ | ||
49 | |||
50 | ENTRY(s3c_cpu_save) | ||
51 | stmfd sp!, { r4 - r12, lr } | ||
52 | ldr r3, =resume_with_mmu | ||
53 | bl cpu_suspend | ||
54 | |||
55 | @@ jump to final code to send system to sleep | ||
56 | ldr r0, =pm_cpu_sleep | ||
57 | @@ldr pc, [ r0 ] | ||
58 | ldr r0, [ r0 ] | ||
59 | mov pc, r0 | ||
60 | |||
61 | @@ return to the caller, after having the MMU | ||
62 | @@ turned on, this restores the last bits from the | ||
63 | @@ stack | ||
64 | resume_with_mmu: | ||
65 | ldmfd sp!, { r4 - r12, pc } | ||
66 | |||
67 | .ltorg | ||
68 | |||
69 | /* sleep magic, to allow the bootloader to check for an valid | 44 | /* sleep magic, to allow the bootloader to check for an valid |
70 | * image to resume to. Must be the first word before the | 45 | * image to resume to. Must be the first word before the |
71 | * s3c_cpu_resume entry. | 46 | * s3c_cpu_resume entry. |
diff --git a/arch/arm/plat-s5p/irq-gpioint.c b/arch/arm/plat-s5p/irq-gpioint.c index 135abda31c9a..327ab9f662e8 100644 --- a/arch/arm/plat-s5p/irq-gpioint.c +++ b/arch/arm/plat-s5p/irq-gpioint.c | |||
@@ -152,7 +152,7 @@ static __init int s5p_gpioint_add(struct s3c_gpio_chip *chip) | |||
152 | if (!gc) | 152 | if (!gc) |
153 | return -ENOMEM; | 153 | return -ENOMEM; |
154 | ct = gc->chip_types; | 154 | ct = gc->chip_types; |
155 | ct->chip.irq_ack = irq_gc_ack; | 155 | ct->chip.irq_ack = irq_gc_ack_set_bit; |
156 | ct->chip.irq_mask = irq_gc_mask_set_bit; | 156 | ct->chip.irq_mask = irq_gc_mask_set_bit; |
157 | ct->chip.irq_unmask = irq_gc_mask_clr_bit; | 157 | ct->chip.irq_unmask = irq_gc_mask_clr_bit; |
158 | ct->chip.irq_set_type = s5p_gpioint_set_type, | 158 | ct->chip.irq_set_type = s5p_gpioint_set_type, |
diff --git a/arch/arm/plat-s5p/s5p-time.c b/arch/arm/plat-s5p/s5p-time.c index 899a8cc011ff..612934c48b0d 100644 --- a/arch/arm/plat-s5p/s5p-time.c +++ b/arch/arm/plat-s5p/s5p-time.c | |||
@@ -370,11 +370,11 @@ static void __init s5p_clocksource_init(void) | |||
370 | 370 | ||
371 | clock_rate = clk_get_rate(tin_source); | 371 | clock_rate = clk_get_rate(tin_source); |
372 | 372 | ||
373 | init_sched_clock(&cd, s5p_update_sched_clock, 32, clock_rate); | ||
374 | |||
375 | s5p_time_setup(timer_source.source_id, TCNT_MAX); | 373 | s5p_time_setup(timer_source.source_id, TCNT_MAX); |
376 | s5p_time_start(timer_source.source_id, PERIODIC); | 374 | s5p_time_start(timer_source.source_id, PERIODIC); |
377 | 375 | ||
376 | init_sched_clock(&cd, s5p_update_sched_clock, 32, clock_rate); | ||
377 | |||
378 | if (clocksource_register_hz(&time_clocksource, clock_rate)) | 378 | if (clocksource_register_hz(&time_clocksource, clock_rate)) |
379 | panic("%s: can't register clocksource\n", time_clocksource.name); | 379 | panic("%s: can't register clocksource\n", time_clocksource.name); |
380 | } | 380 | } |
diff --git a/arch/arm/plat-samsung/dma.c b/arch/arm/plat-samsung/dma.c index cb459dd95459..6143aa147688 100644 --- a/arch/arm/plat-samsung/dma.c +++ b/arch/arm/plat-samsung/dma.c | |||
@@ -41,7 +41,7 @@ struct s3c2410_dma_chan *s3c_dma_lookup_channel(unsigned int channel) | |||
41 | * irq? | 41 | * irq? |
42 | */ | 42 | */ |
43 | 43 | ||
44 | int s3c2410_dma_set_opfn(unsigned int channel, s3c2410_dma_opfn_t rtn) | 44 | int s3c2410_dma_set_opfn(enum dma_ch channel, s3c2410_dma_opfn_t rtn) |
45 | { | 45 | { |
46 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); | 46 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); |
47 | 47 | ||
@@ -56,7 +56,7 @@ int s3c2410_dma_set_opfn(unsigned int channel, s3c2410_dma_opfn_t rtn) | |||
56 | } | 56 | } |
57 | EXPORT_SYMBOL(s3c2410_dma_set_opfn); | 57 | EXPORT_SYMBOL(s3c2410_dma_set_opfn); |
58 | 58 | ||
59 | int s3c2410_dma_set_buffdone_fn(unsigned int channel, s3c2410_dma_cbfn_t rtn) | 59 | int s3c2410_dma_set_buffdone_fn(enum dma_ch channel, s3c2410_dma_cbfn_t rtn) |
60 | { | 60 | { |
61 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); | 61 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); |
62 | 62 | ||
@@ -71,7 +71,7 @@ int s3c2410_dma_set_buffdone_fn(unsigned int channel, s3c2410_dma_cbfn_t rtn) | |||
71 | } | 71 | } |
72 | EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn); | 72 | EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn); |
73 | 73 | ||
74 | int s3c2410_dma_setflags(unsigned int channel, unsigned int flags) | 74 | int s3c2410_dma_setflags(enum dma_ch channel, unsigned int flags) |
75 | { | 75 | { |
76 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); | 76 | struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel); |
77 | 77 | ||
diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index 4af108ff4112..e3b31c26ac3e 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h | |||
@@ -12,6 +12,10 @@ | |||
12 | * it under the terms of the GNU General Public License version 2 as | 12 | * it under the terms of the GNU General Public License version 2 as |
13 | * published by the Free Software Foundation. | 13 | * published by the Free Software Foundation. |
14 | */ | 14 | */ |
15 | |||
16 | #ifndef __PLAT_DEVS_H | ||
17 | #define __PLAT_DEVS_H __FILE__ | ||
18 | |||
15 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
16 | 20 | ||
17 | struct s3c24xx_uart_resources { | 21 | struct s3c24xx_uart_resources { |
@@ -159,3 +163,5 @@ extern struct platform_device s3c_device_ac97; | |||
159 | */ | 163 | */ |
160 | extern void *s3c_set_platdata(void *pd, size_t pdsize, | 164 | extern void *s3c_set_platdata(void *pd, size_t pdsize, |
161 | struct platform_device *pdev); | 165 | struct platform_device *pdev); |
166 | |||
167 | #endif /* __PLAT_DEVS_H */ | ||
diff --git a/arch/arm/plat-samsung/include/plat/dma.h b/arch/arm/plat-samsung/include/plat/dma.h index 2e8f8c6560d7..8c273b7a6f56 100644 --- a/arch/arm/plat-samsung/include/plat/dma.h +++ b/arch/arm/plat-samsung/include/plat/dma.h | |||
@@ -42,6 +42,7 @@ struct s3c2410_dma_client { | |||
42 | }; | 42 | }; |
43 | 43 | ||
44 | struct s3c2410_dma_chan; | 44 | struct s3c2410_dma_chan; |
45 | enum dma_ch; | ||
45 | 46 | ||
46 | /* s3c2410_dma_cbfn_t | 47 | /* s3c2410_dma_cbfn_t |
47 | * | 48 | * |
@@ -62,7 +63,7 @@ typedef int (*s3c2410_dma_opfn_t)(struct s3c2410_dma_chan *, | |||
62 | * request a dma channel exclusivley | 63 | * request a dma channel exclusivley |
63 | */ | 64 | */ |
64 | 65 | ||
65 | extern int s3c2410_dma_request(unsigned int channel, | 66 | extern int s3c2410_dma_request(enum dma_ch channel, |
66 | struct s3c2410_dma_client *, void *dev); | 67 | struct s3c2410_dma_client *, void *dev); |
67 | 68 | ||
68 | 69 | ||
@@ -71,14 +72,14 @@ extern int s3c2410_dma_request(unsigned int channel, | |||
71 | * change the state of the dma channel | 72 | * change the state of the dma channel |
72 | */ | 73 | */ |
73 | 74 | ||
74 | extern int s3c2410_dma_ctrl(unsigned int channel, enum s3c2410_chan_op op); | 75 | extern int s3c2410_dma_ctrl(enum dma_ch channel, enum s3c2410_chan_op op); |
75 | 76 | ||
76 | /* s3c2410_dma_setflags | 77 | /* s3c2410_dma_setflags |
77 | * | 78 | * |
78 | * set the channel's flags to a given state | 79 | * set the channel's flags to a given state |
79 | */ | 80 | */ |
80 | 81 | ||
81 | extern int s3c2410_dma_setflags(unsigned int channel, | 82 | extern int s3c2410_dma_setflags(enum dma_ch channel, |
82 | unsigned int flags); | 83 | unsigned int flags); |
83 | 84 | ||
84 | /* s3c2410_dma_free | 85 | /* s3c2410_dma_free |
@@ -86,7 +87,7 @@ extern int s3c2410_dma_setflags(unsigned int channel, | |||
86 | * free the dma channel (will also abort any outstanding operations) | 87 | * free the dma channel (will also abort any outstanding operations) |
87 | */ | 88 | */ |
88 | 89 | ||
89 | extern int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *); | 90 | extern int s3c2410_dma_free(enum dma_ch channel, struct s3c2410_dma_client *); |
90 | 91 | ||
91 | /* s3c2410_dma_enqueue | 92 | /* s3c2410_dma_enqueue |
92 | * | 93 | * |
@@ -95,7 +96,7 @@ extern int s3c2410_dma_free(unsigned int channel, struct s3c2410_dma_client *); | |||
95 | * drained before the buffer is given to the DMA system. | 96 | * drained before the buffer is given to the DMA system. |
96 | */ | 97 | */ |
97 | 98 | ||
98 | extern int s3c2410_dma_enqueue(unsigned int channel, void *id, | 99 | extern int s3c2410_dma_enqueue(enum dma_ch channel, void *id, |
99 | dma_addr_t data, int size); | 100 | dma_addr_t data, int size); |
100 | 101 | ||
101 | /* s3c2410_dma_config | 102 | /* s3c2410_dma_config |
@@ -103,14 +104,14 @@ extern int s3c2410_dma_enqueue(unsigned int channel, void *id, | |||
103 | * configure the dma channel | 104 | * configure the dma channel |
104 | */ | 105 | */ |
105 | 106 | ||
106 | extern int s3c2410_dma_config(unsigned int channel, int xferunit); | 107 | extern int s3c2410_dma_config(enum dma_ch channel, int xferunit); |
107 | 108 | ||
108 | /* s3c2410_dma_devconfig | 109 | /* s3c2410_dma_devconfig |
109 | * | 110 | * |
110 | * configure the device we're talking to | 111 | * configure the device we're talking to |
111 | */ | 112 | */ |
112 | 113 | ||
113 | extern int s3c2410_dma_devconfig(unsigned int channel, | 114 | extern int s3c2410_dma_devconfig(enum dma_ch channel, |
114 | enum s3c2410_dmasrc source, unsigned long devaddr); | 115 | enum s3c2410_dmasrc source, unsigned long devaddr); |
115 | 116 | ||
116 | /* s3c2410_dma_getposition | 117 | /* s3c2410_dma_getposition |
@@ -118,10 +119,10 @@ extern int s3c2410_dma_devconfig(unsigned int channel, | |||
118 | * get the position that the dma transfer is currently at | 119 | * get the position that the dma transfer is currently at |
119 | */ | 120 | */ |
120 | 121 | ||
121 | extern int s3c2410_dma_getposition(unsigned int channel, | 122 | extern int s3c2410_dma_getposition(enum dma_ch channel, |
122 | dma_addr_t *src, dma_addr_t *dest); | 123 | dma_addr_t *src, dma_addr_t *dest); |
123 | 124 | ||
124 | extern int s3c2410_dma_set_opfn(unsigned int, s3c2410_dma_opfn_t rtn); | 125 | extern int s3c2410_dma_set_opfn(enum dma_ch, s3c2410_dma_opfn_t rtn); |
125 | extern int s3c2410_dma_set_buffdone_fn(unsigned int, s3c2410_dma_cbfn_t rtn); | 126 | extern int s3c2410_dma_set_buffdone_fn(enum dma_ch, s3c2410_dma_cbfn_t rtn); |
126 | 127 | ||
127 | 128 | ||
diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h index 7fb6f6be8c81..f6749916d194 100644 --- a/arch/arm/plat-samsung/include/plat/pm.h +++ b/arch/arm/plat-samsung/include/plat/pm.h | |||
@@ -42,7 +42,7 @@ extern unsigned long s3c_irqwake_eintallow; | |||
42 | /* per-cpu sleep functions */ | 42 | /* per-cpu sleep functions */ |
43 | 43 | ||
44 | extern void (*pm_cpu_prep)(void); | 44 | extern void (*pm_cpu_prep)(void); |
45 | extern void (*pm_cpu_sleep)(void); | 45 | extern int (*pm_cpu_sleep)(unsigned long); |
46 | 46 | ||
47 | /* Flags for PM Control */ | 47 | /* Flags for PM Control */ |
48 | 48 | ||
@@ -52,10 +52,9 @@ extern unsigned char pm_uart_udivslot; /* true to save UART UDIVSLOT */ | |||
52 | 52 | ||
53 | /* from sleep.S */ | 53 | /* from sleep.S */ |
54 | 54 | ||
55 | extern int s3c_cpu_save(unsigned long *saveblk, long); | ||
56 | extern void s3c_cpu_resume(void); | 55 | extern void s3c_cpu_resume(void); |
57 | 56 | ||
58 | extern void s3c2410_cpu_suspend(void); | 57 | extern int s3c2410_cpu_suspend(unsigned long); |
59 | 58 | ||
60 | /* sleep save info */ | 59 | /* sleep save info */ |
61 | 60 | ||
diff --git a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h index 0ffe34a21554..4c16fa3621bb 100644 --- a/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h +++ b/arch/arm/plat-samsung/include/plat/s3c64xx-spi.h | |||
@@ -39,6 +39,7 @@ struct s3c64xx_spi_csinfo { | |||
39 | * @fifo_lvl_mask: All tx fifo_lvl fields start at offset-6 | 39 | * @fifo_lvl_mask: All tx fifo_lvl fields start at offset-6 |
40 | * @rx_lvl_offset: Depends on tx fifo_lvl field and bus number | 40 | * @rx_lvl_offset: Depends on tx fifo_lvl field and bus number |
41 | * @high_speed: If the controller supports HIGH_SPEED_EN bit | 41 | * @high_speed: If the controller supports HIGH_SPEED_EN bit |
42 | * @tx_st_done: Depends on tx fifo_lvl field | ||
42 | */ | 43 | */ |
43 | struct s3c64xx_spi_info { | 44 | struct s3c64xx_spi_info { |
44 | int src_clk_nr; | 45 | int src_clk_nr; |
@@ -53,6 +54,7 @@ struct s3c64xx_spi_info { | |||
53 | int fifo_lvl_mask; | 54 | int fifo_lvl_mask; |
54 | int rx_lvl_offset; | 55 | int rx_lvl_offset; |
55 | int high_speed; | 56 | int high_speed; |
57 | int tx_st_done; | ||
56 | }; | 58 | }; |
57 | 59 | ||
58 | /** | 60 | /** |
diff --git a/arch/arm/plat-samsung/irq-uart.c b/arch/arm/plat-samsung/irq-uart.c index 32582c0958e3..657405c481d0 100644 --- a/arch/arm/plat-samsung/irq-uart.c +++ b/arch/arm/plat-samsung/irq-uart.c | |||
@@ -54,8 +54,15 @@ static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq) | |||
54 | 54 | ||
55 | gc = irq_alloc_generic_chip("s3c-uart", 1, uirq->base_irq, reg_base, | 55 | gc = irq_alloc_generic_chip("s3c-uart", 1, uirq->base_irq, reg_base, |
56 | handle_level_irq); | 56 | handle_level_irq); |
57 | |||
58 | if (!gc) { | ||
59 | pr_err("%s: irq_alloc_generic_chip for IRQ %u failed\n", | ||
60 | __func__, uirq->base_irq); | ||
61 | return; | ||
62 | } | ||
63 | |||
57 | ct = gc->chip_types; | 64 | ct = gc->chip_types; |
58 | ct->chip.irq_ack = irq_gc_ack; | 65 | ct->chip.irq_ack = irq_gc_ack_set_bit; |
59 | ct->chip.irq_mask = irq_gc_mask_set_bit; | 66 | ct->chip.irq_mask = irq_gc_mask_set_bit; |
60 | ct->chip.irq_unmask = irq_gc_mask_clr_bit; | 67 | ct->chip.irq_unmask = irq_gc_mask_clr_bit; |
61 | ct->regs.ack = S3C64XX_UINTP; | 68 | ct->regs.ack = S3C64XX_UINTP; |
diff --git a/arch/arm/plat-samsung/irq-vic-timer.c b/arch/arm/plat-samsung/irq-vic-timer.c index a607546ddbd0..f714d060370d 100644 --- a/arch/arm/plat-samsung/irq-vic-timer.c +++ b/arch/arm/plat-samsung/irq-vic-timer.c | |||
@@ -54,6 +54,13 @@ void __init s3c_init_vic_timer_irq(unsigned int num, unsigned int timer_irq) | |||
54 | 54 | ||
55 | s3c_tgc = irq_alloc_generic_chip("s3c-timer", 1, timer_irq, | 55 | s3c_tgc = irq_alloc_generic_chip("s3c-timer", 1, timer_irq, |
56 | S3C64XX_TINT_CSTAT, handle_level_irq); | 56 | S3C64XX_TINT_CSTAT, handle_level_irq); |
57 | |||
58 | if (!s3c_tgc) { | ||
59 | pr_err("%s: irq_alloc_generic_chip for IRQ %d failed\n", | ||
60 | __func__, timer_irq); | ||
61 | return; | ||
62 | } | ||
63 | |||
57 | ct = s3c_tgc->chip_types; | 64 | ct = s3c_tgc->chip_types; |
58 | ct->chip.irq_mask = irq_gc_mask_clr_bit; | 65 | ct->chip.irq_mask = irq_gc_mask_clr_bit; |
59 | ct->chip.irq_unmask = irq_gc_mask_set_bit; | 66 | ct->chip.irq_unmask = irq_gc_mask_set_bit; |
diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c index 5c0a440d6e16..5fa1742d019b 100644 --- a/arch/arm/plat-samsung/pm.c +++ b/arch/arm/plat-samsung/pm.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | 21 | ||
22 | #include <asm/cacheflush.h> | 22 | #include <asm/cacheflush.h> |
23 | #include <asm/suspend.h> | ||
23 | #include <mach/hardware.h> | 24 | #include <mach/hardware.h> |
24 | #include <mach/map.h> | 25 | #include <mach/map.h> |
25 | 26 | ||
@@ -231,7 +232,7 @@ static void __maybe_unused s3c_pm_show_resume_irqs(int start, | |||
231 | 232 | ||
232 | 233 | ||
233 | void (*pm_cpu_prep)(void); | 234 | void (*pm_cpu_prep)(void); |
234 | void (*pm_cpu_sleep)(void); | 235 | int (*pm_cpu_sleep)(unsigned long); |
235 | 236 | ||
236 | #define any_allowed(mask, allow) (((mask) & (allow)) != (allow)) | 237 | #define any_allowed(mask, allow) (((mask) & (allow)) != (allow)) |
237 | 238 | ||
@@ -294,15 +295,11 @@ static int s3c_pm_enter(suspend_state_t state) | |||
294 | 295 | ||
295 | s3c_pm_arch_stop_clocks(); | 296 | s3c_pm_arch_stop_clocks(); |
296 | 297 | ||
297 | /* s3c_cpu_save will also act as our return point from when | 298 | /* this will also act as our return point from when |
298 | * we resume as it saves its own register state and restores it | 299 | * we resume as it saves its own register state and restores it |
299 | * during the resume. */ | 300 | * during the resume. */ |
300 | 301 | ||
301 | s3c_cpu_save(0, PLAT_PHYS_OFFSET - PAGE_OFFSET); | 302 | cpu_suspend(0, pm_cpu_sleep); |
302 | |||
303 | /* restore the cpu state using the kernel's cpu init code. */ | ||
304 | |||
305 | cpu_init(); | ||
306 | 303 | ||
307 | /* restore the system state */ | 304 | /* restore the system state */ |
308 | 305 | ||
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index c018696765d4..5c74eb797f08 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
15 | #include <linux/kernel.h> | 15 | #include <linux/kernel.h> |
16 | #include <linux/spinlock.h> | 16 | #include <linux/spinlock.h> |
17 | #include <linux/sysdev.h> | 17 | #include <linux/syscore_ops.h> |
18 | #include <linux/irq.h> | 18 | #include <linux/irq.h> |
19 | 19 | ||
20 | #include <asm/i8259.h> | 20 | #include <asm/i8259.h> |
@@ -215,14 +215,13 @@ spurious_8259A_irq: | |||
215 | } | 215 | } |
216 | } | 216 | } |
217 | 217 | ||
218 | static int i8259A_resume(struct sys_device *dev) | 218 | static void i8259A_resume(void) |
219 | { | 219 | { |
220 | if (i8259A_auto_eoi >= 0) | 220 | if (i8259A_auto_eoi >= 0) |
221 | init_8259A(i8259A_auto_eoi); | 221 | init_8259A(i8259A_auto_eoi); |
222 | return 0; | ||
223 | } | 222 | } |
224 | 223 | ||
225 | static int i8259A_shutdown(struct sys_device *dev) | 224 | static void i8259A_shutdown(void) |
226 | { | 225 | { |
227 | /* Put the i8259A into a quiescent state that | 226 | /* Put the i8259A into a quiescent state that |
228 | * the kernel initialization code can get it | 227 | * the kernel initialization code can get it |
@@ -232,26 +231,17 @@ static int i8259A_shutdown(struct sys_device *dev) | |||
232 | outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ | 231 | outb(0xff, PIC_MASTER_IMR); /* mask all of 8259A-1 */ |
233 | outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */ | 232 | outb(0xff, PIC_SLAVE_IMR); /* mask all of 8259A-1 */ |
234 | } | 233 | } |
235 | return 0; | ||
236 | } | 234 | } |
237 | 235 | ||
238 | static struct sysdev_class i8259_sysdev_class = { | 236 | static struct syscore_ops i8259_syscore_ops = { |
239 | .name = "i8259", | ||
240 | .resume = i8259A_resume, | 237 | .resume = i8259A_resume, |
241 | .shutdown = i8259A_shutdown, | 238 | .shutdown = i8259A_shutdown, |
242 | }; | 239 | }; |
243 | 240 | ||
244 | static struct sys_device device_i8259A = { | ||
245 | .id = 0, | ||
246 | .cls = &i8259_sysdev_class, | ||
247 | }; | ||
248 | |||
249 | static int __init i8259A_init_sysfs(void) | 241 | static int __init i8259A_init_sysfs(void) |
250 | { | 242 | { |
251 | int error = sysdev_class_register(&i8259_sysdev_class); | 243 | register_syscore_ops(&i8259_syscore_ops); |
252 | if (!error) | 244 | return 0; |
253 | error = sysdev_register(&device_i8259A); | ||
254 | return error; | ||
255 | } | 245 | } |
256 | 246 | ||
257 | device_initcall(i8259A_init_sysfs); | 247 | device_initcall(i8259A_init_sysfs); |
diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 33867ec4a234..9d6a8effeda2 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c | |||
@@ -12,6 +12,8 @@ | |||
12 | #include <linux/of.h> | 12 | #include <linux/of.h> |
13 | #include <linux/memblock.h> | 13 | #include <linux/memblock.h> |
14 | #include <linux/vmalloc.h> | 14 | #include <linux/vmalloc.h> |
15 | #include <linux/memory.h> | ||
16 | |||
15 | #include <asm/firmware.h> | 17 | #include <asm/firmware.h> |
16 | #include <asm/machdep.h> | 18 | #include <asm/machdep.h> |
17 | #include <asm/pSeries_reconfig.h> | 19 | #include <asm/pSeries_reconfig.h> |
@@ -20,24 +22,25 @@ | |||
20 | static unsigned long get_memblock_size(void) | 22 | static unsigned long get_memblock_size(void) |
21 | { | 23 | { |
22 | struct device_node *np; | 24 | struct device_node *np; |
23 | unsigned int memblock_size = 0; | 25 | unsigned int memblock_size = MIN_MEMORY_BLOCK_SIZE; |
26 | struct resource r; | ||
24 | 27 | ||
25 | np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); | 28 | np = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); |
26 | if (np) { | 29 | if (np) { |
27 | const unsigned long *size; | 30 | const __be64 *size; |
28 | 31 | ||
29 | size = of_get_property(np, "ibm,lmb-size", NULL); | 32 | size = of_get_property(np, "ibm,lmb-size", NULL); |
30 | memblock_size = size ? *size : 0; | 33 | if (size) |
31 | 34 | memblock_size = be64_to_cpup(size); | |
32 | of_node_put(np); | 35 | of_node_put(np); |
33 | } else { | 36 | } else if (machine_is(pseries)) { |
37 | /* This fallback really only applies to pseries */ | ||
34 | unsigned int memzero_size = 0; | 38 | unsigned int memzero_size = 0; |
35 | const unsigned int *regs; | ||
36 | 39 | ||
37 | np = of_find_node_by_path("/memory@0"); | 40 | np = of_find_node_by_path("/memory@0"); |
38 | if (np) { | 41 | if (np) { |
39 | regs = of_get_property(np, "reg", NULL); | 42 | if (!of_address_to_resource(np, 0, &r)) |
40 | memzero_size = regs ? regs[3] : 0; | 43 | memzero_size = resource_size(&r); |
41 | of_node_put(np); | 44 | of_node_put(np); |
42 | } | 45 | } |
43 | 46 | ||
@@ -50,16 +53,21 @@ static unsigned long get_memblock_size(void) | |||
50 | sprintf(buf, "/memory@%x", memzero_size); | 53 | sprintf(buf, "/memory@%x", memzero_size); |
51 | np = of_find_node_by_path(buf); | 54 | np = of_find_node_by_path(buf); |
52 | if (np) { | 55 | if (np) { |
53 | regs = of_get_property(np, "reg", NULL); | 56 | if (!of_address_to_resource(np, 0, &r)) |
54 | memblock_size = regs ? regs[3] : 0; | 57 | memblock_size = resource_size(&r); |
55 | of_node_put(np); | 58 | of_node_put(np); |
56 | } | 59 | } |
57 | } | 60 | } |
58 | } | 61 | } |
59 | |||
60 | return memblock_size; | 62 | return memblock_size; |
61 | } | 63 | } |
62 | 64 | ||
65 | /* WARNING: This is going to override the generic definition whenever | ||
66 | * pseries is built-in regardless of what platform is active at boot | ||
67 | * time. This is fine for now as this is the only "option" and it | ||
68 | * should work everywhere. If not, we'll have to turn this into a | ||
69 | * ppc_md. callback | ||
70 | */ | ||
63 | unsigned long memory_block_size_bytes(void) | 71 | unsigned long memory_block_size_bytes(void) |
64 | { | 72 | { |
65 | return get_memblock_size(); | 73 | return get_memblock_size(); |
diff --git a/arch/sparc/include/asm/irqflags_32.h b/arch/sparc/include/asm/irqflags_32.h index d4d0711de0f9..14848909e0de 100644 --- a/arch/sparc/include/asm/irqflags_32.h +++ b/arch/sparc/include/asm/irqflags_32.h | |||
@@ -18,7 +18,7 @@ extern void arch_local_irq_restore(unsigned long); | |||
18 | extern unsigned long arch_local_irq_save(void); | 18 | extern unsigned long arch_local_irq_save(void); |
19 | extern void arch_local_irq_enable(void); | 19 | extern void arch_local_irq_enable(void); |
20 | 20 | ||
21 | static inline unsigned long arch_local_save_flags(void) | 21 | static inline notrace unsigned long arch_local_save_flags(void) |
22 | { | 22 | { |
23 | unsigned long flags; | 23 | unsigned long flags; |
24 | 24 | ||
@@ -26,17 +26,17 @@ static inline unsigned long arch_local_save_flags(void) | |||
26 | return flags; | 26 | return flags; |
27 | } | 27 | } |
28 | 28 | ||
29 | static inline void arch_local_irq_disable(void) | 29 | static inline notrace void arch_local_irq_disable(void) |
30 | { | 30 | { |
31 | arch_local_irq_save(); | 31 | arch_local_irq_save(); |
32 | } | 32 | } |
33 | 33 | ||
34 | static inline bool arch_irqs_disabled_flags(unsigned long flags) | 34 | static inline notrace bool arch_irqs_disabled_flags(unsigned long flags) |
35 | { | 35 | { |
36 | return (flags & PSR_PIL) != 0; | 36 | return (flags & PSR_PIL) != 0; |
37 | } | 37 | } |
38 | 38 | ||
39 | static inline bool arch_irqs_disabled(void) | 39 | static inline notrace bool arch_irqs_disabled(void) |
40 | { | 40 | { |
41 | return arch_irqs_disabled_flags(arch_local_save_flags()); | 41 | return arch_irqs_disabled_flags(arch_local_save_flags()); |
42 | } | 42 | } |
diff --git a/arch/sparc/include/asm/irqflags_64.h b/arch/sparc/include/asm/irqflags_64.h index aab969c82c2b..23cd27f6beb4 100644 --- a/arch/sparc/include/asm/irqflags_64.h +++ b/arch/sparc/include/asm/irqflags_64.h | |||
@@ -14,7 +14,7 @@ | |||
14 | 14 | ||
15 | #ifndef __ASSEMBLY__ | 15 | #ifndef __ASSEMBLY__ |
16 | 16 | ||
17 | static inline unsigned long arch_local_save_flags(void) | 17 | static inline notrace unsigned long arch_local_save_flags(void) |
18 | { | 18 | { |
19 | unsigned long flags; | 19 | unsigned long flags; |
20 | 20 | ||
@@ -26,7 +26,7 @@ static inline unsigned long arch_local_save_flags(void) | |||
26 | return flags; | 26 | return flags; |
27 | } | 27 | } |
28 | 28 | ||
29 | static inline void arch_local_irq_restore(unsigned long flags) | 29 | static inline notrace void arch_local_irq_restore(unsigned long flags) |
30 | { | 30 | { |
31 | __asm__ __volatile__( | 31 | __asm__ __volatile__( |
32 | "wrpr %0, %%pil" | 32 | "wrpr %0, %%pil" |
@@ -36,7 +36,7 @@ static inline void arch_local_irq_restore(unsigned long flags) | |||
36 | ); | 36 | ); |
37 | } | 37 | } |
38 | 38 | ||
39 | static inline void arch_local_irq_disable(void) | 39 | static inline notrace void arch_local_irq_disable(void) |
40 | { | 40 | { |
41 | __asm__ __volatile__( | 41 | __asm__ __volatile__( |
42 | "wrpr %0, %%pil" | 42 | "wrpr %0, %%pil" |
@@ -46,7 +46,7 @@ static inline void arch_local_irq_disable(void) | |||
46 | ); | 46 | ); |
47 | } | 47 | } |
48 | 48 | ||
49 | static inline void arch_local_irq_enable(void) | 49 | static inline notrace void arch_local_irq_enable(void) |
50 | { | 50 | { |
51 | __asm__ __volatile__( | 51 | __asm__ __volatile__( |
52 | "wrpr 0, %%pil" | 52 | "wrpr 0, %%pil" |
@@ -56,17 +56,17 @@ static inline void arch_local_irq_enable(void) | |||
56 | ); | 56 | ); |
57 | } | 57 | } |
58 | 58 | ||
59 | static inline int arch_irqs_disabled_flags(unsigned long flags) | 59 | static inline notrace int arch_irqs_disabled_flags(unsigned long flags) |
60 | { | 60 | { |
61 | return (flags > 0); | 61 | return (flags > 0); |
62 | } | 62 | } |
63 | 63 | ||
64 | static inline int arch_irqs_disabled(void) | 64 | static inline notrace int arch_irqs_disabled(void) |
65 | { | 65 | { |
66 | return arch_irqs_disabled_flags(arch_local_save_flags()); | 66 | return arch_irqs_disabled_flags(arch_local_save_flags()); |
67 | } | 67 | } |
68 | 68 | ||
69 | static inline unsigned long arch_local_irq_save(void) | 69 | static inline notrace unsigned long arch_local_irq_save(void) |
70 | { | 70 | { |
71 | unsigned long flags, tmp; | 71 | unsigned long flags, tmp; |
72 | 72 | ||
diff --git a/arch/sparc/kernel/entry.S b/arch/sparc/kernel/entry.S index 9fe08a1ea6c6..f445e98463e6 100644 --- a/arch/sparc/kernel/entry.S +++ b/arch/sparc/kernel/entry.S | |||
@@ -293,7 +293,7 @@ maybe_smp4m_msg: | |||
293 | WRITE_PAUSE | 293 | WRITE_PAUSE |
294 | wr %l4, PSR_ET, %psr | 294 | wr %l4, PSR_ET, %psr |
295 | WRITE_PAUSE | 295 | WRITE_PAUSE |
296 | sll %o3, 28, %o2 ! shift for simpler checks below | 296 | srl %o3, 28, %o2 ! shift for simpler checks below |
297 | maybe_smp4m_msg_check_single: | 297 | maybe_smp4m_msg_check_single: |
298 | andcc %o2, 0x1, %g0 | 298 | andcc %o2, 0x1, %g0 |
299 | beq,a maybe_smp4m_msg_check_mask | 299 | beq,a maybe_smp4m_msg_check_mask |
diff --git a/arch/sparc/mm/leon_mm.c b/arch/sparc/mm/leon_mm.c index c0e01297e64e..e485a6804998 100644 --- a/arch/sparc/mm/leon_mm.c +++ b/arch/sparc/mm/leon_mm.c | |||
@@ -226,7 +226,7 @@ void leon3_getCacheRegs(struct leon3_cacheregs *regs) | |||
226 | * Leon2 and Leon3 differ in their way of telling cache information | 226 | * Leon2 and Leon3 differ in their way of telling cache information |
227 | * | 227 | * |
228 | */ | 228 | */ |
229 | int leon_flush_needed(void) | 229 | int __init leon_flush_needed(void) |
230 | { | 230 | { |
231 | int flush_needed = -1; | 231 | int flush_needed = -1; |
232 | unsigned int ssize, sets; | 232 | unsigned int ssize, sets; |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index da349723d411..37357a599dca 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -1170,7 +1170,7 @@ comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI" | |||
1170 | config AMD_NUMA | 1170 | config AMD_NUMA |
1171 | def_bool y | 1171 | def_bool y |
1172 | prompt "Old style AMD Opteron NUMA detection" | 1172 | prompt "Old style AMD Opteron NUMA detection" |
1173 | depends on NUMA && PCI | 1173 | depends on X86_64 && NUMA && PCI |
1174 | ---help--- | 1174 | ---help--- |
1175 | Enable AMD NUMA node topology detection. You should say Y here if | 1175 | Enable AMD NUMA node topology detection. You should say Y here if |
1176 | you have a multi processor AMD system. This uses an old method to | 1176 | you have a multi processor AMD system. This uses an old method to |
diff --git a/arch/x86/include/asm/mmzone_32.h b/arch/x86/include/asm/mmzone_32.h index 224e8c5eb307..ffa037f28d39 100644 --- a/arch/x86/include/asm/mmzone_32.h +++ b/arch/x86/include/asm/mmzone_32.h | |||
@@ -57,6 +57,8 @@ static inline int pfn_valid(int pfn) | |||
57 | return 0; | 57 | return 0; |
58 | } | 58 | } |
59 | 59 | ||
60 | #define early_pfn_valid(pfn) pfn_valid((pfn)) | ||
61 | |||
60 | #endif /* CONFIG_DISCONTIGMEM */ | 62 | #endif /* CONFIG_DISCONTIGMEM */ |
61 | 63 | ||
62 | #ifdef CONFIG_NEED_MULTIPLE_NODES | 64 | #ifdef CONFIG_NEED_MULTIPLE_NODES |
diff --git a/arch/x86/kernel/acpi/realmode/wakeup.S b/arch/x86/kernel/acpi/realmode/wakeup.S index ead21b663117..b4fd836e4053 100644 --- a/arch/x86/kernel/acpi/realmode/wakeup.S +++ b/arch/x86/kernel/acpi/realmode/wakeup.S | |||
@@ -28,6 +28,8 @@ pmode_cr3: .long 0 /* Saved %cr3 */ | |||
28 | pmode_cr4: .long 0 /* Saved %cr4 */ | 28 | pmode_cr4: .long 0 /* Saved %cr4 */ |
29 | pmode_efer: .quad 0 /* Saved EFER */ | 29 | pmode_efer: .quad 0 /* Saved EFER */ |
30 | pmode_gdt: .quad 0 | 30 | pmode_gdt: .quad 0 |
31 | pmode_misc_en: .quad 0 /* Saved MISC_ENABLE MSR */ | ||
32 | pmode_behavior: .long 0 /* Wakeup behavior flags */ | ||
31 | realmode_flags: .long 0 | 33 | realmode_flags: .long 0 |
32 | real_magic: .long 0 | 34 | real_magic: .long 0 |
33 | trampoline_segment: .word 0 | 35 | trampoline_segment: .word 0 |
@@ -91,6 +93,18 @@ wakeup_code: | |||
91 | /* Call the C code */ | 93 | /* Call the C code */ |
92 | calll main | 94 | calll main |
93 | 95 | ||
96 | /* Restore MISC_ENABLE before entering protected mode, in case | ||
97 | BIOS decided to clear XD_DISABLE during S3. */ | ||
98 | movl pmode_behavior, %eax | ||
99 | btl $WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE, %eax | ||
100 | jnc 1f | ||
101 | |||
102 | movl pmode_misc_en, %eax | ||
103 | movl pmode_misc_en + 4, %edx | ||
104 | movl $MSR_IA32_MISC_ENABLE, %ecx | ||
105 | wrmsr | ||
106 | 1: | ||
107 | |||
94 | /* Do any other stuff... */ | 108 | /* Do any other stuff... */ |
95 | 109 | ||
96 | #ifndef CONFIG_64BIT | 110 | #ifndef CONFIG_64BIT |
diff --git a/arch/x86/kernel/acpi/realmode/wakeup.h b/arch/x86/kernel/acpi/realmode/wakeup.h index e1828c07e79c..97a29e1430e3 100644 --- a/arch/x86/kernel/acpi/realmode/wakeup.h +++ b/arch/x86/kernel/acpi/realmode/wakeup.h | |||
@@ -21,6 +21,9 @@ struct wakeup_header { | |||
21 | u32 pmode_efer_low; /* Protected mode EFER */ | 21 | u32 pmode_efer_low; /* Protected mode EFER */ |
22 | u32 pmode_efer_high; | 22 | u32 pmode_efer_high; |
23 | u64 pmode_gdt; | 23 | u64 pmode_gdt; |
24 | u32 pmode_misc_en_low; /* Protected mode MISC_ENABLE */ | ||
25 | u32 pmode_misc_en_high; | ||
26 | u32 pmode_behavior; /* Wakeup routine behavior flags */ | ||
24 | u32 realmode_flags; | 27 | u32 realmode_flags; |
25 | u32 real_magic; | 28 | u32 real_magic; |
26 | u16 trampoline_segment; /* segment with trampoline code, 64-bit only */ | 29 | u16 trampoline_segment; /* segment with trampoline code, 64-bit only */ |
@@ -39,4 +42,7 @@ extern struct wakeup_header wakeup_header; | |||
39 | #define WAKEUP_HEADER_SIGNATURE 0x51ee1111 | 42 | #define WAKEUP_HEADER_SIGNATURE 0x51ee1111 |
40 | #define WAKEUP_END_SIGNATURE 0x65a22c82 | 43 | #define WAKEUP_END_SIGNATURE 0x65a22c82 |
41 | 44 | ||
45 | /* Wakeup behavior bits */ | ||
46 | #define WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE 0 | ||
47 | |||
42 | #endif /* ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H */ | 48 | #endif /* ARCH_X86_KERNEL_ACPI_RM_WAKEUP_H */ |
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 18a857ba7a25..103b6ab368d3 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c | |||
@@ -77,6 +77,12 @@ int acpi_suspend_lowlevel(void) | |||
77 | 77 | ||
78 | header->pmode_cr0 = read_cr0(); | 78 | header->pmode_cr0 = read_cr0(); |
79 | header->pmode_cr4 = read_cr4_safe(); | 79 | header->pmode_cr4 = read_cr4_safe(); |
80 | header->pmode_behavior = 0; | ||
81 | if (!rdmsr_safe(MSR_IA32_MISC_ENABLE, | ||
82 | &header->pmode_misc_en_low, | ||
83 | &header->pmode_misc_en_high)) | ||
84 | header->pmode_behavior |= | ||
85 | (1 << WAKEUP_BEHAVIOR_RESTORE_MISC_ENABLE); | ||
80 | header->realmode_flags = acpi_realmode_flags; | 86 | header->realmode_flags = acpi_realmode_flags; |
81 | header->real_magic = 0x12345678; | 87 | header->real_magic = 0x12345678; |
82 | 88 | ||
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 0c016f727695..14eed214b584 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
@@ -294,6 +294,14 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { | |||
294 | DMI_MATCH(DMI_BOARD_NAME, "VersaLogic Menlow board"), | 294 | DMI_MATCH(DMI_BOARD_NAME, "VersaLogic Menlow board"), |
295 | }, | 295 | }, |
296 | }, | 296 | }, |
297 | { /* Handle reboot issue on Acer Aspire one */ | ||
298 | .callback = set_bios_reboot, | ||
299 | .ident = "Acer Aspire One A110", | ||
300 | .matches = { | ||
301 | DMI_MATCH(DMI_SYS_VENDOR, "Acer"), | ||
302 | DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"), | ||
303 | }, | ||
304 | }, | ||
297 | { } | 305 | { } |
298 | }; | 306 | }; |
299 | 307 | ||
@@ -411,6 +419,14 @@ static struct dmi_system_id __initdata pci_reboot_dmi_table[] = { | |||
411 | DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"), | 419 | DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"), |
412 | }, | 420 | }, |
413 | }, | 421 | }, |
422 | { /* Handle problems with rebooting on the Latitude E6320. */ | ||
423 | .callback = set_pci_reboot, | ||
424 | .ident = "Dell Latitude E6320", | ||
425 | .matches = { | ||
426 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
427 | DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6320"), | ||
428 | }, | ||
429 | }, | ||
414 | { } | 430 | { } |
415 | }; | 431 | }; |
416 | 432 | ||
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index d865c4aeec55..bbaaa005bf0e 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/poison.h> | 28 | #include <linux/poison.h> |
29 | #include <linux/dma-mapping.h> | 29 | #include <linux/dma-mapping.h> |
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
31 | #include <linux/memory.h> | ||
31 | #include <linux/memory_hotplug.h> | 32 | #include <linux/memory_hotplug.h> |
32 | #include <linux/nmi.h> | 33 | #include <linux/nmi.h> |
33 | #include <linux/gfp.h> | 34 | #include <linux/gfp.h> |
@@ -895,8 +896,6 @@ const char *arch_vma_name(struct vm_area_struct *vma) | |||
895 | } | 896 | } |
896 | 897 | ||
897 | #ifdef CONFIG_X86_UV | 898 | #ifdef CONFIG_X86_UV |
898 | #define MIN_MEMORY_BLOCK_SIZE (1 << SECTION_SIZE_BITS) | ||
899 | |||
900 | unsigned long memory_block_size_bytes(void) | 899 | unsigned long memory_block_size_bytes(void) |
901 | { | 900 | { |
902 | if (is_uv_system()) { | 901 | if (is_uv_system()) { |
diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c index cf9750004a08..68894fdc034b 100644 --- a/arch/x86/oprofile/nmi_int.c +++ b/arch/x86/oprofile/nmi_int.c | |||
@@ -112,8 +112,10 @@ static void nmi_cpu_start(void *dummy) | |||
112 | static int nmi_start(void) | 112 | static int nmi_start(void) |
113 | { | 113 | { |
114 | get_online_cpus(); | 114 | get_online_cpus(); |
115 | on_each_cpu(nmi_cpu_start, NULL, 1); | ||
116 | ctr_running = 1; | 115 | ctr_running = 1; |
116 | /* make ctr_running visible to the nmi handler: */ | ||
117 | smp_mb(); | ||
118 | on_each_cpu(nmi_cpu_start, NULL, 1); | ||
117 | put_online_cpus(); | 119 | put_online_cpus(); |
118 | return 0; | 120 | return 0; |
119 | } | 121 | } |
@@ -504,15 +506,18 @@ static int nmi_setup(void) | |||
504 | 506 | ||
505 | nmi_enabled = 0; | 507 | nmi_enabled = 0; |
506 | ctr_running = 0; | 508 | ctr_running = 0; |
507 | barrier(); | 509 | /* make variables visible to the nmi handler: */ |
510 | smp_mb(); | ||
508 | err = register_die_notifier(&profile_exceptions_nb); | 511 | err = register_die_notifier(&profile_exceptions_nb); |
509 | if (err) | 512 | if (err) |
510 | goto fail; | 513 | goto fail; |
511 | 514 | ||
512 | get_online_cpus(); | 515 | get_online_cpus(); |
513 | register_cpu_notifier(&oprofile_cpu_nb); | 516 | register_cpu_notifier(&oprofile_cpu_nb); |
514 | on_each_cpu(nmi_cpu_setup, NULL, 1); | ||
515 | nmi_enabled = 1; | 517 | nmi_enabled = 1; |
518 | /* make nmi_enabled visible to the nmi handler: */ | ||
519 | smp_mb(); | ||
520 | on_each_cpu(nmi_cpu_setup, NULL, 1); | ||
516 | put_online_cpus(); | 521 | put_online_cpus(); |
517 | 522 | ||
518 | return 0; | 523 | return 0; |
@@ -531,7 +536,8 @@ static void nmi_shutdown(void) | |||
531 | nmi_enabled = 0; | 536 | nmi_enabled = 0; |
532 | ctr_running = 0; | 537 | ctr_running = 0; |
533 | put_online_cpus(); | 538 | put_online_cpus(); |
534 | barrier(); | 539 | /* make variables visible to the nmi handler: */ |
540 | smp_mb(); | ||
535 | unregister_die_notifier(&profile_exceptions_nb); | 541 | unregister_die_notifier(&profile_exceptions_nb); |
536 | msrs = &get_cpu_var(cpu_msrs); | 542 | msrs = &get_cpu_var(cpu_msrs); |
537 | model->shutdown(msrs); | 543 | model->shutdown(msrs); |
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c index fe008309ffec..f567965c0620 100644 --- a/arch/x86/pci/xen.c +++ b/arch/x86/pci/xen.c | |||
@@ -327,13 +327,12 @@ int __init pci_xen_hvm_init(void) | |||
327 | } | 327 | } |
328 | 328 | ||
329 | #ifdef CONFIG_XEN_DOM0 | 329 | #ifdef CONFIG_XEN_DOM0 |
330 | static int xen_register_pirq(u32 gsi, int triggering) | 330 | static int xen_register_pirq(u32 gsi, int gsi_override, int triggering) |
331 | { | 331 | { |
332 | int rc, pirq, irq = -1; | 332 | int rc, pirq, irq = -1; |
333 | struct physdev_map_pirq map_irq; | 333 | struct physdev_map_pirq map_irq; |
334 | int shareable = 0; | 334 | int shareable = 0; |
335 | char *name; | 335 | char *name; |
336 | bool gsi_override = false; | ||
337 | 336 | ||
338 | if (!xen_pv_domain()) | 337 | if (!xen_pv_domain()) |
339 | return -1; | 338 | return -1; |
@@ -345,31 +344,12 @@ static int xen_register_pirq(u32 gsi, int triggering) | |||
345 | shareable = 1; | 344 | shareable = 1; |
346 | name = "ioapic-level"; | 345 | name = "ioapic-level"; |
347 | } | 346 | } |
348 | |||
349 | pirq = xen_allocate_pirq_gsi(gsi); | 347 | pirq = xen_allocate_pirq_gsi(gsi); |
350 | if (pirq < 0) | 348 | if (pirq < 0) |
351 | goto out; | 349 | goto out; |
352 | 350 | ||
353 | /* Before we bind the GSI to a Linux IRQ, check whether | 351 | if (gsi_override >= 0) |
354 | * we need to override it with bus_irq (IRQ) value. Usually for | 352 | irq = xen_bind_pirq_gsi_to_irq(gsi_override, pirq, shareable, name); |
355 | * IRQs below IRQ_LEGACY_IRQ this holds IRQ == GSI, as so: | ||
356 | * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 low level) | ||
357 | * but there are oddballs where the IRQ != GSI: | ||
358 | * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 20 low level) | ||
359 | * which ends up being: gsi_to_irq[9] == 20 | ||
360 | * (which is what acpi_gsi_to_irq ends up calling when starting the | ||
361 | * the ACPI interpreter and keels over since IRQ 9 has not been | ||
362 | * setup as we had setup IRQ 20 for it). | ||
363 | */ | ||
364 | if (gsi == acpi_sci_override_gsi) { | ||
365 | /* Check whether the GSI != IRQ */ | ||
366 | acpi_gsi_to_irq(gsi, &irq); | ||
367 | if (irq != gsi) | ||
368 | /* Bugger, we MUST have that IRQ. */ | ||
369 | gsi_override = true; | ||
370 | } | ||
371 | if (gsi_override) | ||
372 | irq = xen_bind_pirq_gsi_to_irq(irq, pirq, shareable, name); | ||
373 | else | 353 | else |
374 | irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name); | 354 | irq = xen_bind_pirq_gsi_to_irq(gsi, pirq, shareable, name); |
375 | if (irq < 0) | 355 | if (irq < 0) |
@@ -392,7 +372,7 @@ out: | |||
392 | return irq; | 372 | return irq; |
393 | } | 373 | } |
394 | 374 | ||
395 | static int xen_register_gsi(u32 gsi, int triggering, int polarity) | 375 | static int xen_register_gsi(u32 gsi, int gsi_override, int triggering, int polarity) |
396 | { | 376 | { |
397 | int rc, irq; | 377 | int rc, irq; |
398 | struct physdev_setup_gsi setup_gsi; | 378 | struct physdev_setup_gsi setup_gsi; |
@@ -403,7 +383,7 @@ static int xen_register_gsi(u32 gsi, int triggering, int polarity) | |||
403 | printk(KERN_DEBUG "xen: registering gsi %u triggering %d polarity %d\n", | 383 | printk(KERN_DEBUG "xen: registering gsi %u triggering %d polarity %d\n", |
404 | gsi, triggering, polarity); | 384 | gsi, triggering, polarity); |
405 | 385 | ||
406 | irq = xen_register_pirq(gsi, triggering); | 386 | irq = xen_register_pirq(gsi, gsi_override, triggering); |
407 | 387 | ||
408 | setup_gsi.gsi = gsi; | 388 | setup_gsi.gsi = gsi; |
409 | setup_gsi.triggering = (triggering == ACPI_EDGE_SENSITIVE ? 0 : 1); | 389 | setup_gsi.triggering = (triggering == ACPI_EDGE_SENSITIVE ? 0 : 1); |
@@ -425,6 +405,8 @@ static __init void xen_setup_acpi_sci(void) | |||
425 | int rc; | 405 | int rc; |
426 | int trigger, polarity; | 406 | int trigger, polarity; |
427 | int gsi = acpi_sci_override_gsi; | 407 | int gsi = acpi_sci_override_gsi; |
408 | int irq = -1; | ||
409 | int gsi_override = -1; | ||
428 | 410 | ||
429 | if (!gsi) | 411 | if (!gsi) |
430 | return; | 412 | return; |
@@ -441,7 +423,25 @@ static __init void xen_setup_acpi_sci(void) | |||
441 | printk(KERN_INFO "xen: sci override: global_irq=%d trigger=%d " | 423 | printk(KERN_INFO "xen: sci override: global_irq=%d trigger=%d " |
442 | "polarity=%d\n", gsi, trigger, polarity); | 424 | "polarity=%d\n", gsi, trigger, polarity); |
443 | 425 | ||
444 | gsi = xen_register_gsi(gsi, trigger, polarity); | 426 | /* Before we bind the GSI to a Linux IRQ, check whether |
427 | * we need to override it with bus_irq (IRQ) value. Usually for | ||
428 | * IRQs below IRQ_LEGACY_IRQ this holds IRQ == GSI, as so: | ||
429 | * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 low level) | ||
430 | * but there are oddballs where the IRQ != GSI: | ||
431 | * ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 20 low level) | ||
432 | * which ends up being: gsi_to_irq[9] == 20 | ||
433 | * (which is what acpi_gsi_to_irq ends up calling when starting the | ||
434 | * the ACPI interpreter and keels over since IRQ 9 has not been | ||
435 | * setup as we had setup IRQ 20 for it). | ||
436 | */ | ||
437 | /* Check whether the GSI != IRQ */ | ||
438 | if (acpi_gsi_to_irq(gsi, &irq) == 0) { | ||
439 | if (irq >= 0 && irq != gsi) | ||
440 | /* Bugger, we MUST have that IRQ. */ | ||
441 | gsi_override = irq; | ||
442 | } | ||
443 | |||
444 | gsi = xen_register_gsi(gsi, gsi_override, trigger, polarity); | ||
445 | printk(KERN_INFO "xen: acpi sci %d\n", gsi); | 445 | printk(KERN_INFO "xen: acpi sci %d\n", gsi); |
446 | 446 | ||
447 | return; | 447 | return; |
@@ -450,7 +450,7 @@ static __init void xen_setup_acpi_sci(void) | |||
450 | static int acpi_register_gsi_xen(struct device *dev, u32 gsi, | 450 | static int acpi_register_gsi_xen(struct device *dev, u32 gsi, |
451 | int trigger, int polarity) | 451 | int trigger, int polarity) |
452 | { | 452 | { |
453 | return xen_register_gsi(gsi, trigger, polarity); | 453 | return xen_register_gsi(gsi, -1 /* no GSI override */, trigger, polarity); |
454 | } | 454 | } |
455 | 455 | ||
456 | static int __init pci_xen_initial_domain(void) | 456 | static int __init pci_xen_initial_domain(void) |
@@ -489,7 +489,7 @@ void __init xen_setup_pirqs(void) | |||
489 | if (acpi_get_override_irq(irq, &trigger, &polarity) == -1) | 489 | if (acpi_get_override_irq(irq, &trigger, &polarity) == -1) |
490 | continue; | 490 | continue; |
491 | 491 | ||
492 | xen_register_pirq(irq, | 492 | xen_register_pirq(irq, -1 /* no GSI override */, |
493 | trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE); | 493 | trigger ? ACPI_LEVEL_SENSITIVE : ACPI_EDGE_SENSITIVE); |
494 | } | 494 | } |
495 | } | 495 | } |
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 474356b98ede..899e393d8e73 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -504,9 +504,6 @@ void __init efi_init(void) | |||
504 | x86_platform.set_wallclock = efi_set_rtc_mmss; | 504 | x86_platform.set_wallclock = efi_set_rtc_mmss; |
505 | #endif | 505 | #endif |
506 | 506 | ||
507 | /* Setup for EFI runtime service */ | ||
508 | reboot_type = BOOT_EFI; | ||
509 | |||
510 | #if EFI_DEBUG | 507 | #if EFI_DEBUG |
511 | print_efi_memmap(); | 508 | print_efi_memmap(); |
512 | #endif | 509 | #endif |
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index f3799432676d..ae21919f15e1 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -2773,11 +2773,14 @@ static void __cfq_exit_single_io_context(struct cfq_data *cfqd, | |||
2773 | smp_wmb(); | 2773 | smp_wmb(); |
2774 | cic->key = cfqd_dead_key(cfqd); | 2774 | cic->key = cfqd_dead_key(cfqd); |
2775 | 2775 | ||
2776 | rcu_read_lock(); | ||
2776 | if (rcu_dereference(ioc->ioc_data) == cic) { | 2777 | if (rcu_dereference(ioc->ioc_data) == cic) { |
2778 | rcu_read_unlock(); | ||
2777 | spin_lock(&ioc->lock); | 2779 | spin_lock(&ioc->lock); |
2778 | rcu_assign_pointer(ioc->ioc_data, NULL); | 2780 | rcu_assign_pointer(ioc->ioc_data, NULL); |
2779 | spin_unlock(&ioc->lock); | 2781 | spin_unlock(&ioc->lock); |
2780 | } | 2782 | } else |
2783 | rcu_read_unlock(); | ||
2781 | 2784 | ||
2782 | if (cic->cfqq[BLK_RW_ASYNC]) { | 2785 | if (cic->cfqq[BLK_RW_ASYNC]) { |
2783 | cfq_exit_cfqq(cfqd, cic->cfqq[BLK_RW_ASYNC]); | 2786 | cfq_exit_cfqq(cfqd, cic->cfqq[BLK_RW_ASYNC]); |
@@ -3084,7 +3087,8 @@ cfq_drop_dead_cic(struct cfq_data *cfqd, struct io_context *ioc, | |||
3084 | 3087 | ||
3085 | spin_lock_irqsave(&ioc->lock, flags); | 3088 | spin_lock_irqsave(&ioc->lock, flags); |
3086 | 3089 | ||
3087 | BUG_ON(ioc->ioc_data == cic); | 3090 | BUG_ON(rcu_dereference_check(ioc->ioc_data, |
3091 | lockdep_is_held(&ioc->lock)) == cic); | ||
3088 | 3092 | ||
3089 | radix_tree_delete(&ioc->radix_root, cfqd->cic_index); | 3093 | radix_tree_delete(&ioc->radix_root, cfqd->cic_index); |
3090 | hlist_del_rcu(&cic->cic_list); | 3094 | hlist_del_rcu(&cic->cic_list); |
diff --git a/drivers/acpi/apei/hest.c b/drivers/acpi/apei/hest.c index abda3786a5d7..181bc2f7bb74 100644 --- a/drivers/acpi/apei/hest.c +++ b/drivers/acpi/apei/hest.c | |||
@@ -139,13 +139,23 @@ 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; |
142 | int rc; | 142 | int rc, i; |
143 | 143 | ||
144 | if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) | 144 | if (hest_hdr->type != ACPI_HEST_TYPE_GENERIC_ERROR) |
145 | return 0; | 145 | return 0; |
146 | 146 | ||
147 | if (!((struct acpi_hest_generic *)hest_hdr)->enabled) | 147 | if (!((struct acpi_hest_generic *)hest_hdr)->enabled) |
148 | return 0; | 148 | return 0; |
149 | for (i = 0; i < ghes_arr->count; i++) { | ||
150 | struct acpi_hest_header *hdr; | ||
151 | ghes_dev = ghes_arr->ghes_devs[i]; | ||
152 | hdr = *(struct acpi_hest_header **)ghes_dev->dev.platform_data; | ||
153 | if (hdr->source_id == hest_hdr->source_id) { | ||
154 | pr_warning(FW_WARN HEST_PFX "Duplicated hardware error source ID: %d.\n", | ||
155 | hdr->source_id); | ||
156 | return -EIO; | ||
157 | } | ||
158 | } | ||
149 | ghes_dev = platform_device_alloc("GHES", hest_hdr->source_id); | 159 | ghes_dev = platform_device_alloc("GHES", hest_hdr->source_id); |
150 | if (!ghes_dev) | 160 | if (!ghes_dev) |
151 | return -ENOMEM; | 161 | return -ENOMEM; |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 52ca9649d769..372f9b70f7f4 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -1333,23 +1333,6 @@ int acpi_resources_are_enforced(void) | |||
1333 | EXPORT_SYMBOL(acpi_resources_are_enforced); | 1333 | EXPORT_SYMBOL(acpi_resources_are_enforced); |
1334 | 1334 | ||
1335 | /* | 1335 | /* |
1336 | * Create and initialize a spinlock. | ||
1337 | */ | ||
1338 | acpi_status | ||
1339 | acpi_os_create_lock(acpi_spinlock *out_handle) | ||
1340 | { | ||
1341 | spinlock_t *lock; | ||
1342 | |||
1343 | lock = ACPI_ALLOCATE(sizeof(spinlock_t)); | ||
1344 | if (!lock) | ||
1345 | return AE_NO_MEMORY; | ||
1346 | spin_lock_init(lock); | ||
1347 | *out_handle = lock; | ||
1348 | |||
1349 | return AE_OK; | ||
1350 | } | ||
1351 | |||
1352 | /* | ||
1353 | * Deallocate the memory for a spinlock. | 1336 | * Deallocate the memory for a spinlock. |
1354 | */ | 1337 | */ |
1355 | void acpi_os_delete_lock(acpi_spinlock handle) | 1338 | void acpi_os_delete_lock(acpi_spinlock handle) |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index 9f9b2359f718..45d7c8fc73bd 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -30,7 +30,6 @@ | |||
30 | static DEFINE_MUTEX(mem_sysfs_mutex); | 30 | static DEFINE_MUTEX(mem_sysfs_mutex); |
31 | 31 | ||
32 | #define MEMORY_CLASS_NAME "memory" | 32 | #define MEMORY_CLASS_NAME "memory" |
33 | #define MIN_MEMORY_BLOCK_SIZE (1 << SECTION_SIZE_BITS) | ||
34 | 33 | ||
35 | static int sections_per_block; | 34 | static int sections_per_block; |
36 | 35 | ||
diff --git a/drivers/base/syscore.c b/drivers/base/syscore.c index c126db3cb7d1..e8d11b6630ee 100644 --- a/drivers/base/syscore.c +++ b/drivers/base/syscore.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/syscore_ops.h> | 9 | #include <linux/syscore_ops.h> |
10 | #include <linux/mutex.h> | 10 | #include <linux/mutex.h> |
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/interrupt.h> | ||
12 | 13 | ||
13 | static LIST_HEAD(syscore_ops_list); | 14 | static LIST_HEAD(syscore_ops_list); |
14 | static DEFINE_MUTEX(syscore_ops_lock); | 15 | static DEFINE_MUTEX(syscore_ops_lock); |
@@ -48,6 +49,13 @@ int syscore_suspend(void) | |||
48 | struct syscore_ops *ops; | 49 | struct syscore_ops *ops; |
49 | int ret = 0; | 50 | int ret = 0; |
50 | 51 | ||
52 | pr_debug("Checking wakeup interrupts\n"); | ||
53 | |||
54 | /* Return error code if there are any wakeup interrupts pending. */ | ||
55 | ret = check_wakeup_irqs(); | ||
56 | if (ret) | ||
57 | return ret; | ||
58 | |||
51 | WARN_ONCE(!irqs_disabled(), | 59 | WARN_ONCE(!irqs_disabled(), |
52 | "Interrupts enabled before system core suspend.\n"); | 60 | "Interrupts enabled before system core suspend.\n"); |
53 | 61 | ||
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c index 09ef9a878ef0..cf0e63dd97da 100644 --- a/drivers/block/drbd/drbd_actlog.c +++ b/drivers/block/drbd/drbd_actlog.c | |||
@@ -79,7 +79,7 @@ static int _drbd_md_sync_page_io(struct drbd_conf *mdev, | |||
79 | md_io.error = 0; | 79 | md_io.error = 0; |
80 | 80 | ||
81 | if ((rw & WRITE) && !test_bit(MD_NO_FUA, &mdev->flags)) | 81 | if ((rw & WRITE) && !test_bit(MD_NO_FUA, &mdev->flags)) |
82 | rw |= REQ_FUA; | 82 | rw |= REQ_FUA | REQ_FLUSH; |
83 | rw |= REQ_SYNC; | 83 | rw |= REQ_SYNC; |
84 | 84 | ||
85 | bio = bio_alloc(GFP_NOIO, 1); | 85 | bio = bio_alloc(GFP_NOIO, 1); |
diff --git a/drivers/block/drbd/drbd_bitmap.c b/drivers/block/drbd/drbd_bitmap.c index f440a02dfdb1..7b976296b564 100644 --- a/drivers/block/drbd/drbd_bitmap.c +++ b/drivers/block/drbd/drbd_bitmap.c | |||
@@ -112,9 +112,6 @@ struct drbd_bitmap { | |||
112 | struct task_struct *bm_task; | 112 | struct task_struct *bm_task; |
113 | }; | 113 | }; |
114 | 114 | ||
115 | static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, | ||
116 | unsigned long e, int val, const enum km_type km); | ||
117 | |||
118 | #define bm_print_lock_info(m) __bm_print_lock_info(m, __func__) | 115 | #define bm_print_lock_info(m) __bm_print_lock_info(m, __func__) |
119 | static void __bm_print_lock_info(struct drbd_conf *mdev, const char *func) | 116 | static void __bm_print_lock_info(struct drbd_conf *mdev, const char *func) |
120 | { | 117 | { |
@@ -994,6 +991,9 @@ static void bm_page_io_async(struct bm_aio_ctx *ctx, int page_nr, int rw) __must | |||
994 | bio_endio(bio, -EIO); | 991 | bio_endio(bio, -EIO); |
995 | } else { | 992 | } else { |
996 | submit_bio(rw, bio); | 993 | submit_bio(rw, bio); |
994 | /* this should not count as user activity and cause the | ||
995 | * resync to throttle -- see drbd_rs_should_slow_down(). */ | ||
996 | atomic_add(len >> 9, &mdev->rs_sect_ev); | ||
997 | } | 997 | } |
998 | } | 998 | } |
999 | 999 | ||
@@ -1256,7 +1256,7 @@ unsigned long _drbd_bm_find_next_zero(struct drbd_conf *mdev, unsigned long bm_f | |||
1256 | * expected to be called for only a few bits (e - s about BITS_PER_LONG). | 1256 | * expected to be called for only a few bits (e - s about BITS_PER_LONG). |
1257 | * Must hold bitmap lock already. */ | 1257 | * Must hold bitmap lock already. */ |
1258 | static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, | 1258 | static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, |
1259 | unsigned long e, int val, const enum km_type km) | 1259 | unsigned long e, int val) |
1260 | { | 1260 | { |
1261 | struct drbd_bitmap *b = mdev->bitmap; | 1261 | struct drbd_bitmap *b = mdev->bitmap; |
1262 | unsigned long *p_addr = NULL; | 1262 | unsigned long *p_addr = NULL; |
@@ -1274,14 +1274,14 @@ static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, | |||
1274 | unsigned int page_nr = bm_bit_to_page_idx(b, bitnr); | 1274 | unsigned int page_nr = bm_bit_to_page_idx(b, bitnr); |
1275 | if (page_nr != last_page_nr) { | 1275 | if (page_nr != last_page_nr) { |
1276 | if (p_addr) | 1276 | if (p_addr) |
1277 | __bm_unmap(p_addr, km); | 1277 | __bm_unmap(p_addr, KM_IRQ1); |
1278 | if (c < 0) | 1278 | if (c < 0) |
1279 | bm_set_page_lazy_writeout(b->bm_pages[last_page_nr]); | 1279 | bm_set_page_lazy_writeout(b->bm_pages[last_page_nr]); |
1280 | else if (c > 0) | 1280 | else if (c > 0) |
1281 | bm_set_page_need_writeout(b->bm_pages[last_page_nr]); | 1281 | bm_set_page_need_writeout(b->bm_pages[last_page_nr]); |
1282 | changed_total += c; | 1282 | changed_total += c; |
1283 | c = 0; | 1283 | c = 0; |
1284 | p_addr = __bm_map_pidx(b, page_nr, km); | 1284 | p_addr = __bm_map_pidx(b, page_nr, KM_IRQ1); |
1285 | last_page_nr = page_nr; | 1285 | last_page_nr = page_nr; |
1286 | } | 1286 | } |
1287 | if (val) | 1287 | if (val) |
@@ -1290,7 +1290,7 @@ static int __bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, | |||
1290 | c -= (0 != __test_and_clear_bit_le(bitnr & BITS_PER_PAGE_MASK, p_addr)); | 1290 | c -= (0 != __test_and_clear_bit_le(bitnr & BITS_PER_PAGE_MASK, p_addr)); |
1291 | } | 1291 | } |
1292 | if (p_addr) | 1292 | if (p_addr) |
1293 | __bm_unmap(p_addr, km); | 1293 | __bm_unmap(p_addr, KM_IRQ1); |
1294 | if (c < 0) | 1294 | if (c < 0) |
1295 | bm_set_page_lazy_writeout(b->bm_pages[last_page_nr]); | 1295 | bm_set_page_lazy_writeout(b->bm_pages[last_page_nr]); |
1296 | else if (c > 0) | 1296 | else if (c > 0) |
@@ -1318,7 +1318,7 @@ static int bm_change_bits_to(struct drbd_conf *mdev, const unsigned long s, | |||
1318 | if ((val ? BM_DONT_SET : BM_DONT_CLEAR) & b->bm_flags) | 1318 | if ((val ? BM_DONT_SET : BM_DONT_CLEAR) & b->bm_flags) |
1319 | bm_print_lock_info(mdev); | 1319 | bm_print_lock_info(mdev); |
1320 | 1320 | ||
1321 | c = __bm_change_bits_to(mdev, s, e, val, KM_IRQ1); | 1321 | c = __bm_change_bits_to(mdev, s, e, val); |
1322 | 1322 | ||
1323 | spin_unlock_irqrestore(&b->bm_lock, flags); | 1323 | spin_unlock_irqrestore(&b->bm_lock, flags); |
1324 | return c; | 1324 | return c; |
@@ -1343,16 +1343,17 @@ static inline void bm_set_full_words_within_one_page(struct drbd_bitmap *b, | |||
1343 | { | 1343 | { |
1344 | int i; | 1344 | int i; |
1345 | int bits; | 1345 | int bits; |
1346 | unsigned long *paddr = kmap_atomic(b->bm_pages[page_nr], KM_USER0); | 1346 | unsigned long *paddr = kmap_atomic(b->bm_pages[page_nr], KM_IRQ1); |
1347 | for (i = first_word; i < last_word; i++) { | 1347 | for (i = first_word; i < last_word; i++) { |
1348 | bits = hweight_long(paddr[i]); | 1348 | bits = hweight_long(paddr[i]); |
1349 | paddr[i] = ~0UL; | 1349 | paddr[i] = ~0UL; |
1350 | b->bm_set += BITS_PER_LONG - bits; | 1350 | b->bm_set += BITS_PER_LONG - bits; |
1351 | } | 1351 | } |
1352 | kunmap_atomic(paddr, KM_USER0); | 1352 | kunmap_atomic(paddr, KM_IRQ1); |
1353 | } | 1353 | } |
1354 | 1354 | ||
1355 | /* Same thing as drbd_bm_set_bits, but without taking the spin_lock_irqsave. | 1355 | /* Same thing as drbd_bm_set_bits, |
1356 | * but more efficient for a large bit range. | ||
1356 | * You must first drbd_bm_lock(). | 1357 | * You must first drbd_bm_lock(). |
1357 | * Can be called to set the whole bitmap in one go. | 1358 | * Can be called to set the whole bitmap in one go. |
1358 | * Sets bits from s to e _inclusive_. */ | 1359 | * Sets bits from s to e _inclusive_. */ |
@@ -1366,6 +1367,7 @@ void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsi | |||
1366 | * Do not use memset, because we must account for changes, | 1367 | * Do not use memset, because we must account for changes, |
1367 | * so we need to loop over the words with hweight() anyways. | 1368 | * so we need to loop over the words with hweight() anyways. |
1368 | */ | 1369 | */ |
1370 | struct drbd_bitmap *b = mdev->bitmap; | ||
1369 | unsigned long sl = ALIGN(s,BITS_PER_LONG); | 1371 | unsigned long sl = ALIGN(s,BITS_PER_LONG); |
1370 | unsigned long el = (e+1) & ~((unsigned long)BITS_PER_LONG-1); | 1372 | unsigned long el = (e+1) & ~((unsigned long)BITS_PER_LONG-1); |
1371 | int first_page; | 1373 | int first_page; |
@@ -1376,15 +1378,19 @@ void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsi | |||
1376 | 1378 | ||
1377 | if (e - s <= 3*BITS_PER_LONG) { | 1379 | if (e - s <= 3*BITS_PER_LONG) { |
1378 | /* don't bother; el and sl may even be wrong. */ | 1380 | /* don't bother; el and sl may even be wrong. */ |
1379 | __bm_change_bits_to(mdev, s, e, 1, KM_USER0); | 1381 | spin_lock_irq(&b->bm_lock); |
1382 | __bm_change_bits_to(mdev, s, e, 1); | ||
1383 | spin_unlock_irq(&b->bm_lock); | ||
1380 | return; | 1384 | return; |
1381 | } | 1385 | } |
1382 | 1386 | ||
1383 | /* difference is large enough that we can trust sl and el */ | 1387 | /* difference is large enough that we can trust sl and el */ |
1384 | 1388 | ||
1389 | spin_lock_irq(&b->bm_lock); | ||
1390 | |||
1385 | /* bits filling the current long */ | 1391 | /* bits filling the current long */ |
1386 | if (sl) | 1392 | if (sl) |
1387 | __bm_change_bits_to(mdev, s, sl-1, 1, KM_USER0); | 1393 | __bm_change_bits_to(mdev, s, sl-1, 1); |
1388 | 1394 | ||
1389 | first_page = sl >> (3 + PAGE_SHIFT); | 1395 | first_page = sl >> (3 + PAGE_SHIFT); |
1390 | last_page = el >> (3 + PAGE_SHIFT); | 1396 | last_page = el >> (3 + PAGE_SHIFT); |
@@ -1397,8 +1403,10 @@ void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsi | |||
1397 | /* first and full pages, unless first page == last page */ | 1403 | /* first and full pages, unless first page == last page */ |
1398 | for (page_nr = first_page; page_nr < last_page; page_nr++) { | 1404 | for (page_nr = first_page; page_nr < last_page; page_nr++) { |
1399 | bm_set_full_words_within_one_page(mdev->bitmap, page_nr, first_word, last_word); | 1405 | bm_set_full_words_within_one_page(mdev->bitmap, page_nr, first_word, last_word); |
1406 | spin_unlock_irq(&b->bm_lock); | ||
1400 | cond_resched(); | 1407 | cond_resched(); |
1401 | first_word = 0; | 1408 | first_word = 0; |
1409 | spin_lock_irq(&b->bm_lock); | ||
1402 | } | 1410 | } |
1403 | 1411 | ||
1404 | /* last page (respectively only page, for first page == last page) */ | 1412 | /* last page (respectively only page, for first page == last page) */ |
@@ -1411,7 +1419,8 @@ void _drbd_bm_set_bits(struct drbd_conf *mdev, const unsigned long s, const unsi | |||
1411 | * it would trigger an assert in __bm_change_bits_to() | 1419 | * it would trigger an assert in __bm_change_bits_to() |
1412 | */ | 1420 | */ |
1413 | if (el <= e) | 1421 | if (el <= e) |
1414 | __bm_change_bits_to(mdev, el, e, 1, KM_USER0); | 1422 | __bm_change_bits_to(mdev, el, e, 1); |
1423 | spin_unlock_irq(&b->bm_lock); | ||
1415 | } | 1424 | } |
1416 | 1425 | ||
1417 | /* returns bit state | 1426 | /* returns bit state |
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c index 25d32c5aa50a..43beaca53179 100644 --- a/drivers/block/drbd/drbd_receiver.c +++ b/drivers/block/drbd/drbd_receiver.c | |||
@@ -4602,6 +4602,11 @@ int drbd_asender(struct drbd_thread *thi) | |||
4602 | dev_err(DEV, "meta connection shut down by peer.\n"); | 4602 | dev_err(DEV, "meta connection shut down by peer.\n"); |
4603 | goto reconnect; | 4603 | goto reconnect; |
4604 | } else if (rv == -EAGAIN) { | 4604 | } else if (rv == -EAGAIN) { |
4605 | /* If the data socket received something meanwhile, | ||
4606 | * that is good enough: peer is still alive. */ | ||
4607 | if (time_after(mdev->last_received, | ||
4608 | jiffies - mdev->meta.socket->sk->sk_rcvtimeo)) | ||
4609 | continue; | ||
4605 | if (ping_timeout_active) { | 4610 | if (ping_timeout_active) { |
4606 | dev_err(DEV, "PingAck did not arrive in time.\n"); | 4611 | dev_err(DEV, "PingAck did not arrive in time.\n"); |
4607 | goto reconnect; | 4612 | goto reconnect; |
@@ -4637,6 +4642,7 @@ int drbd_asender(struct drbd_thread *thi) | |||
4637 | goto reconnect; | 4642 | goto reconnect; |
4638 | } | 4643 | } |
4639 | if (received == expect) { | 4644 | if (received == expect) { |
4645 | mdev->last_received = jiffies; | ||
4640 | D_ASSERT(cmd != NULL); | 4646 | D_ASSERT(cmd != NULL); |
4641 | if (!cmd->process(mdev, h)) | 4647 | if (!cmd->process(mdev, h)) |
4642 | goto reconnect; | 4648 | goto reconnect; |
diff --git a/drivers/block/drbd/drbd_worker.c b/drivers/block/drbd/drbd_worker.c index 4d76b06b6b20..4d3e6f6213ba 100644 --- a/drivers/block/drbd/drbd_worker.c +++ b/drivers/block/drbd/drbd_worker.c | |||
@@ -536,12 +536,7 @@ static int w_make_resync_request(struct drbd_conf *mdev, | |||
536 | return 1; | 536 | return 1; |
537 | } | 537 | } |
538 | 538 | ||
539 | /* starting with drbd 8.3.8, we can handle multi-bio EEs, | 539 | max_bio_size = queue_max_hw_sectors(mdev->rq_queue) << 9; |
540 | * if it should be necessary */ | ||
541 | max_bio_size = | ||
542 | mdev->agreed_pro_version < 94 ? queue_max_hw_sectors(mdev->rq_queue) << 9 : | ||
543 | mdev->agreed_pro_version < 95 ? DRBD_MAX_SIZE_H80_PACKET : DRBD_MAX_BIO_SIZE; | ||
544 | |||
545 | number = drbd_rs_number_requests(mdev); | 540 | number = drbd_rs_number_requests(mdev); |
546 | if (number == 0) | 541 | if (number == 0) |
547 | goto requeue; | 542 | goto requeue; |
diff --git a/drivers/char/agp/intel-agp.h b/drivers/char/agp/intel-agp.h index 999803ce10dc..5da67f165afa 100644 --- a/drivers/char/agp/intel-agp.h +++ b/drivers/char/agp/intel-agp.h | |||
@@ -90,9 +90,10 @@ | |||
90 | #define G4x_GMCH_SIZE_MASK (0xf << 8) | 90 | #define G4x_GMCH_SIZE_MASK (0xf << 8) |
91 | #define G4x_GMCH_SIZE_1M (0x1 << 8) | 91 | #define G4x_GMCH_SIZE_1M (0x1 << 8) |
92 | #define G4x_GMCH_SIZE_2M (0x3 << 8) | 92 | #define G4x_GMCH_SIZE_2M (0x3 << 8) |
93 | #define G4x_GMCH_SIZE_VT_1M (0x9 << 8) | 93 | #define G4x_GMCH_SIZE_VT_EN (0x8 << 8) |
94 | #define G4x_GMCH_SIZE_VT_1_5M (0xa << 8) | 94 | #define G4x_GMCH_SIZE_VT_1M (G4x_GMCH_SIZE_1M | G4x_GMCH_SIZE_VT_EN) |
95 | #define G4x_GMCH_SIZE_VT_2M (0xc << 8) | 95 | #define G4x_GMCH_SIZE_VT_1_5M ((0x2 << 8) | G4x_GMCH_SIZE_VT_EN) |
96 | #define G4x_GMCH_SIZE_VT_2M (G4x_GMCH_SIZE_2M | G4x_GMCH_SIZE_VT_EN) | ||
96 | 97 | ||
97 | #define GFX_FLSH_CNTL 0x2170 /* 915+ */ | 98 | #define GFX_FLSH_CNTL 0x2170 /* 915+ */ |
98 | 99 | ||
diff --git a/drivers/cpufreq/acpi-cpufreq.c b/drivers/cpufreq/acpi-cpufreq.c index 4e04e1274388..596d5dd32f41 100644 --- a/drivers/cpufreq/acpi-cpufreq.c +++ b/drivers/cpufreq/acpi-cpufreq.c | |||
@@ -759,7 +759,7 @@ static void __exit acpi_cpufreq_exit(void) | |||
759 | 759 | ||
760 | cpufreq_unregister_driver(&acpi_cpufreq_driver); | 760 | cpufreq_unregister_driver(&acpi_cpufreq_driver); |
761 | 761 | ||
762 | free_percpu(acpi_perf_data); | 762 | free_acpi_perf_data(); |
763 | } | 763 | } |
764 | 764 | ||
765 | module_param(acpi_pstate_strict, uint, 0644); | 765 | module_param(acpi_pstate_strict, uint, 0644); |
diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 438e6c831170..ebb897329c1e 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c | |||
@@ -264,6 +264,7 @@ static char ohci_driver_name[] = KBUILD_MODNAME; | |||
264 | #define PCI_DEVICE_ID_AGERE_FW643 0x5901 | 264 | #define PCI_DEVICE_ID_AGERE_FW643 0x5901 |
265 | #define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380 | 265 | #define PCI_DEVICE_ID_JMICRON_JMB38X_FW 0x2380 |
266 | #define PCI_DEVICE_ID_TI_TSB12LV22 0x8009 | 266 | #define PCI_DEVICE_ID_TI_TSB12LV22 0x8009 |
267 | #define PCI_VENDOR_ID_PINNACLE_SYSTEMS 0x11bd | ||
267 | 268 | ||
268 | #define QUIRK_CYCLE_TIMER 1 | 269 | #define QUIRK_CYCLE_TIMER 1 |
269 | #define QUIRK_RESET_PACKET 2 | 270 | #define QUIRK_RESET_PACKET 2 |
@@ -3190,6 +3191,11 @@ static int __devinit pci_probe(struct pci_dev *dev, | |||
3190 | int i, err; | 3191 | int i, err; |
3191 | size_t size; | 3192 | size_t size; |
3192 | 3193 | ||
3194 | if (dev->vendor == PCI_VENDOR_ID_PINNACLE_SYSTEMS) { | ||
3195 | dev_err(&dev->dev, "Pinnacle MovieBoard is not yet supported\n"); | ||
3196 | return -ENOSYS; | ||
3197 | } | ||
3198 | |||
3193 | ohci = kzalloc(sizeof(*ohci), GFP_KERNEL); | 3199 | ohci = kzalloc(sizeof(*ohci), GFP_KERNEL); |
3194 | if (ohci == NULL) { | 3200 | if (ohci == NULL) { |
3195 | err = -ENOMEM; | 3201 | err = -ENOMEM; |
diff --git a/drivers/gpio/langwell_gpio.c b/drivers/gpio/langwell_gpio.c index bd6571e0097a..644ba1255d3c 100644 --- a/drivers/gpio/langwell_gpio.c +++ b/drivers/gpio/langwell_gpio.c | |||
@@ -223,7 +223,7 @@ static void lnw_irq_handler(unsigned irq, struct irq_desc *desc) | |||
223 | gedr = gpio_reg(&lnw->chip, base, GEDR); | 223 | gedr = gpio_reg(&lnw->chip, base, GEDR); |
224 | pending = readl(gedr); | 224 | pending = readl(gedr); |
225 | while (pending) { | 225 | while (pending) { |
226 | gpio = __ffs(pending) - 1; | 226 | gpio = __ffs(pending); |
227 | mask = BIT(gpio); | 227 | mask = BIT(gpio); |
228 | pending &= ~mask; | 228 | pending &= ~mask; |
229 | /* Clear before handling so we can't lose an edge */ | 229 | /* Clear before handling so we can't lose an edge */ |
diff --git a/drivers/gpio/tps65910-gpio.c b/drivers/gpio/tps65910-gpio.c index 8d1ddfdd63eb..15097ca616d6 100644 --- a/drivers/gpio/tps65910-gpio.c +++ b/drivers/gpio/tps65910-gpio.c | |||
@@ -81,8 +81,10 @@ void tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base) | |||
81 | switch(tps65910_chip_id(tps65910)) { | 81 | switch(tps65910_chip_id(tps65910)) { |
82 | case TPS65910: | 82 | case TPS65910: |
83 | tps65910->gpio.ngpio = 6; | 83 | tps65910->gpio.ngpio = 6; |
84 | break; | ||
84 | case TPS65911: | 85 | case TPS65911: |
85 | tps65910->gpio.ngpio = 9; | 86 | tps65910->gpio.ngpio = 9; |
87 | break; | ||
86 | default: | 88 | default: |
87 | return; | 89 | return; |
88 | } | 90 | } |
diff --git a/drivers/gpio/wm831x-gpio.c b/drivers/gpio/wm831x-gpio.c index 309644cf4d9b..2bcfb0be09ff 100644 --- a/drivers/gpio/wm831x-gpio.c +++ b/drivers/gpio/wm831x-gpio.c | |||
@@ -180,6 +180,7 @@ static void wm831x_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) | |||
180 | break; | 180 | break; |
181 | case WM831X_GPIO_PULL_UP: | 181 | case WM831X_GPIO_PULL_UP: |
182 | pull = "pullup"; | 182 | pull = "pullup"; |
183 | break; | ||
183 | default: | 184 | default: |
184 | pull = "INVALID PULL"; | 185 | pull = "INVALID PULL"; |
185 | break; | 186 | break; |
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 21058e6ad2b8..82db18506662 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -886,9 +886,6 @@ int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group) | |||
886 | total_objects += dev->mode_config.num_connector; | 886 | total_objects += dev->mode_config.num_connector; |
887 | total_objects += dev->mode_config.num_encoder; | 887 | total_objects += dev->mode_config.num_encoder; |
888 | 888 | ||
889 | if (total_objects == 0) | ||
890 | return -EINVAL; | ||
891 | |||
892 | group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL); | 889 | group->id_list = kzalloc(total_objects * sizeof(uint32_t), GFP_KERNEL); |
893 | if (!group->id_list) | 890 | if (!group->id_list) |
894 | return -ENOMEM; | 891 | return -ENOMEM; |
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index e1787022d6c8..296fbd66f0e1 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1943,7 +1943,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1943 | if (!dev_priv->mm.gtt) { | 1943 | if (!dev_priv->mm.gtt) { |
1944 | DRM_ERROR("Failed to initialize GTT\n"); | 1944 | DRM_ERROR("Failed to initialize GTT\n"); |
1945 | ret = -ENODEV; | 1945 | ret = -ENODEV; |
1946 | goto out_iomapfree; | 1946 | goto out_rmmap; |
1947 | } | 1947 | } |
1948 | 1948 | ||
1949 | agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; | 1949 | agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; |
@@ -1987,7 +1987,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1987 | if (dev_priv->wq == NULL) { | 1987 | if (dev_priv->wq == NULL) { |
1988 | DRM_ERROR("Failed to create our workqueue.\n"); | 1988 | DRM_ERROR("Failed to create our workqueue.\n"); |
1989 | ret = -ENOMEM; | 1989 | ret = -ENOMEM; |
1990 | goto out_iomapfree; | 1990 | goto out_mtrrfree; |
1991 | } | 1991 | } |
1992 | 1992 | ||
1993 | /* enable GEM by default */ | 1993 | /* enable GEM by default */ |
@@ -2074,13 +2074,21 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2074 | return 0; | 2074 | return 0; |
2075 | 2075 | ||
2076 | out_gem_unload: | 2076 | out_gem_unload: |
2077 | if (dev_priv->mm.inactive_shrinker.shrink) | ||
2078 | unregister_shrinker(&dev_priv->mm.inactive_shrinker); | ||
2079 | |||
2077 | if (dev->pdev->msi_enabled) | 2080 | if (dev->pdev->msi_enabled) |
2078 | pci_disable_msi(dev->pdev); | 2081 | pci_disable_msi(dev->pdev); |
2079 | 2082 | ||
2080 | intel_teardown_gmbus(dev); | 2083 | intel_teardown_gmbus(dev); |
2081 | intel_teardown_mchbar(dev); | 2084 | intel_teardown_mchbar(dev); |
2082 | destroy_workqueue(dev_priv->wq); | 2085 | destroy_workqueue(dev_priv->wq); |
2083 | out_iomapfree: | 2086 | out_mtrrfree: |
2087 | if (dev_priv->mm.gtt_mtrr >= 0) { | ||
2088 | mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base, | ||
2089 | dev->agp->agp_info.aper_size * 1024 * 1024); | ||
2090 | dev_priv->mm.gtt_mtrr = -1; | ||
2091 | } | ||
2084 | io_mapping_free(dev_priv->mm.gtt_mapping); | 2092 | io_mapping_free(dev_priv->mm.gtt_mapping); |
2085 | out_rmmap: | 2093 | out_rmmap: |
2086 | pci_iounmap(dev->pdev, dev_priv->regs); | 2094 | pci_iounmap(dev->pdev, dev_priv->regs); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 013d304455b9..eb91e2dd7914 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -52,7 +52,7 @@ module_param_named(powersave, i915_powersave, int, 0600); | |||
52 | unsigned int i915_semaphores = 0; | 52 | unsigned int i915_semaphores = 0; |
53 | module_param_named(semaphores, i915_semaphores, int, 0600); | 53 | module_param_named(semaphores, i915_semaphores, int, 0600); |
54 | 54 | ||
55 | unsigned int i915_enable_rc6 = 1; | 55 | unsigned int i915_enable_rc6 = 0; |
56 | module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); | 56 | module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); |
57 | 57 | ||
58 | unsigned int i915_enable_fbc = 0; | 58 | unsigned int i915_enable_fbc = 0; |
@@ -577,6 +577,7 @@ int i915_reset(struct drm_device *dev, u8 flags) | |||
577 | if (get_seconds() - dev_priv->last_gpu_reset < 5) { | 577 | if (get_seconds() - dev_priv->last_gpu_reset < 5) { |
578 | DRM_ERROR("GPU hanging too fast, declaring wedged!\n"); | 578 | DRM_ERROR("GPU hanging too fast, declaring wedged!\n"); |
579 | } else switch (INTEL_INFO(dev)->gen) { | 579 | } else switch (INTEL_INFO(dev)->gen) { |
580 | case 7: | ||
580 | case 6: | 581 | case 6: |
581 | ret = gen6_do_reset(dev, flags); | 582 | ret = gen6_do_reset(dev, flags); |
582 | /* If reset with a user forcewake, try to restore */ | 583 | /* If reset with a user forcewake, try to restore */ |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 391b55f1cc74..e2aced6eec4c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -50,7 +50,6 @@ struct intel_dp { | |||
50 | bool has_audio; | 50 | bool has_audio; |
51 | int force_audio; | 51 | int force_audio; |
52 | uint32_t color_range; | 52 | uint32_t color_range; |
53 | int dpms_mode; | ||
54 | uint8_t link_bw; | 53 | uint8_t link_bw; |
55 | uint8_t lane_count; | 54 | uint8_t lane_count; |
56 | uint8_t dpcd[4]; | 55 | uint8_t dpcd[4]; |
@@ -138,8 +137,8 @@ intel_dp_max_lane_count(struct intel_dp *intel_dp) | |||
138 | { | 137 | { |
139 | int max_lane_count = 4; | 138 | int max_lane_count = 4; |
140 | 139 | ||
141 | if (intel_dp->dpcd[0] >= 0x11) { | 140 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) { |
142 | max_lane_count = intel_dp->dpcd[2] & 0x1f; | 141 | max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f; |
143 | switch (max_lane_count) { | 142 | switch (max_lane_count) { |
144 | case 1: case 2: case 4: | 143 | case 1: case 2: case 4: |
145 | break; | 144 | break; |
@@ -153,7 +152,7 @@ intel_dp_max_lane_count(struct intel_dp *intel_dp) | |||
153 | static int | 152 | static int |
154 | intel_dp_max_link_bw(struct intel_dp *intel_dp) | 153 | intel_dp_max_link_bw(struct intel_dp *intel_dp) |
155 | { | 154 | { |
156 | int max_link_bw = intel_dp->dpcd[1]; | 155 | int max_link_bw = intel_dp->dpcd[DP_MAX_LINK_RATE]; |
157 | 156 | ||
158 | switch (max_link_bw) { | 157 | switch (max_link_bw) { |
159 | case DP_LINK_BW_1_62: | 158 | case DP_LINK_BW_1_62: |
@@ -774,7 +773,8 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
774 | /* | 773 | /* |
775 | * Check for DPCD version > 1.1 and enhanced framing support | 774 | * Check for DPCD version > 1.1 and enhanced framing support |
776 | */ | 775 | */ |
777 | if (intel_dp->dpcd[0] >= 0x11 && (intel_dp->dpcd[2] & DP_ENHANCED_FRAME_CAP)) { | 776 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 && |
777 | (intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)) { | ||
778 | intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; | 778 | intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; |
779 | intel_dp->DP |= DP_ENHANCED_FRAMING; | 779 | intel_dp->DP |= DP_ENHANCED_FRAMING; |
780 | } | 780 | } |
@@ -942,11 +942,44 @@ static void ironlake_edp_pll_off(struct drm_encoder *encoder) | |||
942 | udelay(200); | 942 | udelay(200); |
943 | } | 943 | } |
944 | 944 | ||
945 | /* If the sink supports it, try to set the power state appropriately */ | ||
946 | static void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode) | ||
947 | { | ||
948 | int ret, i; | ||
949 | |||
950 | /* Should have a valid DPCD by this point */ | ||
951 | if (intel_dp->dpcd[DP_DPCD_REV] < 0x11) | ||
952 | return; | ||
953 | |||
954 | if (mode != DRM_MODE_DPMS_ON) { | ||
955 | ret = intel_dp_aux_native_write_1(intel_dp, DP_SET_POWER, | ||
956 | DP_SET_POWER_D3); | ||
957 | if (ret != 1) | ||
958 | DRM_DEBUG_DRIVER("failed to write sink power state\n"); | ||
959 | } else { | ||
960 | /* | ||
961 | * When turning on, we need to retry for 1ms to give the sink | ||
962 | * time to wake up. | ||
963 | */ | ||
964 | for (i = 0; i < 3; i++) { | ||
965 | ret = intel_dp_aux_native_write_1(intel_dp, | ||
966 | DP_SET_POWER, | ||
967 | DP_SET_POWER_D0); | ||
968 | if (ret == 1) | ||
969 | break; | ||
970 | msleep(1); | ||
971 | } | ||
972 | } | ||
973 | } | ||
974 | |||
945 | static void intel_dp_prepare(struct drm_encoder *encoder) | 975 | static void intel_dp_prepare(struct drm_encoder *encoder) |
946 | { | 976 | { |
947 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 977 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
948 | struct drm_device *dev = encoder->dev; | 978 | struct drm_device *dev = encoder->dev; |
949 | 979 | ||
980 | /* Wake up the sink first */ | ||
981 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); | ||
982 | |||
950 | if (is_edp(intel_dp)) { | 983 | if (is_edp(intel_dp)) { |
951 | ironlake_edp_backlight_off(dev); | 984 | ironlake_edp_backlight_off(dev); |
952 | ironlake_edp_panel_off(dev); | 985 | ironlake_edp_panel_off(dev); |
@@ -990,6 +1023,7 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
990 | if (mode != DRM_MODE_DPMS_ON) { | 1023 | if (mode != DRM_MODE_DPMS_ON) { |
991 | if (is_edp(intel_dp)) | 1024 | if (is_edp(intel_dp)) |
992 | ironlake_edp_backlight_off(dev); | 1025 | ironlake_edp_backlight_off(dev); |
1026 | intel_dp_sink_dpms(intel_dp, mode); | ||
993 | intel_dp_link_down(intel_dp); | 1027 | intel_dp_link_down(intel_dp); |
994 | if (is_edp(intel_dp)) | 1028 | if (is_edp(intel_dp)) |
995 | ironlake_edp_panel_off(dev); | 1029 | ironlake_edp_panel_off(dev); |
@@ -998,6 +1032,7 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
998 | } else { | 1032 | } else { |
999 | if (is_edp(intel_dp)) | 1033 | if (is_edp(intel_dp)) |
1000 | ironlake_edp_panel_vdd_on(intel_dp); | 1034 | ironlake_edp_panel_vdd_on(intel_dp); |
1035 | intel_dp_sink_dpms(intel_dp, mode); | ||
1001 | if (!(dp_reg & DP_PORT_EN)) { | 1036 | if (!(dp_reg & DP_PORT_EN)) { |
1002 | intel_dp_start_link_train(intel_dp); | 1037 | intel_dp_start_link_train(intel_dp); |
1003 | if (is_edp(intel_dp)) { | 1038 | if (is_edp(intel_dp)) { |
@@ -1009,7 +1044,31 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
1009 | if (is_edp(intel_dp)) | 1044 | if (is_edp(intel_dp)) |
1010 | ironlake_edp_backlight_on(dev); | 1045 | ironlake_edp_backlight_on(dev); |
1011 | } | 1046 | } |
1012 | intel_dp->dpms_mode = mode; | 1047 | } |
1048 | |||
1049 | /* | ||
1050 | * Native read with retry for link status and receiver capability reads for | ||
1051 | * cases where the sink may still be asleep. | ||
1052 | */ | ||
1053 | static bool | ||
1054 | intel_dp_aux_native_read_retry(struct intel_dp *intel_dp, uint16_t address, | ||
1055 | uint8_t *recv, int recv_bytes) | ||
1056 | { | ||
1057 | int ret, i; | ||
1058 | |||
1059 | /* | ||
1060 | * Sinks are *supposed* to come up within 1ms from an off state, | ||
1061 | * but we're also supposed to retry 3 times per the spec. | ||
1062 | */ | ||
1063 | for (i = 0; i < 3; i++) { | ||
1064 | ret = intel_dp_aux_native_read(intel_dp, address, recv, | ||
1065 | recv_bytes); | ||
1066 | if (ret == recv_bytes) | ||
1067 | return true; | ||
1068 | msleep(1); | ||
1069 | } | ||
1070 | |||
1071 | return false; | ||
1013 | } | 1072 | } |
1014 | 1073 | ||
1015 | /* | 1074 | /* |
@@ -1019,14 +1078,10 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
1019 | static bool | 1078 | static bool |
1020 | intel_dp_get_link_status(struct intel_dp *intel_dp) | 1079 | intel_dp_get_link_status(struct intel_dp *intel_dp) |
1021 | { | 1080 | { |
1022 | int ret; | 1081 | return intel_dp_aux_native_read_retry(intel_dp, |
1023 | 1082 | DP_LANE0_1_STATUS, | |
1024 | ret = intel_dp_aux_native_read(intel_dp, | 1083 | intel_dp->link_status, |
1025 | DP_LANE0_1_STATUS, | 1084 | DP_LINK_STATUS_SIZE); |
1026 | intel_dp->link_status, DP_LINK_STATUS_SIZE); | ||
1027 | if (ret != DP_LINK_STATUS_SIZE) | ||
1028 | return false; | ||
1029 | return true; | ||
1030 | } | 1085 | } |
1031 | 1086 | ||
1032 | static uint8_t | 1087 | static uint8_t |
@@ -1515,6 +1570,8 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1515 | static void | 1570 | static void |
1516 | intel_dp_check_link_status(struct intel_dp *intel_dp) | 1571 | intel_dp_check_link_status(struct intel_dp *intel_dp) |
1517 | { | 1572 | { |
1573 | int ret; | ||
1574 | |||
1518 | if (!intel_dp->base.base.crtc) | 1575 | if (!intel_dp->base.base.crtc) |
1519 | return; | 1576 | return; |
1520 | 1577 | ||
@@ -1523,6 +1580,15 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) | |||
1523 | return; | 1580 | return; |
1524 | } | 1581 | } |
1525 | 1582 | ||
1583 | /* Try to read receiver status if the link appears to be up */ | ||
1584 | ret = intel_dp_aux_native_read(intel_dp, | ||
1585 | 0x000, intel_dp->dpcd, | ||
1586 | sizeof (intel_dp->dpcd)); | ||
1587 | if (ret != sizeof(intel_dp->dpcd)) { | ||
1588 | intel_dp_link_down(intel_dp); | ||
1589 | return; | ||
1590 | } | ||
1591 | |||
1526 | if (!intel_channel_eq_ok(intel_dp)) { | 1592 | if (!intel_channel_eq_ok(intel_dp)) { |
1527 | intel_dp_start_link_train(intel_dp); | 1593 | intel_dp_start_link_train(intel_dp); |
1528 | intel_dp_complete_link_train(intel_dp); | 1594 | intel_dp_complete_link_train(intel_dp); |
@@ -1533,6 +1599,7 @@ static enum drm_connector_status | |||
1533 | ironlake_dp_detect(struct intel_dp *intel_dp) | 1599 | ironlake_dp_detect(struct intel_dp *intel_dp) |
1534 | { | 1600 | { |
1535 | enum drm_connector_status status; | 1601 | enum drm_connector_status status; |
1602 | bool ret; | ||
1536 | 1603 | ||
1537 | /* Can't disconnect eDP, but you can close the lid... */ | 1604 | /* Can't disconnect eDP, but you can close the lid... */ |
1538 | if (is_edp(intel_dp)) { | 1605 | if (is_edp(intel_dp)) { |
@@ -1543,13 +1610,11 @@ ironlake_dp_detect(struct intel_dp *intel_dp) | |||
1543 | } | 1610 | } |
1544 | 1611 | ||
1545 | status = connector_status_disconnected; | 1612 | status = connector_status_disconnected; |
1546 | if (intel_dp_aux_native_read(intel_dp, | 1613 | ret = intel_dp_aux_native_read_retry(intel_dp, |
1547 | 0x000, intel_dp->dpcd, | 1614 | 0x000, intel_dp->dpcd, |
1548 | sizeof (intel_dp->dpcd)) | 1615 | sizeof (intel_dp->dpcd)); |
1549 | == sizeof(intel_dp->dpcd)) { | 1616 | if (ret && intel_dp->dpcd[DP_DPCD_REV] != 0) |
1550 | if (intel_dp->dpcd[0] != 0) | 1617 | status = connector_status_connected; |
1551 | status = connector_status_connected; | ||
1552 | } | ||
1553 | DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0], | 1618 | DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0], |
1554 | intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]); | 1619 | intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]); |
1555 | return status; | 1620 | return status; |
@@ -1586,7 +1651,7 @@ g4x_dp_detect(struct intel_dp *intel_dp) | |||
1586 | if (intel_dp_aux_native_read(intel_dp, 0x000, intel_dp->dpcd, | 1651 | if (intel_dp_aux_native_read(intel_dp, 0x000, intel_dp->dpcd, |
1587 | sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd)) | 1652 | sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd)) |
1588 | { | 1653 | { |
1589 | if (intel_dp->dpcd[0] != 0) | 1654 | if (intel_dp->dpcd[DP_DPCD_REV] != 0) |
1590 | status = connector_status_connected; | 1655 | status = connector_status_connected; |
1591 | } | 1656 | } |
1592 | 1657 | ||
@@ -1790,8 +1855,7 @@ intel_dp_hot_plug(struct intel_encoder *intel_encoder) | |||
1790 | { | 1855 | { |
1791 | struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base); | 1856 | struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base); |
1792 | 1857 | ||
1793 | if (intel_dp->dpms_mode == DRM_MODE_DPMS_ON) | 1858 | intel_dp_check_link_status(intel_dp); |
1794 | intel_dp_check_link_status(intel_dp); | ||
1795 | } | 1859 | } |
1796 | 1860 | ||
1797 | /* Return which DP Port should be selected for Transcoder DP control */ | 1861 | /* Return which DP Port should be selected for Transcoder DP control */ |
@@ -1859,7 +1923,6 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1859 | return; | 1923 | return; |
1860 | 1924 | ||
1861 | intel_dp->output_reg = output_reg; | 1925 | intel_dp->output_reg = output_reg; |
1862 | intel_dp->dpms_mode = -1; | ||
1863 | 1926 | ||
1864 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 1927 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
1865 | if (!intel_connector) { | 1928 | if (!intel_connector) { |
@@ -1954,8 +2017,9 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1954 | sizeof(intel_dp->dpcd)); | 2017 | sizeof(intel_dp->dpcd)); |
1955 | ironlake_edp_panel_vdd_off(intel_dp); | 2018 | ironlake_edp_panel_vdd_off(intel_dp); |
1956 | if (ret == sizeof(intel_dp->dpcd)) { | 2019 | if (ret == sizeof(intel_dp->dpcd)) { |
1957 | if (intel_dp->dpcd[0] >= 0x11) | 2020 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) |
1958 | dev_priv->no_aux_handshake = intel_dp->dpcd[3] & | 2021 | dev_priv->no_aux_handshake = |
2022 | intel_dp->dpcd[DP_MAX_DOWNSPREAD] & | ||
1959 | DP_NO_AUX_HANDSHAKE_LINK_TRAINING; | 2023 | DP_NO_AUX_HANDSHAKE_LINK_TRAINING; |
1960 | } else { | 2024 | } else { |
1961 | /* if this fails, presume the device is a ghost */ | 2025 | /* if this fails, presume the device is a ghost */ |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index c0e0ee63fbf4..39ac2b634ae5 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -165,7 +165,7 @@ void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring); | |||
165 | int __must_check intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n); | 165 | int __must_check intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n); |
166 | static inline int intel_wait_ring_idle(struct intel_ring_buffer *ring) | 166 | static inline int intel_wait_ring_idle(struct intel_ring_buffer *ring) |
167 | { | 167 | { |
168 | return intel_wait_ring_buffer(ring, ring->space - 8); | 168 | return intel_wait_ring_buffer(ring, ring->size - 8); |
169 | } | 169 | } |
170 | 170 | ||
171 | int __must_check intel_ring_begin(struct intel_ring_buffer *ring, int n); | 171 | int __must_check intel_ring_begin(struct intel_ring_buffer *ring, int n); |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index e8a5ffb0124d..15bd0477a3e8 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -985,17 +985,19 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav | |||
985 | { | 985 | { |
986 | save->vga_control[0] = RREG32(D1VGA_CONTROL); | 986 | save->vga_control[0] = RREG32(D1VGA_CONTROL); |
987 | save->vga_control[1] = RREG32(D2VGA_CONTROL); | 987 | save->vga_control[1] = RREG32(D2VGA_CONTROL); |
988 | save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL); | ||
989 | save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL); | ||
990 | save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL); | ||
991 | save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL); | ||
992 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); | 988 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); |
993 | save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); | 989 | save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); |
994 | save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET); | 990 | save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET); |
995 | save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); | 991 | save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); |
996 | if (!(rdev->flags & RADEON_IS_IGP)) { | 992 | if (rdev->num_crtc >= 4) { |
993 | save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL); | ||
994 | save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL); | ||
997 | save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET); | 995 | save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET); |
998 | save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET); | 996 | save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET); |
997 | } | ||
998 | if (rdev->num_crtc >= 6) { | ||
999 | save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL); | ||
1000 | save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL); | ||
999 | save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET); | 1001 | save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET); |
1000 | save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); | 1002 | save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); |
1001 | } | 1003 | } |
@@ -1004,35 +1006,45 @@ void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *sav | |||
1004 | WREG32(VGA_RENDER_CONTROL, 0); | 1006 | WREG32(VGA_RENDER_CONTROL, 0); |
1005 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); | 1007 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); |
1006 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); | 1008 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); |
1007 | if (!(rdev->flags & RADEON_IS_IGP)) { | 1009 | if (rdev->num_crtc >= 4) { |
1008 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); | 1010 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); |
1009 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); | 1011 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); |
1012 | } | ||
1013 | if (rdev->num_crtc >= 6) { | ||
1010 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); | 1014 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); |
1011 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); | 1015 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); |
1012 | } | 1016 | } |
1013 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 1017 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); |
1014 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 1018 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); |
1015 | if (!(rdev->flags & RADEON_IS_IGP)) { | 1019 | if (rdev->num_crtc >= 4) { |
1016 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | 1020 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); |
1017 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | 1021 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); |
1022 | } | ||
1023 | if (rdev->num_crtc >= 6) { | ||
1018 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | 1024 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); |
1019 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | 1025 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); |
1020 | } | 1026 | } |
1021 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 1027 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); |
1022 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 1028 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); |
1023 | if (!(rdev->flags & RADEON_IS_IGP)) { | 1029 | if (rdev->num_crtc >= 4) { |
1024 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | 1030 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); |
1025 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | 1031 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); |
1032 | } | ||
1033 | if (rdev->num_crtc >= 6) { | ||
1026 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | 1034 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); |
1027 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | 1035 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); |
1028 | } | 1036 | } |
1029 | 1037 | ||
1030 | WREG32(D1VGA_CONTROL, 0); | 1038 | WREG32(D1VGA_CONTROL, 0); |
1031 | WREG32(D2VGA_CONTROL, 0); | 1039 | WREG32(D2VGA_CONTROL, 0); |
1032 | WREG32(EVERGREEN_D3VGA_CONTROL, 0); | 1040 | if (rdev->num_crtc >= 4) { |
1033 | WREG32(EVERGREEN_D4VGA_CONTROL, 0); | 1041 | WREG32(EVERGREEN_D3VGA_CONTROL, 0); |
1034 | WREG32(EVERGREEN_D5VGA_CONTROL, 0); | 1042 | WREG32(EVERGREEN_D4VGA_CONTROL, 0); |
1035 | WREG32(EVERGREEN_D6VGA_CONTROL, 0); | 1043 | } |
1044 | if (rdev->num_crtc >= 6) { | ||
1045 | WREG32(EVERGREEN_D5VGA_CONTROL, 0); | ||
1046 | WREG32(EVERGREEN_D6VGA_CONTROL, 0); | ||
1047 | } | ||
1036 | } | 1048 | } |
1037 | 1049 | ||
1038 | void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) | 1050 | void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) |
@@ -1055,7 +1067,7 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s | |||
1055 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET, | 1067 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET, |
1056 | (u32)rdev->mc.vram_start); | 1068 | (u32)rdev->mc.vram_start); |
1057 | 1069 | ||
1058 | if (!(rdev->flags & RADEON_IS_IGP)) { | 1070 | if (rdev->num_crtc >= 4) { |
1059 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, | 1071 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, |
1060 | upper_32_bits(rdev->mc.vram_start)); | 1072 | upper_32_bits(rdev->mc.vram_start)); |
1061 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, | 1073 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, |
@@ -1073,7 +1085,8 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s | |||
1073 | (u32)rdev->mc.vram_start); | 1085 | (u32)rdev->mc.vram_start); |
1074 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, | 1086 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, |
1075 | (u32)rdev->mc.vram_start); | 1087 | (u32)rdev->mc.vram_start); |
1076 | 1088 | } | |
1089 | if (rdev->num_crtc >= 6) { | ||
1077 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, | 1090 | WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, |
1078 | upper_32_bits(rdev->mc.vram_start)); | 1091 | upper_32_bits(rdev->mc.vram_start)); |
1079 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, | 1092 | WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, |
@@ -1101,31 +1114,41 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s | |||
1101 | /* Restore video state */ | 1114 | /* Restore video state */ |
1102 | WREG32(D1VGA_CONTROL, save->vga_control[0]); | 1115 | WREG32(D1VGA_CONTROL, save->vga_control[0]); |
1103 | WREG32(D2VGA_CONTROL, save->vga_control[1]); | 1116 | WREG32(D2VGA_CONTROL, save->vga_control[1]); |
1104 | WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]); | 1117 | if (rdev->num_crtc >= 4) { |
1105 | WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]); | 1118 | WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]); |
1106 | WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]); | 1119 | WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]); |
1107 | WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]); | 1120 | } |
1121 | if (rdev->num_crtc >= 6) { | ||
1122 | WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]); | ||
1123 | WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]); | ||
1124 | } | ||
1108 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); | 1125 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); |
1109 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); | 1126 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); |
1110 | if (!(rdev->flags & RADEON_IS_IGP)) { | 1127 | if (rdev->num_crtc >= 4) { |
1111 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); | 1128 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); |
1112 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); | 1129 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); |
1130 | } | ||
1131 | if (rdev->num_crtc >= 6) { | ||
1113 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); | 1132 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); |
1114 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); | 1133 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); |
1115 | } | 1134 | } |
1116 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]); | 1135 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]); |
1117 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]); | 1136 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]); |
1118 | if (!(rdev->flags & RADEON_IS_IGP)) { | 1137 | if (rdev->num_crtc >= 4) { |
1119 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]); | 1138 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]); |
1120 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]); | 1139 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]); |
1140 | } | ||
1141 | if (rdev->num_crtc >= 6) { | ||
1121 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]); | 1142 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]); |
1122 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]); | 1143 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]); |
1123 | } | 1144 | } |
1124 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 1145 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); |
1125 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 1146 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); |
1126 | if (!(rdev->flags & RADEON_IS_IGP)) { | 1147 | if (rdev->num_crtc >= 4) { |
1127 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | 1148 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); |
1128 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | 1149 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); |
1150 | } | ||
1151 | if (rdev->num_crtc >= 6) { | ||
1129 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | 1152 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); |
1130 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | 1153 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); |
1131 | } | 1154 | } |
@@ -1977,7 +2000,7 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
1977 | gb_backend_map = 0x66442200; | 2000 | gb_backend_map = 0x66442200; |
1978 | break; | 2001 | break; |
1979 | case CHIP_JUNIPER: | 2002 | case CHIP_JUNIPER: |
1980 | gb_backend_map = 0x00006420; | 2003 | gb_backend_map = 0x00002200; |
1981 | break; | 2004 | break; |
1982 | default: | 2005 | default: |
1983 | gb_backend_map = | 2006 | gb_backend_map = |
@@ -2417,18 +2440,22 @@ void evergreen_disable_interrupt_state(struct radeon_device *rdev) | |||
2417 | WREG32(GRBM_INT_CNTL, 0); | 2440 | WREG32(GRBM_INT_CNTL, 0); |
2418 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 2441 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); |
2419 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 2442 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); |
2420 | if (!(rdev->flags & RADEON_IS_IGP)) { | 2443 | if (rdev->num_crtc >= 4) { |
2421 | WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | 2444 | WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); |
2422 | WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | 2445 | WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); |
2446 | } | ||
2447 | if (rdev->num_crtc >= 6) { | ||
2423 | WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | 2448 | WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); |
2424 | WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | 2449 | WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); |
2425 | } | 2450 | } |
2426 | 2451 | ||
2427 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | 2452 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); |
2428 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | 2453 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); |
2429 | if (!(rdev->flags & RADEON_IS_IGP)) { | 2454 | if (rdev->num_crtc >= 4) { |
2430 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | 2455 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); |
2431 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | 2456 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); |
2457 | } | ||
2458 | if (rdev->num_crtc >= 6) { | ||
2432 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | 2459 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); |
2433 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | 2460 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); |
2434 | } | 2461 | } |
@@ -2547,19 +2574,25 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
2547 | 2574 | ||
2548 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); | 2575 | WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); |
2549 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2); | 2576 | WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2); |
2550 | if (!(rdev->flags & RADEON_IS_IGP)) { | 2577 | if (rdev->num_crtc >= 4) { |
2551 | WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3); | 2578 | WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3); |
2552 | WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4); | 2579 | WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4); |
2580 | } | ||
2581 | if (rdev->num_crtc >= 6) { | ||
2553 | WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, crtc5); | 2582 | WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, crtc5); |
2554 | WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); | 2583 | WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); |
2555 | } | 2584 | } |
2556 | 2585 | ||
2557 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1); | 2586 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1); |
2558 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2); | 2587 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2); |
2559 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3); | 2588 | if (rdev->num_crtc >= 4) { |
2560 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4); | 2589 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3); |
2561 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5); | 2590 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4); |
2562 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6); | 2591 | } |
2592 | if (rdev->num_crtc >= 6) { | ||
2593 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5); | ||
2594 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6); | ||
2595 | } | ||
2563 | 2596 | ||
2564 | WREG32(DC_HPD1_INT_CONTROL, hpd1); | 2597 | WREG32(DC_HPD1_INT_CONTROL, hpd1); |
2565 | WREG32(DC_HPD2_INT_CONTROL, hpd2); | 2598 | WREG32(DC_HPD2_INT_CONTROL, hpd2); |
@@ -2583,53 +2616,57 @@ static inline void evergreen_irq_ack(struct radeon_device *rdev) | |||
2583 | rdev->irq.stat_regs.evergreen.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5); | 2616 | rdev->irq.stat_regs.evergreen.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5); |
2584 | rdev->irq.stat_regs.evergreen.d1grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET); | 2617 | rdev->irq.stat_regs.evergreen.d1grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET); |
2585 | rdev->irq.stat_regs.evergreen.d2grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET); | 2618 | rdev->irq.stat_regs.evergreen.d2grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET); |
2586 | rdev->irq.stat_regs.evergreen.d3grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET); | 2619 | if (rdev->num_crtc >= 4) { |
2587 | rdev->irq.stat_regs.evergreen.d4grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET); | 2620 | rdev->irq.stat_regs.evergreen.d3grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET); |
2588 | rdev->irq.stat_regs.evergreen.d5grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET); | 2621 | rdev->irq.stat_regs.evergreen.d4grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET); |
2589 | rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET); | 2622 | } |
2623 | if (rdev->num_crtc >= 6) { | ||
2624 | rdev->irq.stat_regs.evergreen.d5grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET); | ||
2625 | rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET); | ||
2626 | } | ||
2590 | 2627 | ||
2591 | if (rdev->irq.stat_regs.evergreen.d1grph_int & GRPH_PFLIP_INT_OCCURRED) | 2628 | if (rdev->irq.stat_regs.evergreen.d1grph_int & GRPH_PFLIP_INT_OCCURRED) |
2592 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); | 2629 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); |
2593 | if (rdev->irq.stat_regs.evergreen.d2grph_int & GRPH_PFLIP_INT_OCCURRED) | 2630 | if (rdev->irq.stat_regs.evergreen.d2grph_int & GRPH_PFLIP_INT_OCCURRED) |
2594 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); | 2631 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); |
2595 | if (rdev->irq.stat_regs.evergreen.d3grph_int & GRPH_PFLIP_INT_OCCURRED) | ||
2596 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); | ||
2597 | if (rdev->irq.stat_regs.evergreen.d4grph_int & GRPH_PFLIP_INT_OCCURRED) | ||
2598 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); | ||
2599 | if (rdev->irq.stat_regs.evergreen.d5grph_int & GRPH_PFLIP_INT_OCCURRED) | ||
2600 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); | ||
2601 | if (rdev->irq.stat_regs.evergreen.d6grph_int & GRPH_PFLIP_INT_OCCURRED) | ||
2602 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); | ||
2603 | |||
2604 | if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) | 2632 | if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) |
2605 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK); | 2633 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK); |
2606 | if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT) | 2634 | if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT) |
2607 | WREG32(VLINE_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VLINE_ACK); | 2635 | WREG32(VLINE_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VLINE_ACK); |
2608 | |||
2609 | if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) | 2636 | if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) |
2610 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VBLANK_ACK); | 2637 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VBLANK_ACK); |
2611 | if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) | 2638 | if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) |
2612 | WREG32(VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK); | 2639 | WREG32(VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK); |
2613 | 2640 | ||
2614 | if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) | 2641 | if (rdev->num_crtc >= 4) { |
2615 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK); | 2642 | if (rdev->irq.stat_regs.evergreen.d3grph_int & GRPH_PFLIP_INT_OCCURRED) |
2616 | if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) | 2643 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); |
2617 | WREG32(VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK); | 2644 | if (rdev->irq.stat_regs.evergreen.d4grph_int & GRPH_PFLIP_INT_OCCURRED) |
2618 | 2645 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); | |
2619 | if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) | 2646 | if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) |
2620 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK); | 2647 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK); |
2621 | if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) | 2648 | if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) |
2622 | WREG32(VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK); | 2649 | WREG32(VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK); |
2623 | 2650 | if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) | |
2624 | if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) | 2651 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK); |
2625 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK); | 2652 | if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) |
2626 | if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) | 2653 | WREG32(VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK); |
2627 | WREG32(VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK); | 2654 | } |
2628 | 2655 | ||
2629 | if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) | 2656 | if (rdev->num_crtc >= 6) { |
2630 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK); | 2657 | if (rdev->irq.stat_regs.evergreen.d5grph_int & GRPH_PFLIP_INT_OCCURRED) |
2631 | if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) | 2658 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); |
2632 | WREG32(VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK); | 2659 | if (rdev->irq.stat_regs.evergreen.d6grph_int & GRPH_PFLIP_INT_OCCURRED) |
2660 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); | ||
2661 | if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) | ||
2662 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK); | ||
2663 | if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) | ||
2664 | WREG32(VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK); | ||
2665 | if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) | ||
2666 | WREG32(VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK); | ||
2667 | if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) | ||
2668 | WREG32(VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK); | ||
2669 | } | ||
2633 | 2670 | ||
2634 | if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) { | 2671 | if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) { |
2635 | tmp = RREG32(DC_HPD1_INT_CONTROL); | 2672 | tmp = RREG32(DC_HPD1_INT_CONTROL); |
@@ -3237,6 +3274,7 @@ void evergreen_fini(struct radeon_device *rdev) | |||
3237 | r700_cp_fini(rdev); | 3274 | r700_cp_fini(rdev); |
3238 | r600_irq_fini(rdev); | 3275 | r600_irq_fini(rdev); |
3239 | radeon_wb_fini(rdev); | 3276 | radeon_wb_fini(rdev); |
3277 | radeon_ib_pool_fini(rdev); | ||
3240 | radeon_irq_kms_fini(rdev); | 3278 | radeon_irq_kms_fini(rdev); |
3241 | evergreen_pcie_gart_fini(rdev); | 3279 | evergreen_pcie_gart_fini(rdev); |
3242 | radeon_gem_fini(rdev); | 3280 | radeon_gem_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c index 57f3bc17b87e..2eb251858e72 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c | |||
@@ -252,7 +252,7 @@ draw_auto(struct radeon_device *rdev) | |||
252 | 252 | ||
253 | } | 253 | } |
254 | 254 | ||
255 | /* emits 36 */ | 255 | /* emits 39 */ |
256 | static void | 256 | static void |
257 | set_default_state(struct radeon_device *rdev) | 257 | set_default_state(struct radeon_device *rdev) |
258 | { | 258 | { |
@@ -531,6 +531,11 @@ set_default_state(struct radeon_device *rdev) | |||
531 | radeon_ring_write(rdev, (SQ_DYN_GPR_CNTL_PS_FLUSH_REQ - PACKET3_SET_CONFIG_REG_START) >> 2); | 531 | radeon_ring_write(rdev, (SQ_DYN_GPR_CNTL_PS_FLUSH_REQ - PACKET3_SET_CONFIG_REG_START) >> 2); |
532 | radeon_ring_write(rdev, 0); | 532 | radeon_ring_write(rdev, 0); |
533 | 533 | ||
534 | /* setup LDS */ | ||
535 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 1)); | ||
536 | radeon_ring_write(rdev, (SQ_LDS_RESOURCE_MGMT - PACKET3_SET_CONFIG_REG_START) >> 2); | ||
537 | radeon_ring_write(rdev, 0x10001000); | ||
538 | |||
534 | /* SQ config */ | 539 | /* SQ config */ |
535 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 11)); | 540 | radeon_ring_write(rdev, PACKET3(PACKET3_SET_CONFIG_REG, 11)); |
536 | radeon_ring_write(rdev, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_START) >> 2); | 541 | radeon_ring_write(rdev, (SQ_CONFIG - PACKET3_SET_CONFIG_REG_START) >> 2); |
@@ -773,7 +778,7 @@ int evergreen_blit_prepare_copy(struct radeon_device *rdev, int size_bytes) | |||
773 | /* calculate number of loops correctly */ | 778 | /* calculate number of loops correctly */ |
774 | ring_size = num_loops * dwords_per_loop; | 779 | ring_size = num_loops * dwords_per_loop; |
775 | /* set default + shaders */ | 780 | /* set default + shaders */ |
776 | ring_size += 52; /* shaders + def state */ | 781 | ring_size += 55; /* shaders + def state */ |
777 | ring_size += 10; /* fence emit for VB IB */ | 782 | ring_size += 10; /* fence emit for VB IB */ |
778 | ring_size += 5; /* done copy */ | 783 | ring_size += 5; /* done copy */ |
779 | ring_size += 10; /* fence emit for done copy */ | 784 | ring_size += 10; /* fence emit for done copy */ |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 1636e3449825..b7b2714f0b32 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -466,7 +466,7 @@ | |||
466 | #define IH_RB_WPTR_ADDR_LO 0x3e14 | 466 | #define IH_RB_WPTR_ADDR_LO 0x3e14 |
467 | #define IH_CNTL 0x3e18 | 467 | #define IH_CNTL 0x3e18 |
468 | # define ENABLE_INTR (1 << 0) | 468 | # define ENABLE_INTR (1 << 0) |
469 | # define IH_MC_SWAP(x) ((x) << 2) | 469 | # define IH_MC_SWAP(x) ((x) << 1) |
470 | # define IH_MC_SWAP_NONE 0 | 470 | # define IH_MC_SWAP_NONE 0 |
471 | # define IH_MC_SWAP_16BIT 1 | 471 | # define IH_MC_SWAP_16BIT 1 |
472 | # define IH_MC_SWAP_32BIT 2 | 472 | # define IH_MC_SWAP_32BIT 2 |
@@ -547,7 +547,7 @@ | |||
547 | # define LB_D5_VBLANK_INTERRUPT (1 << 3) | 547 | # define LB_D5_VBLANK_INTERRUPT (1 << 3) |
548 | # define DC_HPD5_INTERRUPT (1 << 17) | 548 | # define DC_HPD5_INTERRUPT (1 << 17) |
549 | # define DC_HPD5_RX_INTERRUPT (1 << 18) | 549 | # define DC_HPD5_RX_INTERRUPT (1 << 18) |
550 | #define DISP_INTERRUPT_STATUS_CONTINUE5 0x6050 | 550 | #define DISP_INTERRUPT_STATUS_CONTINUE5 0x6150 |
551 | # define LB_D6_VLINE_INTERRUPT (1 << 2) | 551 | # define LB_D6_VLINE_INTERRUPT (1 << 2) |
552 | # define LB_D6_VBLANK_INTERRUPT (1 << 3) | 552 | # define LB_D6_VBLANK_INTERRUPT (1 << 3) |
553 | # define DC_HPD6_INTERRUPT (1 << 17) | 553 | # define DC_HPD6_INTERRUPT (1 << 17) |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 16caafeadf5e..559dbd412906 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -1581,6 +1581,7 @@ void cayman_fini(struct radeon_device *rdev) | |||
1581 | cayman_cp_fini(rdev); | 1581 | cayman_cp_fini(rdev); |
1582 | r600_irq_fini(rdev); | 1582 | r600_irq_fini(rdev); |
1583 | radeon_wb_fini(rdev); | 1583 | radeon_wb_fini(rdev); |
1584 | radeon_ib_pool_fini(rdev); | ||
1584 | radeon_irq_kms_fini(rdev); | 1585 | radeon_irq_kms_fini(rdev); |
1585 | cayman_pcie_gart_fini(rdev); | 1586 | cayman_pcie_gart_fini(rdev); |
1586 | radeon_gem_fini(rdev); | 1587 | radeon_gem_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index f79d2ccb6755..bc54b26cb32f 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -2628,6 +2628,7 @@ void r600_fini(struct radeon_device *rdev) | |||
2628 | r600_cp_fini(rdev); | 2628 | r600_cp_fini(rdev); |
2629 | r600_irq_fini(rdev); | 2629 | r600_irq_fini(rdev); |
2630 | radeon_wb_fini(rdev); | 2630 | radeon_wb_fini(rdev); |
2631 | radeon_ib_pool_fini(rdev); | ||
2631 | radeon_irq_kms_fini(rdev); | 2632 | radeon_irq_kms_fini(rdev); |
2632 | r600_pcie_gart_fini(rdev); | 2633 | r600_pcie_gart_fini(rdev); |
2633 | radeon_agp_fini(rdev); | 2634 | radeon_agp_fini(rdev); |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index f140a0d5cb54..0245ae6c204e 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
@@ -536,7 +536,7 @@ | |||
536 | #define IH_RB_WPTR_ADDR_LO 0x3e14 | 536 | #define IH_RB_WPTR_ADDR_LO 0x3e14 |
537 | #define IH_CNTL 0x3e18 | 537 | #define IH_CNTL 0x3e18 |
538 | # define ENABLE_INTR (1 << 0) | 538 | # define ENABLE_INTR (1 << 0) |
539 | # define IH_MC_SWAP(x) ((x) << 2) | 539 | # define IH_MC_SWAP(x) ((x) << 1) |
540 | # define IH_MC_SWAP_NONE 0 | 540 | # define IH_MC_SWAP_NONE 0 |
541 | # define IH_MC_SWAP_16BIT 1 | 541 | # define IH_MC_SWAP_16BIT 1 |
542 | # define IH_MC_SWAP_32BIT 2 | 542 | # define IH_MC_SWAP_32BIT 2 |
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c index 3fc5fa1aefd0..229a20f10e2b 100644 --- a/drivers/gpu/drm/radeon/radeon_bios.c +++ b/drivers/gpu/drm/radeon/radeon_bios.c | |||
@@ -331,7 +331,7 @@ static bool avivo_read_disabled_bios(struct radeon_device *rdev) | |||
331 | 331 | ||
332 | seprom_cntl1 = RREG32(RADEON_SEPROM_CNTL1); | 332 | seprom_cntl1 = RREG32(RADEON_SEPROM_CNTL1); |
333 | viph_control = RREG32(RADEON_VIPH_CONTROL); | 333 | viph_control = RREG32(RADEON_VIPH_CONTROL); |
334 | bus_cntl = RREG32(RADEON_BUS_CNTL); | 334 | bus_cntl = RREG32(RV370_BUS_CNTL); |
335 | d1vga_control = RREG32(AVIVO_D1VGA_CONTROL); | 335 | d1vga_control = RREG32(AVIVO_D1VGA_CONTROL); |
336 | d2vga_control = RREG32(AVIVO_D2VGA_CONTROL); | 336 | d2vga_control = RREG32(AVIVO_D2VGA_CONTROL); |
337 | vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL); | 337 | vga_render_control = RREG32(AVIVO_VGA_RENDER_CONTROL); |
@@ -350,7 +350,7 @@ static bool avivo_read_disabled_bios(struct radeon_device *rdev) | |||
350 | WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN)); | 350 | WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN)); |
351 | 351 | ||
352 | /* enable the rom */ | 352 | /* enable the rom */ |
353 | WREG32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM)); | 353 | WREG32(RV370_BUS_CNTL, (bus_cntl & ~RV370_BUS_BIOS_DIS_ROM)); |
354 | 354 | ||
355 | /* Disable VGA mode */ | 355 | /* Disable VGA mode */ |
356 | WREG32(AVIVO_D1VGA_CONTROL, | 356 | WREG32(AVIVO_D1VGA_CONTROL, |
@@ -367,7 +367,7 @@ static bool avivo_read_disabled_bios(struct radeon_device *rdev) | |||
367 | /* restore regs */ | 367 | /* restore regs */ |
368 | WREG32(RADEON_SEPROM_CNTL1, seprom_cntl1); | 368 | WREG32(RADEON_SEPROM_CNTL1, seprom_cntl1); |
369 | WREG32(RADEON_VIPH_CONTROL, viph_control); | 369 | WREG32(RADEON_VIPH_CONTROL, viph_control); |
370 | WREG32(RADEON_BUS_CNTL, bus_cntl); | 370 | WREG32(RV370_BUS_CNTL, bus_cntl); |
371 | WREG32(AVIVO_D1VGA_CONTROL, d1vga_control); | 371 | WREG32(AVIVO_D1VGA_CONTROL, d1vga_control); |
372 | WREG32(AVIVO_D2VGA_CONTROL, d2vga_control); | 372 | WREG32(AVIVO_D2VGA_CONTROL, d2vga_control); |
373 | WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control); | 373 | WREG32(AVIVO_VGA_RENDER_CONTROL, vga_render_control); |
@@ -390,7 +390,10 @@ static bool legacy_read_disabled_bios(struct radeon_device *rdev) | |||
390 | 390 | ||
391 | seprom_cntl1 = RREG32(RADEON_SEPROM_CNTL1); | 391 | seprom_cntl1 = RREG32(RADEON_SEPROM_CNTL1); |
392 | viph_control = RREG32(RADEON_VIPH_CONTROL); | 392 | viph_control = RREG32(RADEON_VIPH_CONTROL); |
393 | bus_cntl = RREG32(RADEON_BUS_CNTL); | 393 | if (rdev->flags & RADEON_IS_PCIE) |
394 | bus_cntl = RREG32(RV370_BUS_CNTL); | ||
395 | else | ||
396 | bus_cntl = RREG32(RADEON_BUS_CNTL); | ||
394 | crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL); | 397 | crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL); |
395 | crtc2_gen_cntl = 0; | 398 | crtc2_gen_cntl = 0; |
396 | crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); | 399 | crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); |
@@ -412,7 +415,10 @@ static bool legacy_read_disabled_bios(struct radeon_device *rdev) | |||
412 | WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN)); | 415 | WREG32(RADEON_VIPH_CONTROL, (viph_control & ~RADEON_VIPH_EN)); |
413 | 416 | ||
414 | /* enable the rom */ | 417 | /* enable the rom */ |
415 | WREG32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM)); | 418 | if (rdev->flags & RADEON_IS_PCIE) |
419 | WREG32(RV370_BUS_CNTL, (bus_cntl & ~RV370_BUS_BIOS_DIS_ROM)); | ||
420 | else | ||
421 | WREG32(RADEON_BUS_CNTL, (bus_cntl & ~RADEON_BUS_BIOS_DIS_ROM)); | ||
416 | 422 | ||
417 | /* Turn off mem requests and CRTC for both controllers */ | 423 | /* Turn off mem requests and CRTC for both controllers */ |
418 | WREG32(RADEON_CRTC_GEN_CNTL, | 424 | WREG32(RADEON_CRTC_GEN_CNTL, |
@@ -439,7 +445,10 @@ static bool legacy_read_disabled_bios(struct radeon_device *rdev) | |||
439 | /* restore regs */ | 445 | /* restore regs */ |
440 | WREG32(RADEON_SEPROM_CNTL1, seprom_cntl1); | 446 | WREG32(RADEON_SEPROM_CNTL1, seprom_cntl1); |
441 | WREG32(RADEON_VIPH_CONTROL, viph_control); | 447 | WREG32(RADEON_VIPH_CONTROL, viph_control); |
442 | WREG32(RADEON_BUS_CNTL, bus_cntl); | 448 | if (rdev->flags & RADEON_IS_PCIE) |
449 | WREG32(RV370_BUS_CNTL, bus_cntl); | ||
450 | else | ||
451 | WREG32(RADEON_BUS_CNTL, bus_cntl); | ||
443 | WREG32(RADEON_CRTC_GEN_CNTL, crtc_gen_cntl); | 452 | WREG32(RADEON_CRTC_GEN_CNTL, crtc_gen_cntl); |
444 | if (!(rdev->flags & RADEON_SINGLE_CRTC)) { | 453 | if (!(rdev->flags & RADEON_SINGLE_CRTC)) { |
445 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); | 454 | WREG32(RADEON_CRTC2_GEN_CNTL, crtc2_gen_cntl); |
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index cbfca3a24fdf..9792d4ffdc86 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c | |||
@@ -52,6 +52,12 @@ void radeon_connector_hotplug(struct drm_connector *connector) | |||
52 | struct radeon_device *rdev = dev->dev_private; | 52 | struct radeon_device *rdev = dev->dev_private; |
53 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); | 53 | struct radeon_connector *radeon_connector = to_radeon_connector(connector); |
54 | 54 | ||
55 | /* bail if the connector does not have hpd pin, e.g., | ||
56 | * VGA, TV, etc. | ||
57 | */ | ||
58 | if (radeon_connector->hpd.hpd == RADEON_HPD_NONE) | ||
59 | return; | ||
60 | |||
55 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); | 61 | radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd); |
56 | 62 | ||
57 | /* powering up/down the eDP panel generates hpd events which | 63 | /* powering up/down the eDP panel generates hpd events which |
diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index ec93a75369e6..bc44a3d35ec6 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h | |||
@@ -300,6 +300,8 @@ | |||
300 | # define RADEON_BUS_READ_BURST (1 << 30) | 300 | # define RADEON_BUS_READ_BURST (1 << 30) |
301 | #define RADEON_BUS_CNTL1 0x0034 | 301 | #define RADEON_BUS_CNTL1 0x0034 |
302 | # define RADEON_BUS_WAIT_ON_LOCK_EN (1 << 4) | 302 | # define RADEON_BUS_WAIT_ON_LOCK_EN (1 << 4) |
303 | #define RV370_BUS_CNTL 0x004c | ||
304 | # define RV370_BUS_BIOS_DIS_ROM (1 << 2) | ||
303 | /* rv370/rv380, rv410, r423/r430/r480, r5xx */ | 305 | /* rv370/rv380, rv410, r423/r430/r480, r5xx */ |
304 | #define RADEON_MSI_REARM_EN 0x0160 | 306 | #define RADEON_MSI_REARM_EN 0x0160 |
305 | # define RV370_MSI_REARM_EN (1 << 0) | 307 | # define RV370_MSI_REARM_EN (1 << 0) |
diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 6e3b11e5abbe..1f5850e473cc 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c | |||
@@ -426,7 +426,7 @@ int rs600_gart_init(struct radeon_device *rdev) | |||
426 | return radeon_gart_table_vram_alloc(rdev); | 426 | return radeon_gart_table_vram_alloc(rdev); |
427 | } | 427 | } |
428 | 428 | ||
429 | int rs600_gart_enable(struct radeon_device *rdev) | 429 | static int rs600_gart_enable(struct radeon_device *rdev) |
430 | { | 430 | { |
431 | u32 tmp; | 431 | u32 tmp; |
432 | int r, i; | 432 | int r, i; |
@@ -440,8 +440,8 @@ int rs600_gart_enable(struct radeon_device *rdev) | |||
440 | return r; | 440 | return r; |
441 | radeon_gart_restore(rdev); | 441 | radeon_gart_restore(rdev); |
442 | /* Enable bus master */ | 442 | /* Enable bus master */ |
443 | tmp = RREG32(R_00004C_BUS_CNTL) & C_00004C_BUS_MASTER_DIS; | 443 | tmp = RREG32(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS; |
444 | WREG32(R_00004C_BUS_CNTL, tmp); | 444 | WREG32(RADEON_BUS_CNTL, tmp); |
445 | /* FIXME: setup default page */ | 445 | /* FIXME: setup default page */ |
446 | WREG32_MC(R_000100_MC_PT0_CNTL, | 446 | WREG32_MC(R_000100_MC_PT0_CNTL, |
447 | (S_000100_EFFECTIVE_L2_CACHE_SIZE(6) | | 447 | (S_000100_EFFECTIVE_L2_CACHE_SIZE(6) | |
diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 8bb347d23ca6..4de51891aa6d 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c | |||
@@ -1368,6 +1368,7 @@ void rv770_fini(struct radeon_device *rdev) | |||
1368 | r700_cp_fini(rdev); | 1368 | r700_cp_fini(rdev); |
1369 | r600_irq_fini(rdev); | 1369 | r600_irq_fini(rdev); |
1370 | radeon_wb_fini(rdev); | 1370 | radeon_wb_fini(rdev); |
1371 | radeon_ib_pool_fini(rdev); | ||
1371 | radeon_irq_kms_fini(rdev); | 1372 | radeon_irq_kms_fini(rdev); |
1372 | rv770_pcie_gart_fini(rdev); | 1373 | rv770_pcie_gart_fini(rdev); |
1373 | rv770_vram_scratch_fini(rdev); | 1374 | rv770_vram_scratch_fini(rdev); |
diff --git a/drivers/hwmon/adm1275.c b/drivers/hwmon/adm1275.c index b9b7caf4a1d2..8bc1bd663721 100644 --- a/drivers/hwmon/adm1275.c +++ b/drivers/hwmon/adm1275.c | |||
@@ -53,23 +53,23 @@ static int adm1275_probe(struct i2c_client *client, | |||
53 | info->direct[PSC_VOLTAGE_IN] = true; | 53 | info->direct[PSC_VOLTAGE_IN] = true; |
54 | info->direct[PSC_VOLTAGE_OUT] = true; | 54 | info->direct[PSC_VOLTAGE_OUT] = true; |
55 | info->direct[PSC_CURRENT_OUT] = true; | 55 | info->direct[PSC_CURRENT_OUT] = true; |
56 | info->m[PSC_CURRENT_OUT] = 800; | 56 | info->m[PSC_CURRENT_OUT] = 807; |
57 | info->b[PSC_CURRENT_OUT] = 20475; | 57 | info->b[PSC_CURRENT_OUT] = 20475; |
58 | info->R[PSC_CURRENT_OUT] = -1; | 58 | info->R[PSC_CURRENT_OUT] = -1; |
59 | info->func[0] = PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT; | 59 | info->func[0] = PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT; |
60 | 60 | ||
61 | if (config & ADM1275_VRANGE) { | 61 | if (config & ADM1275_VRANGE) { |
62 | info->m[PSC_VOLTAGE_IN] = 19045; | 62 | info->m[PSC_VOLTAGE_IN] = 19199; |
63 | info->b[PSC_VOLTAGE_IN] = 0; | 63 | info->b[PSC_VOLTAGE_IN] = 0; |
64 | info->R[PSC_VOLTAGE_IN] = -2; | 64 | info->R[PSC_VOLTAGE_IN] = -2; |
65 | info->m[PSC_VOLTAGE_OUT] = 19045; | 65 | info->m[PSC_VOLTAGE_OUT] = 19199; |
66 | info->b[PSC_VOLTAGE_OUT] = 0; | 66 | info->b[PSC_VOLTAGE_OUT] = 0; |
67 | info->R[PSC_VOLTAGE_OUT] = -2; | 67 | info->R[PSC_VOLTAGE_OUT] = -2; |
68 | } else { | 68 | } else { |
69 | info->m[PSC_VOLTAGE_IN] = 6666; | 69 | info->m[PSC_VOLTAGE_IN] = 6720; |
70 | info->b[PSC_VOLTAGE_IN] = 0; | 70 | info->b[PSC_VOLTAGE_IN] = 0; |
71 | info->R[PSC_VOLTAGE_IN] = -1; | 71 | info->R[PSC_VOLTAGE_IN] = -1; |
72 | info->m[PSC_VOLTAGE_OUT] = 6666; | 72 | info->m[PSC_VOLTAGE_OUT] = 6720; |
73 | info->b[PSC_VOLTAGE_OUT] = 0; | 73 | info->b[PSC_VOLTAGE_OUT] = 0; |
74 | info->R[PSC_VOLTAGE_OUT] = -1; | 74 | info->R[PSC_VOLTAGE_OUT] = -1; |
75 | } | 75 | } |
diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index dcb78a7a8047..00e98517f94c 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c | |||
@@ -674,6 +674,7 @@ static int atk_debugfs_gitm_get(void *p, u64 *val) | |||
674 | else | 674 | else |
675 | err = -EIO; | 675 | err = -EIO; |
676 | 676 | ||
677 | ACPI_FREE(ret); | ||
677 | return err; | 678 | return err; |
678 | } | 679 | } |
679 | 680 | ||
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index bb6405b92007..5f5247750430 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -1538,7 +1538,7 @@ static struct attribute *it87_attributes_label[] = { | |||
1538 | }; | 1538 | }; |
1539 | 1539 | ||
1540 | static const struct attribute_group it87_group_label = { | 1540 | static const struct attribute_group it87_group_label = { |
1541 | .attrs = it87_attributes_vid, | 1541 | .attrs = it87_attributes_label, |
1542 | }; | 1542 | }; |
1543 | 1543 | ||
1544 | /* SuperIO detection - will change isa_address if a chip is found */ | 1544 | /* SuperIO detection - will change isa_address if a chip is found */ |
diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c index 1a6dfb6df1e7..d3b464b74ced 100644 --- a/drivers/hwmon/lm95241.c +++ b/drivers/hwmon/lm95241.c | |||
@@ -98,11 +98,16 @@ struct lm95241_data { | |||
98 | }; | 98 | }; |
99 | 99 | ||
100 | /* Conversions */ | 100 | /* Conversions */ |
101 | static int TempFromReg(u8 val_h, u8 val_l) | 101 | static int temp_from_reg_signed(u8 val_h, u8 val_l) |
102 | { | 102 | { |
103 | if (val_h & 0x80) | 103 | s16 val_hl = (val_h << 8) | val_l; |
104 | return val_h - 0x100; | 104 | return val_hl * 1000 / 256; |
105 | return val_h * 1000 + val_l * 1000 / 256; | 105 | } |
106 | |||
107 | static int temp_from_reg_unsigned(u8 val_h, u8 val_l) | ||
108 | { | ||
109 | u16 val_hl = (val_h << 8) | val_l; | ||
110 | return val_hl * 1000 / 256; | ||
106 | } | 111 | } |
107 | 112 | ||
108 | static struct lm95241_data *lm95241_update_device(struct device *dev) | 113 | static struct lm95241_data *lm95241_update_device(struct device *dev) |
@@ -135,10 +140,13 @@ static ssize_t show_input(struct device *dev, struct device_attribute *attr, | |||
135 | char *buf) | 140 | char *buf) |
136 | { | 141 | { |
137 | struct lm95241_data *data = lm95241_update_device(dev); | 142 | struct lm95241_data *data = lm95241_update_device(dev); |
143 | int index = to_sensor_dev_attr(attr)->index; | ||
138 | 144 | ||
139 | return snprintf(buf, PAGE_SIZE - 1, "%d\n", | 145 | return snprintf(buf, PAGE_SIZE - 1, "%d\n", |
140 | TempFromReg(data->temp[to_sensor_dev_attr(attr)->index], | 146 | index == 0 || (data->config & (1 << (index / 2))) ? |
141 | data->temp[to_sensor_dev_attr(attr)->index + 1])); | 147 | temp_from_reg_signed(data->temp[index], data->temp[index + 1]) : |
148 | temp_from_reg_unsigned(data->temp[index], | ||
149 | data->temp[index + 1])); | ||
142 | } | 150 | } |
143 | 151 | ||
144 | static ssize_t show_type(struct device *dev, struct device_attribute *attr, | 152 | static ssize_t show_type(struct device *dev, struct device_attribute *attr, |
@@ -339,7 +347,7 @@ static int lm95241_detect(struct i2c_client *new_client, | |||
339 | if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID) | 347 | if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID) |
340 | == MANUFACTURER_ID) | 348 | == MANUFACTURER_ID) |
341 | && (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID) | 349 | && (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID) |
342 | >= DEFAULT_REVISION)) { | 350 | == DEFAULT_REVISION)) { |
343 | name = DEVNAME; | 351 | name = DEVNAME; |
344 | } else { | 352 | } else { |
345 | dev_dbg(&adapter->dev, "LM95241 detection failed at 0x%02x\n", | 353 | dev_dbg(&adapter->dev, "LM95241 detection failed at 0x%02x\n", |
diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c index 12a54aa29776..14335bbc9bdc 100644 --- a/drivers/hwmon/max1111.c +++ b/drivers/hwmon/max1111.c | |||
@@ -40,6 +40,8 @@ struct max1111_data { | |||
40 | struct spi_transfer xfer[2]; | 40 | struct spi_transfer xfer[2]; |
41 | uint8_t *tx_buf; | 41 | uint8_t *tx_buf; |
42 | uint8_t *rx_buf; | 42 | uint8_t *rx_buf; |
43 | struct mutex drvdata_lock; | ||
44 | /* protect msg, xfer and buffers from multiple access */ | ||
43 | }; | 45 | }; |
44 | 46 | ||
45 | static int max1111_read(struct device *dev, int channel) | 47 | static int max1111_read(struct device *dev, int channel) |
@@ -48,6 +50,9 @@ static int max1111_read(struct device *dev, int channel) | |||
48 | uint8_t v1, v2; | 50 | uint8_t v1, v2; |
49 | int err; | 51 | int err; |
50 | 52 | ||
53 | /* writing to drvdata struct is not thread safe, wait on mutex */ | ||
54 | mutex_lock(&data->drvdata_lock); | ||
55 | |||
51 | data->tx_buf[0] = (channel << MAX1111_CTRL_SEL_SH) | | 56 | data->tx_buf[0] = (channel << MAX1111_CTRL_SEL_SH) | |
52 | MAX1111_CTRL_PD0 | MAX1111_CTRL_PD1 | | 57 | MAX1111_CTRL_PD0 | MAX1111_CTRL_PD1 | |
53 | MAX1111_CTRL_SGL | MAX1111_CTRL_UNI | MAX1111_CTRL_STR; | 58 | MAX1111_CTRL_SGL | MAX1111_CTRL_UNI | MAX1111_CTRL_STR; |
@@ -55,12 +60,15 @@ static int max1111_read(struct device *dev, int channel) | |||
55 | err = spi_sync(data->spi, &data->msg); | 60 | err = spi_sync(data->spi, &data->msg); |
56 | if (err < 0) { | 61 | if (err < 0) { |
57 | dev_err(dev, "spi_sync failed with %d\n", err); | 62 | dev_err(dev, "spi_sync failed with %d\n", err); |
63 | mutex_unlock(&data->drvdata_lock); | ||
58 | return err; | 64 | return err; |
59 | } | 65 | } |
60 | 66 | ||
61 | v1 = data->rx_buf[0]; | 67 | v1 = data->rx_buf[0]; |
62 | v2 = data->rx_buf[1]; | 68 | v2 = data->rx_buf[1]; |
63 | 69 | ||
70 | mutex_unlock(&data->drvdata_lock); | ||
71 | |||
64 | if ((v1 & 0xc0) || (v2 & 0x3f)) | 72 | if ((v1 & 0xc0) || (v2 & 0x3f)) |
65 | return -EINVAL; | 73 | return -EINVAL; |
66 | 74 | ||
@@ -176,6 +184,8 @@ static int __devinit max1111_probe(struct spi_device *spi) | |||
176 | if (err) | 184 | if (err) |
177 | goto err_free_data; | 185 | goto err_free_data; |
178 | 186 | ||
187 | mutex_init(&data->drvdata_lock); | ||
188 | |||
179 | data->spi = spi; | 189 | data->spi = spi; |
180 | spi_set_drvdata(spi, data); | 190 | spi_set_drvdata(spi, data); |
181 | 191 | ||
@@ -213,6 +223,7 @@ static int __devexit max1111_remove(struct spi_device *spi) | |||
213 | 223 | ||
214 | hwmon_device_unregister(data->hwmon_dev); | 224 | hwmon_device_unregister(data->hwmon_dev); |
215 | sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group); | 225 | sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group); |
226 | mutex_destroy(&data->drvdata_lock); | ||
216 | kfree(data->rx_buf); | 227 | kfree(data->rx_buf); |
217 | kfree(data->tx_buf); | 228 | kfree(data->tx_buf); |
218 | kfree(data); | 229 | kfree(data); |
diff --git a/drivers/hwmon/pmbus.c b/drivers/hwmon/pmbus.c index 931d940923ae..9b1f0c37ef77 100644 --- a/drivers/hwmon/pmbus.c +++ b/drivers/hwmon/pmbus.c | |||
@@ -59,16 +59,17 @@ static void pmbus_find_sensor_groups(struct i2c_client *client, | |||
59 | if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_34)) | 59 | if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_34)) |
60 | info->func[0] |= PMBUS_HAVE_STATUS_FAN34; | 60 | info->func[0] |= PMBUS_HAVE_STATUS_FAN34; |
61 | } | 61 | } |
62 | if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1)) { | 62 | if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1)) |
63 | info->func[0] |= PMBUS_HAVE_TEMP; | 63 | info->func[0] |= PMBUS_HAVE_TEMP; |
64 | if (pmbus_check_byte_register(client, 0, | ||
65 | PMBUS_STATUS_TEMPERATURE)) | ||
66 | info->func[0] |= PMBUS_HAVE_STATUS_TEMP; | ||
67 | } | ||
68 | if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_2)) | 64 | if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_2)) |
69 | info->func[0] |= PMBUS_HAVE_TEMP2; | 65 | info->func[0] |= PMBUS_HAVE_TEMP2; |
70 | if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_3)) | 66 | if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_3)) |
71 | info->func[0] |= PMBUS_HAVE_TEMP3; | 67 | info->func[0] |= PMBUS_HAVE_TEMP3; |
68 | if (info->func[0] & (PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2 | ||
69 | | PMBUS_HAVE_TEMP3) | ||
70 | && pmbus_check_byte_register(client, 0, | ||
71 | PMBUS_STATUS_TEMPERATURE)) | ||
72 | info->func[0] |= PMBUS_HAVE_STATUS_TEMP; | ||
72 | 73 | ||
73 | /* Sensors detected on all pages */ | 74 | /* Sensors detected on all pages */ |
74 | for (page = 0; page < info->pages; page++) { | 75 | for (page = 0; page < info->pages; page++) { |
diff --git a/drivers/hwmon/pmbus_core.c b/drivers/hwmon/pmbus_core.c index 744672c1f26d..8e31a8e2c746 100644 --- a/drivers/hwmon/pmbus_core.c +++ b/drivers/hwmon/pmbus_core.c | |||
@@ -362,8 +362,8 @@ static struct pmbus_data *pmbus_update_device(struct device *dev) | |||
362 | * Convert linear sensor values to milli- or micro-units | 362 | * Convert linear sensor values to milli- or micro-units |
363 | * depending on sensor type. | 363 | * depending on sensor type. |
364 | */ | 364 | */ |
365 | static int pmbus_reg2data_linear(struct pmbus_data *data, | 365 | static long pmbus_reg2data_linear(struct pmbus_data *data, |
366 | struct pmbus_sensor *sensor) | 366 | struct pmbus_sensor *sensor) |
367 | { | 367 | { |
368 | s16 exponent; | 368 | s16 exponent; |
369 | s32 mantissa; | 369 | s32 mantissa; |
@@ -397,15 +397,15 @@ static int pmbus_reg2data_linear(struct pmbus_data *data, | |||
397 | else | 397 | else |
398 | val >>= -exponent; | 398 | val >>= -exponent; |
399 | 399 | ||
400 | return (int)val; | 400 | return val; |
401 | } | 401 | } |
402 | 402 | ||
403 | /* | 403 | /* |
404 | * Convert direct sensor values to milli- or micro-units | 404 | * Convert direct sensor values to milli- or micro-units |
405 | * depending on sensor type. | 405 | * depending on sensor type. |
406 | */ | 406 | */ |
407 | static int pmbus_reg2data_direct(struct pmbus_data *data, | 407 | static long pmbus_reg2data_direct(struct pmbus_data *data, |
408 | struct pmbus_sensor *sensor) | 408 | struct pmbus_sensor *sensor) |
409 | { | 409 | { |
410 | long val = (s16) sensor->data; | 410 | long val = (s16) sensor->data; |
411 | long m, b, R; | 411 | long m, b, R; |
@@ -440,12 +440,12 @@ static int pmbus_reg2data_direct(struct pmbus_data *data, | |||
440 | R++; | 440 | R++; |
441 | } | 441 | } |
442 | 442 | ||
443 | return (int)((val - b) / m); | 443 | return (val - b) / m; |
444 | } | 444 | } |
445 | 445 | ||
446 | static int pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor) | 446 | static long pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor) |
447 | { | 447 | { |
448 | int val; | 448 | long val; |
449 | 449 | ||
450 | if (data->info->direct[sensor->class]) | 450 | if (data->info->direct[sensor->class]) |
451 | val = pmbus_reg2data_direct(data, sensor); | 451 | val = pmbus_reg2data_direct(data, sensor); |
@@ -619,7 +619,7 @@ static int pmbus_get_boolean(struct pmbus_data *data, int index, int *val) | |||
619 | if (!s1 && !s2) | 619 | if (!s1 && !s2) |
620 | *val = !!regval; | 620 | *val = !!regval; |
621 | else { | 621 | else { |
622 | int v1, v2; | 622 | long v1, v2; |
623 | struct pmbus_sensor *sensor1, *sensor2; | 623 | struct pmbus_sensor *sensor1, *sensor2; |
624 | 624 | ||
625 | sensor1 = &data->sensors[s1]; | 625 | sensor1 = &data->sensors[s1]; |
@@ -661,7 +661,7 @@ static ssize_t pmbus_show_sensor(struct device *dev, | |||
661 | if (sensor->data < 0) | 661 | if (sensor->data < 0) |
662 | return sensor->data; | 662 | return sensor->data; |
663 | 663 | ||
664 | return snprintf(buf, PAGE_SIZE, "%d\n", pmbus_reg2data(data, sensor)); | 664 | return snprintf(buf, PAGE_SIZE, "%ld\n", pmbus_reg2data(data, sensor)); |
665 | } | 665 | } |
666 | 666 | ||
667 | static ssize_t pmbus_set_sensor(struct device *dev, | 667 | static ssize_t pmbus_set_sensor(struct device *dev, |
diff --git a/drivers/i2c/busses/i2c-bfin-twi.c b/drivers/i2c/busses/i2c-bfin-twi.c index 52b545a795f2..cbc98aea5b09 100644 --- a/drivers/i2c/busses/i2c-bfin-twi.c +++ b/drivers/i2c/busses/i2c-bfin-twi.c | |||
@@ -193,7 +193,13 @@ static void bfin_twi_handle_interrupt(struct bfin_twi_iface *iface, | |||
193 | return; | 193 | return; |
194 | } | 194 | } |
195 | if (twi_int_status & MCOMP) { | 195 | if (twi_int_status & MCOMP) { |
196 | if (iface->cur_mode == TWI_I2C_MODE_COMBINED) { | 196 | if ((read_MASTER_CTL(iface) & MEN) == 0 && |
197 | (iface->cur_mode == TWI_I2C_MODE_REPEAT || | ||
198 | iface->cur_mode == TWI_I2C_MODE_COMBINED)) { | ||
199 | iface->result = -1; | ||
200 | write_INT_MASK(iface, 0); | ||
201 | write_MASTER_CTL(iface, 0); | ||
202 | } else if (iface->cur_mode == TWI_I2C_MODE_COMBINED) { | ||
197 | if (iface->readNum == 0) { | 203 | if (iface->readNum == 0) { |
198 | /* set the read number to 1 and ask for manual | 204 | /* set the read number to 1 and ask for manual |
199 | * stop in block combine mode | 205 | * stop in block combine mode |
diff --git a/drivers/i2c/busses/i2c-s3c2410.c b/drivers/i2c/busses/i2c-s3c2410.c index 6c00c107ebf3..f84a63c6dd97 100644 --- a/drivers/i2c/busses/i2c-s3c2410.c +++ b/drivers/i2c/busses/i2c-s3c2410.c | |||
@@ -248,12 +248,12 @@ static inline int is_msgend(struct s3c24xx_i2c *i2c) | |||
248 | return i2c->msg_ptr >= i2c->msg->len; | 248 | return i2c->msg_ptr >= i2c->msg->len; |
249 | } | 249 | } |
250 | 250 | ||
251 | /* i2s_s3c_irq_nextbyte | 251 | /* i2c_s3c_irq_nextbyte |
252 | * | 252 | * |
253 | * process an interrupt and work out what to do | 253 | * process an interrupt and work out what to do |
254 | */ | 254 | */ |
255 | 255 | ||
256 | static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat) | 256 | static int i2c_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat) |
257 | { | 257 | { |
258 | unsigned long tmp; | 258 | unsigned long tmp; |
259 | unsigned char byte; | 259 | unsigned char byte; |
@@ -264,7 +264,6 @@ static int i2s_s3c_irq_nextbyte(struct s3c24xx_i2c *i2c, unsigned long iicstat) | |||
264 | case STATE_IDLE: | 264 | case STATE_IDLE: |
265 | dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __func__); | 265 | dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __func__); |
266 | goto out; | 266 | goto out; |
267 | break; | ||
268 | 267 | ||
269 | case STATE_STOP: | 268 | case STATE_STOP: |
270 | dev_err(i2c->dev, "%s: called in STATE_STOP\n", __func__); | 269 | dev_err(i2c->dev, "%s: called in STATE_STOP\n", __func__); |
@@ -444,7 +443,7 @@ static irqreturn_t s3c24xx_i2c_irq(int irqno, void *dev_id) | |||
444 | /* pretty much this leaves us with the fact that we've | 443 | /* pretty much this leaves us with the fact that we've |
445 | * transmitted or received whatever byte we last sent */ | 444 | * transmitted or received whatever byte we last sent */ |
446 | 445 | ||
447 | i2s_s3c_irq_nextbyte(i2c, status); | 446 | i2c_s3c_irq_nextbyte(i2c, status); |
448 | 447 | ||
449 | out: | 448 | out: |
450 | return IRQ_HANDLED; | 449 | return IRQ_HANDLED; |
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 4d9319665e32..fb3b4f8f8152 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c | |||
@@ -40,8 +40,10 @@ | |||
40 | #define I2C_CNFG_NEW_MASTER_FSM (1<<11) | 40 | #define I2C_CNFG_NEW_MASTER_FSM (1<<11) |
41 | #define I2C_STATUS 0x01C | 41 | #define I2C_STATUS 0x01C |
42 | #define I2C_SL_CNFG 0x020 | 42 | #define I2C_SL_CNFG 0x020 |
43 | #define I2C_SL_CNFG_NACK (1<<1) | ||
43 | #define I2C_SL_CNFG_NEWSL (1<<2) | 44 | #define I2C_SL_CNFG_NEWSL (1<<2) |
44 | #define I2C_SL_ADDR1 0x02c | 45 | #define I2C_SL_ADDR1 0x02c |
46 | #define I2C_SL_ADDR2 0x030 | ||
45 | #define I2C_TX_FIFO 0x050 | 47 | #define I2C_TX_FIFO 0x050 |
46 | #define I2C_RX_FIFO 0x054 | 48 | #define I2C_RX_FIFO 0x054 |
47 | #define I2C_PACKET_TRANSFER_STATUS 0x058 | 49 | #define I2C_PACKET_TRANSFER_STATUS 0x058 |
@@ -337,7 +339,11 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev) | |||
337 | 339 | ||
338 | if (!i2c_dev->is_dvc) { | 340 | if (!i2c_dev->is_dvc) { |
339 | u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG); | 341 | u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG); |
340 | i2c_writel(i2c_dev, sl_cfg | I2C_SL_CNFG_NEWSL, I2C_SL_CNFG); | 342 | sl_cfg |= I2C_SL_CNFG_NACK | I2C_SL_CNFG_NEWSL; |
343 | i2c_writel(i2c_dev, sl_cfg, I2C_SL_CNFG); | ||
344 | i2c_writel(i2c_dev, 0xfc, I2C_SL_ADDR1); | ||
345 | i2c_writel(i2c_dev, 0x00, I2C_SL_ADDR2); | ||
346 | |||
341 | } | 347 | } |
342 | 348 | ||
343 | val = 7 << I2C_FIFO_CONTROL_TX_TRIG_SHIFT | | 349 | val = 7 << I2C_FIFO_CONTROL_TX_TRIG_SHIFT | |
diff --git a/drivers/input/keyboard/pmic8xxx-keypad.c b/drivers/input/keyboard/pmic8xxx-keypad.c index 40b02ae96f86..6229c3e8e78b 100644 --- a/drivers/input/keyboard/pmic8xxx-keypad.c +++ b/drivers/input/keyboard/pmic8xxx-keypad.c | |||
@@ -520,7 +520,8 @@ static void pmic8xxx_kp_close(struct input_dev *dev) | |||
520 | */ | 520 | */ |
521 | static int __devinit pmic8xxx_kp_probe(struct platform_device *pdev) | 521 | static int __devinit pmic8xxx_kp_probe(struct platform_device *pdev) |
522 | { | 522 | { |
523 | const struct pm8xxx_keypad_platform_data *pdata = mfd_get_data(pdev); | 523 | const struct pm8xxx_keypad_platform_data *pdata = |
524 | dev_get_platdata(&pdev->dev); | ||
524 | const struct matrix_keymap_data *keymap_data; | 525 | const struct matrix_keymap_data *keymap_data; |
525 | struct pmic8xxx_kp *kp; | 526 | struct pmic8xxx_kp *kp; |
526 | int rc; | 527 | int rc; |
diff --git a/drivers/input/misc/pmic8xxx-pwrkey.c b/drivers/input/misc/pmic8xxx-pwrkey.c index 97e07e786e41..b3cfb9c71e66 100644 --- a/drivers/input/misc/pmic8xxx-pwrkey.c +++ b/drivers/input/misc/pmic8xxx-pwrkey.c | |||
@@ -90,7 +90,8 @@ static int __devinit pmic8xxx_pwrkey_probe(struct platform_device *pdev) | |||
90 | unsigned int delay; | 90 | unsigned int delay; |
91 | u8 pon_cntl; | 91 | u8 pon_cntl; |
92 | struct pmic8xxx_pwrkey *pwrkey; | 92 | struct pmic8xxx_pwrkey *pwrkey; |
93 | const struct pm8xxx_pwrkey_platform_data *pdata = mfd_get_data(pdev); | 93 | const struct pm8xxx_pwrkey_platform_data *pdata = |
94 | dev_get_platdata(&pdev->dev); | ||
94 | 95 | ||
95 | if (!pdata) { | 96 | if (!pdata) { |
96 | dev_err(&pdev->dev, "power key platform data not supplied\n"); | 97 | dev_err(&pdev->dev, "power key platform data not supplied\n"); |
diff --git a/drivers/leds/leds-pca9532.c b/drivers/leds/leds-pca9532.c index d8d3a1e910a1..a2c874623e35 100644 --- a/drivers/leds/leds-pca9532.c +++ b/drivers/leds/leds-pca9532.c | |||
@@ -88,7 +88,7 @@ static const struct pca9532_chip_info pca9532_chip_info_tbl[] = { | |||
88 | 88 | ||
89 | static struct i2c_driver pca9532_driver = { | 89 | static struct i2c_driver pca9532_driver = { |
90 | .driver = { | 90 | .driver = { |
91 | .name = "pca953x", | 91 | .name = "leds-pca953x", |
92 | }, | 92 | }, |
93 | .probe = pca9532_probe, | 93 | .probe = pca9532_probe, |
94 | .remove = pca9532_remove, | 94 | .remove = pca9532_remove, |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 98278041d75f..5b6b451d4694 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
@@ -1988,6 +1988,14 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) | |||
1988 | if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) { | 1988 | if (dvbdev->users == -1 && fe->ops.ts_bus_ctrl) { |
1989 | if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0) | 1989 | if ((ret = fe->ops.ts_bus_ctrl(fe, 1)) < 0) |
1990 | goto err0; | 1990 | goto err0; |
1991 | |||
1992 | /* If we took control of the bus, we need to force | ||
1993 | reinitialization. This is because many ts_bus_ctrl() | ||
1994 | functions strobe the RESET pin on the demod, and if the | ||
1995 | frontend thread already exists then the dvb_init() routine | ||
1996 | won't get called (which is what usually does initial | ||
1997 | register configuration). */ | ||
1998 | fepriv->reinitialise = 1; | ||
1991 | } | 1999 | } |
1992 | 2000 | ||
1993 | if ((ret = dvb_generic_open (inode, file)) < 0) | 2001 | if ((ret = dvb_generic_open (inode, file)) < 0) |
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index e4c97fd6f05a..52798a111e16 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig | |||
@@ -168,7 +168,7 @@ config RADIO_MAXIRADIO | |||
168 | 168 | ||
169 | config RADIO_MIROPCM20 | 169 | config RADIO_MIROPCM20 |
170 | tristate "miroSOUND PCM20 radio" | 170 | tristate "miroSOUND PCM20 radio" |
171 | depends on ISA && VIDEO_V4L2 && SND | 171 | depends on ISA && ISA_DMA_API && VIDEO_V4L2 && SND |
172 | select SND_ISA | 172 | select SND_ISA |
173 | select SND_MIRO | 173 | select SND_MIRO |
174 | ---help--- | 174 | ---help--- |
@@ -201,7 +201,7 @@ config RADIO_SF16FMI | |||
201 | 201 | ||
202 | config RADIO_SF16FMR2 | 202 | config RADIO_SF16FMR2 |
203 | tristate "SF16FMR2 Radio" | 203 | tristate "SF16FMR2 Radio" |
204 | depends on ISA && VIDEO_V4L2 | 204 | depends on ISA && VIDEO_V4L2 && SND |
205 | ---help--- | 205 | ---help--- |
206 | Choose Y here if you have one of these FM radio cards. | 206 | Choose Y here if you have one of these FM radio cards. |
207 | 207 | ||
diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c index deca2e06ff22..c9f4a8e65dc4 100644 --- a/drivers/media/radio/si4713-i2c.c +++ b/drivers/media/radio/si4713-i2c.c | |||
@@ -1033,7 +1033,7 @@ static int si4713_write_econtrol_string(struct si4713_device *sdev, | |||
1033 | char ps_name[MAX_RDS_PS_NAME + 1]; | 1033 | char ps_name[MAX_RDS_PS_NAME + 1]; |
1034 | 1034 | ||
1035 | len = control->size - 1; | 1035 | len = control->size - 1; |
1036 | if (len > MAX_RDS_PS_NAME) { | 1036 | if (len < 0 || len > MAX_RDS_PS_NAME) { |
1037 | rval = -ERANGE; | 1037 | rval = -ERANGE; |
1038 | goto exit; | 1038 | goto exit; |
1039 | } | 1039 | } |
@@ -1057,7 +1057,7 @@ static int si4713_write_econtrol_string(struct si4713_device *sdev, | |||
1057 | char radio_text[MAX_RDS_RADIO_TEXT + 1]; | 1057 | char radio_text[MAX_RDS_RADIO_TEXT + 1]; |
1058 | 1058 | ||
1059 | len = control->size - 1; | 1059 | len = control->size - 1; |
1060 | if (len > MAX_RDS_RADIO_TEXT) { | 1060 | if (len < 0 || len > MAX_RDS_RADIO_TEXT) { |
1061 | rval = -ERANGE; | 1061 | rval = -ERANGE; |
1062 | goto exit; | 1062 | goto exit; |
1063 | } | 1063 | } |
diff --git a/drivers/media/rc/fintek-cir.c b/drivers/media/rc/fintek-cir.c index 8fa539dde1b4..7f7079b12f23 100644 --- a/drivers/media/rc/fintek-cir.c +++ b/drivers/media/rc/fintek-cir.c | |||
@@ -597,12 +597,17 @@ static void __devexit fintek_remove(struct pnp_dev *pdev) | |||
597 | static int fintek_suspend(struct pnp_dev *pdev, pm_message_t state) | 597 | static int fintek_suspend(struct pnp_dev *pdev, pm_message_t state) |
598 | { | 598 | { |
599 | struct fintek_dev *fintek = pnp_get_drvdata(pdev); | 599 | struct fintek_dev *fintek = pnp_get_drvdata(pdev); |
600 | unsigned long flags; | ||
600 | 601 | ||
601 | fit_dbg("%s called", __func__); | 602 | fit_dbg("%s called", __func__); |
602 | 603 | ||
604 | spin_lock_irqsave(&fintek->fintek_lock, flags); | ||
605 | |||
603 | /* disable all CIR interrupts */ | 606 | /* disable all CIR interrupts */ |
604 | fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_MASK, CIR_STATUS); | 607 | fintek_cir_reg_write(fintek, CIR_STATUS_IRQ_MASK, CIR_STATUS); |
605 | 608 | ||
609 | spin_unlock_irqrestore(&fintek->fintek_lock, flags); | ||
610 | |||
606 | fintek_config_mode_enable(fintek); | 611 | fintek_config_mode_enable(fintek); |
607 | 612 | ||
608 | /* disable cir logical dev */ | 613 | /* disable cir logical dev */ |
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index 3f3c70716268..6bc35eeb653b 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c | |||
@@ -307,6 +307,14 @@ static const struct { | |||
307 | /* 0xffdc iMON MCE VFD */ | 307 | /* 0xffdc iMON MCE VFD */ |
308 | { 0x00010000ffffffeell, KEY_VOLUMEUP }, | 308 | { 0x00010000ffffffeell, KEY_VOLUMEUP }, |
309 | { 0x01000000ffffffeell, KEY_VOLUMEDOWN }, | 309 | { 0x01000000ffffffeell, KEY_VOLUMEDOWN }, |
310 | { 0x00000001ffffffeell, KEY_MUTE }, | ||
311 | { 0x0000000fffffffeell, KEY_MEDIA }, | ||
312 | { 0x00000012ffffffeell, KEY_UP }, | ||
313 | { 0x00000013ffffffeell, KEY_DOWN }, | ||
314 | { 0x00000014ffffffeell, KEY_LEFT }, | ||
315 | { 0x00000015ffffffeell, KEY_RIGHT }, | ||
316 | { 0x00000016ffffffeell, KEY_ENTER }, | ||
317 | { 0x00000017ffffffeell, KEY_ESC }, | ||
310 | /* iMON Knob values */ | 318 | /* iMON Knob values */ |
311 | { 0x000100ffffffffeell, KEY_VOLUMEUP }, | 319 | { 0x000100ffffffffeell, KEY_VOLUMEUP }, |
312 | { 0x010000ffffffffeell, KEY_VOLUMEDOWN }, | 320 | { 0x010000ffffffffeell, KEY_VOLUMEDOWN }, |
@@ -1582,16 +1590,16 @@ static void imon_incoming_packet(struct imon_context *ictx, | |||
1582 | /* Only panel type events left to process now */ | 1590 | /* Only panel type events left to process now */ |
1583 | spin_lock_irqsave(&ictx->kc_lock, flags); | 1591 | spin_lock_irqsave(&ictx->kc_lock, flags); |
1584 | 1592 | ||
1593 | do_gettimeofday(&t); | ||
1585 | /* KEY_MUTE repeats from knob need to be suppressed */ | 1594 | /* KEY_MUTE repeats from knob need to be suppressed */ |
1586 | if (ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode) { | 1595 | if (ictx->kc == KEY_MUTE && ictx->kc == ictx->last_keycode) { |
1587 | do_gettimeofday(&t); | ||
1588 | msec = tv2int(&t, &prev_time); | 1596 | msec = tv2int(&t, &prev_time); |
1589 | prev_time = t; | ||
1590 | if (msec < ictx->idev->rep[REP_DELAY]) { | 1597 | if (msec < ictx->idev->rep[REP_DELAY]) { |
1591 | spin_unlock_irqrestore(&ictx->kc_lock, flags); | 1598 | spin_unlock_irqrestore(&ictx->kc_lock, flags); |
1592 | return; | 1599 | return; |
1593 | } | 1600 | } |
1594 | } | 1601 | } |
1602 | prev_time = t; | ||
1595 | kc = ictx->kc; | 1603 | kc = ictx->kc; |
1596 | 1604 | ||
1597 | spin_unlock_irqrestore(&ictx->kc_lock, flags); | 1605 | spin_unlock_irqrestore(&ictx->kc_lock, flags); |
@@ -1603,7 +1611,9 @@ static void imon_incoming_packet(struct imon_context *ictx, | |||
1603 | input_report_key(ictx->idev, kc, 0); | 1611 | input_report_key(ictx->idev, kc, 0); |
1604 | input_sync(ictx->idev); | 1612 | input_sync(ictx->idev); |
1605 | 1613 | ||
1614 | spin_lock_irqsave(&ictx->kc_lock, flags); | ||
1606 | ictx->last_keycode = kc; | 1615 | ictx->last_keycode = kc; |
1616 | spin_unlock_irqrestore(&ictx->kc_lock, flags); | ||
1607 | 1617 | ||
1608 | return; | 1618 | return; |
1609 | 1619 | ||
@@ -1740,6 +1750,8 @@ static void imon_get_ffdc_type(struct imon_context *ictx) | |||
1740 | detected_display_type = IMON_DISPLAY_TYPE_VFD; | 1750 | detected_display_type = IMON_DISPLAY_TYPE_VFD; |
1741 | break; | 1751 | break; |
1742 | /* iMON VFD, MCE IR */ | 1752 | /* iMON VFD, MCE IR */ |
1753 | case 0x46: | ||
1754 | case 0x7e: | ||
1743 | case 0x9e: | 1755 | case 0x9e: |
1744 | dev_info(ictx->dev, "0xffdc iMON VFD, MCE IR"); | 1756 | dev_info(ictx->dev, "0xffdc iMON VFD, MCE IR"); |
1745 | detected_display_type = IMON_DISPLAY_TYPE_VFD; | 1757 | detected_display_type = IMON_DISPLAY_TYPE_VFD; |
@@ -1755,6 +1767,9 @@ static void imon_get_ffdc_type(struct imon_context *ictx) | |||
1755 | dev_info(ictx->dev, "Unknown 0xffdc device, " | 1767 | dev_info(ictx->dev, "Unknown 0xffdc device, " |
1756 | "defaulting to VFD and iMON IR"); | 1768 | "defaulting to VFD and iMON IR"); |
1757 | detected_display_type = IMON_DISPLAY_TYPE_VFD; | 1769 | detected_display_type = IMON_DISPLAY_TYPE_VFD; |
1770 | /* We don't know which one it is, allow user to set the | ||
1771 | * RC6 one from userspace if OTHER wasn't correct. */ | ||
1772 | allowed_protos |= RC_TYPE_RC6; | ||
1758 | break; | 1773 | break; |
1759 | } | 1774 | } |
1760 | 1775 | ||
diff --git a/drivers/media/rc/ir-raw.c b/drivers/media/rc/ir-raw.c index 11c19d8d0ee0..423ed45d6c55 100644 --- a/drivers/media/rc/ir-raw.c +++ b/drivers/media/rc/ir-raw.c | |||
@@ -114,18 +114,20 @@ int ir_raw_event_store_edge(struct rc_dev *dev, enum raw_event_type type) | |||
114 | s64 delta; /* ns */ | 114 | s64 delta; /* ns */ |
115 | DEFINE_IR_RAW_EVENT(ev); | 115 | DEFINE_IR_RAW_EVENT(ev); |
116 | int rc = 0; | 116 | int rc = 0; |
117 | int delay; | ||
117 | 118 | ||
118 | if (!dev->raw) | 119 | if (!dev->raw) |
119 | return -EINVAL; | 120 | return -EINVAL; |
120 | 121 | ||
121 | now = ktime_get(); | 122 | now = ktime_get(); |
122 | delta = ktime_to_ns(ktime_sub(now, dev->raw->last_event)); | 123 | delta = ktime_to_ns(ktime_sub(now, dev->raw->last_event)); |
124 | delay = MS_TO_NS(dev->input_dev->rep[REP_DELAY]); | ||
123 | 125 | ||
124 | /* Check for a long duration since last event or if we're | 126 | /* Check for a long duration since last event or if we're |
125 | * being called for the first time, note that delta can't | 127 | * being called for the first time, note that delta can't |
126 | * possibly be negative. | 128 | * possibly be negative. |
127 | */ | 129 | */ |
128 | if (delta > IR_MAX_DURATION || !dev->raw->last_type) | 130 | if (delta > delay || !dev->raw->last_type) |
129 | type |= IR_START_EVENT; | 131 | type |= IR_START_EVENT; |
130 | else | 132 | else |
131 | ev.duration = delta; | 133 | ev.duration = delta; |
diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c index e716b931cf7e..ecd3d0280768 100644 --- a/drivers/media/rc/ite-cir.c +++ b/drivers/media/rc/ite-cir.c | |||
@@ -1347,6 +1347,7 @@ static const struct ite_dev_params ite_dev_descs[] = { | |||
1347 | { /* 0: ITE8704 */ | 1347 | { /* 0: ITE8704 */ |
1348 | .model = "ITE8704 CIR transceiver", | 1348 | .model = "ITE8704 CIR transceiver", |
1349 | .io_region_size = IT87_IOREG_LENGTH, | 1349 | .io_region_size = IT87_IOREG_LENGTH, |
1350 | .io_rsrc_no = 0, | ||
1350 | .hw_tx_capable = true, | 1351 | .hw_tx_capable = true, |
1351 | .sample_period = (u32) (1000000000ULL / 115200), | 1352 | .sample_period = (u32) (1000000000ULL / 115200), |
1352 | .tx_carrier_freq = 38000, | 1353 | .tx_carrier_freq = 38000, |
@@ -1371,6 +1372,7 @@ static const struct ite_dev_params ite_dev_descs[] = { | |||
1371 | { /* 1: ITE8713 */ | 1372 | { /* 1: ITE8713 */ |
1372 | .model = "ITE8713 CIR transceiver", | 1373 | .model = "ITE8713 CIR transceiver", |
1373 | .io_region_size = IT87_IOREG_LENGTH, | 1374 | .io_region_size = IT87_IOREG_LENGTH, |
1375 | .io_rsrc_no = 0, | ||
1374 | .hw_tx_capable = true, | 1376 | .hw_tx_capable = true, |
1375 | .sample_period = (u32) (1000000000ULL / 115200), | 1377 | .sample_period = (u32) (1000000000ULL / 115200), |
1376 | .tx_carrier_freq = 38000, | 1378 | .tx_carrier_freq = 38000, |
@@ -1395,6 +1397,7 @@ static const struct ite_dev_params ite_dev_descs[] = { | |||
1395 | { /* 2: ITE8708 */ | 1397 | { /* 2: ITE8708 */ |
1396 | .model = "ITE8708 CIR transceiver", | 1398 | .model = "ITE8708 CIR transceiver", |
1397 | .io_region_size = IT8708_IOREG_LENGTH, | 1399 | .io_region_size = IT8708_IOREG_LENGTH, |
1400 | .io_rsrc_no = 0, | ||
1398 | .hw_tx_capable = true, | 1401 | .hw_tx_capable = true, |
1399 | .sample_period = (u32) (1000000000ULL / 115200), | 1402 | .sample_period = (u32) (1000000000ULL / 115200), |
1400 | .tx_carrier_freq = 38000, | 1403 | .tx_carrier_freq = 38000, |
@@ -1420,6 +1423,7 @@ static const struct ite_dev_params ite_dev_descs[] = { | |||
1420 | { /* 3: ITE8709 */ | 1423 | { /* 3: ITE8709 */ |
1421 | .model = "ITE8709 CIR transceiver", | 1424 | .model = "ITE8709 CIR transceiver", |
1422 | .io_region_size = IT8709_IOREG_LENGTH, | 1425 | .io_region_size = IT8709_IOREG_LENGTH, |
1426 | .io_rsrc_no = 2, | ||
1423 | .hw_tx_capable = true, | 1427 | .hw_tx_capable = true, |
1424 | .sample_period = (u32) (1000000000ULL / 115200), | 1428 | .sample_period = (u32) (1000000000ULL / 115200), |
1425 | .tx_carrier_freq = 38000, | 1429 | .tx_carrier_freq = 38000, |
@@ -1461,6 +1465,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id | |||
1461 | struct rc_dev *rdev = NULL; | 1465 | struct rc_dev *rdev = NULL; |
1462 | int ret = -ENOMEM; | 1466 | int ret = -ENOMEM; |
1463 | int model_no; | 1467 | int model_no; |
1468 | int io_rsrc_no; | ||
1464 | 1469 | ||
1465 | ite_dbg("%s called", __func__); | 1470 | ite_dbg("%s called", __func__); |
1466 | 1471 | ||
@@ -1490,10 +1495,11 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id | |||
1490 | 1495 | ||
1491 | /* get the description for the device */ | 1496 | /* get the description for the device */ |
1492 | dev_desc = &ite_dev_descs[model_no]; | 1497 | dev_desc = &ite_dev_descs[model_no]; |
1498 | io_rsrc_no = dev_desc->io_rsrc_no; | ||
1493 | 1499 | ||
1494 | /* validate pnp resources */ | 1500 | /* validate pnp resources */ |
1495 | if (!pnp_port_valid(pdev, 0) || | 1501 | if (!pnp_port_valid(pdev, io_rsrc_no) || |
1496 | pnp_port_len(pdev, 0) != dev_desc->io_region_size) { | 1502 | pnp_port_len(pdev, io_rsrc_no) != dev_desc->io_region_size) { |
1497 | dev_err(&pdev->dev, "IR PNP Port not valid!\n"); | 1503 | dev_err(&pdev->dev, "IR PNP Port not valid!\n"); |
1498 | goto failure; | 1504 | goto failure; |
1499 | } | 1505 | } |
@@ -1504,7 +1510,7 @@ static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id | |||
1504 | } | 1510 | } |
1505 | 1511 | ||
1506 | /* store resource values */ | 1512 | /* store resource values */ |
1507 | itdev->cir_addr = pnp_port_start(pdev, 0); | 1513 | itdev->cir_addr = pnp_port_start(pdev, io_rsrc_no); |
1508 | itdev->cir_irq = pnp_irq(pdev, 0); | 1514 | itdev->cir_irq = pnp_irq(pdev, 0); |
1509 | 1515 | ||
1510 | /* initialize spinlocks */ | 1516 | /* initialize spinlocks */ |
diff --git a/drivers/media/rc/ite-cir.h b/drivers/media/rc/ite-cir.h index 16a19f5fd718..aa899a0b9750 100644 --- a/drivers/media/rc/ite-cir.h +++ b/drivers/media/rc/ite-cir.h | |||
@@ -57,6 +57,9 @@ struct ite_dev_params { | |||
57 | /* size of the I/O region */ | 57 | /* size of the I/O region */ |
58 | int io_region_size; | 58 | int io_region_size; |
59 | 59 | ||
60 | /* IR pnp I/O resource number */ | ||
61 | int io_rsrc_no; | ||
62 | |||
60 | /* true if the hardware supports transmission */ | 63 | /* true if the hardware supports transmission */ |
61 | bool hw_tx_capable; | 64 | bool hw_tx_capable; |
62 | 65 | ||
diff --git a/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c index bb10ffe086b4..8d558ae63456 100644 --- a/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c +++ b/drivers/media/rc/keymaps/rc-pinnacle-pctv-hd.c | |||
@@ -15,43 +15,39 @@ | |||
15 | /* Pinnacle PCTV HD 800i mini remote */ | 15 | /* Pinnacle PCTV HD 800i mini remote */ |
16 | 16 | ||
17 | static struct rc_map_table pinnacle_pctv_hd[] = { | 17 | static struct rc_map_table pinnacle_pctv_hd[] = { |
18 | 18 | /* Key codes for the tiny Pinnacle remote*/ | |
19 | { 0x0f, KEY_1 }, | 19 | { 0x0700, KEY_MUTE }, |
20 | { 0x15, KEY_2 }, | 20 | { 0x0701, KEY_MENU }, /* Pinnacle logo */ |
21 | { 0x10, KEY_3 }, | 21 | { 0x0739, KEY_POWER }, |
22 | { 0x18, KEY_4 }, | 22 | { 0x0703, KEY_VOLUMEUP }, |
23 | { 0x1b, KEY_5 }, | 23 | { 0x0709, KEY_VOLUMEDOWN }, |
24 | { 0x1e, KEY_6 }, | 24 | { 0x0706, KEY_CHANNELUP }, |
25 | { 0x11, KEY_7 }, | 25 | { 0x070c, KEY_CHANNELDOWN }, |
26 | { 0x21, KEY_8 }, | 26 | { 0x070f, KEY_1 }, |
27 | { 0x12, KEY_9 }, | 27 | { 0x0715, KEY_2 }, |
28 | { 0x27, KEY_0 }, | 28 | { 0x0710, KEY_3 }, |
29 | 29 | { 0x0718, KEY_4 }, | |
30 | { 0x24, KEY_ZOOM }, | 30 | { 0x071b, KEY_5 }, |
31 | { 0x2a, KEY_SUBTITLE }, | 31 | { 0x071e, KEY_6 }, |
32 | 32 | { 0x0711, KEY_7 }, | |
33 | { 0x00, KEY_MUTE }, | 33 | { 0x0721, KEY_8 }, |
34 | { 0x01, KEY_ENTER }, /* Pinnacle Logo */ | 34 | { 0x0712, KEY_9 }, |
35 | { 0x39, KEY_POWER }, | 35 | { 0x0727, KEY_0 }, |
36 | 36 | { 0x0724, KEY_ZOOM }, /* 'Square' key */ | |
37 | { 0x03, KEY_VOLUMEUP }, | 37 | { 0x072a, KEY_SUBTITLE }, /* 'T' key */ |
38 | { 0x09, KEY_VOLUMEDOWN }, | 38 | { 0x072d, KEY_REWIND }, |
39 | { 0x06, KEY_CHANNELUP }, | 39 | { 0x0730, KEY_PLAYPAUSE }, |
40 | { 0x0c, KEY_CHANNELDOWN }, | 40 | { 0x0733, KEY_FASTFORWARD }, |
41 | 41 | { 0x0736, KEY_RECORD }, | |
42 | { 0x2d, KEY_REWIND }, | 42 | { 0x073c, KEY_STOP }, |
43 | { 0x30, KEY_PLAYPAUSE }, | 43 | { 0x073f, KEY_HELP }, /* '?' key */ |
44 | { 0x33, KEY_FASTFORWARD }, | ||
45 | { 0x3c, KEY_STOP }, | ||
46 | { 0x36, KEY_RECORD }, | ||
47 | { 0x3f, KEY_EPG }, /* Labeled "?" */ | ||
48 | }; | 44 | }; |
49 | 45 | ||
50 | static struct rc_map_list pinnacle_pctv_hd_map = { | 46 | static struct rc_map_list pinnacle_pctv_hd_map = { |
51 | .map = { | 47 | .map = { |
52 | .scan = pinnacle_pctv_hd, | 48 | .scan = pinnacle_pctv_hd, |
53 | .size = ARRAY_SIZE(pinnacle_pctv_hd), | 49 | .size = ARRAY_SIZE(pinnacle_pctv_hd), |
54 | .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */ | 50 | .rc_type = RC_TYPE_RC5, |
55 | .name = RC_MAP_PINNACLE_PCTV_HD, | 51 | .name = RC_MAP_PINNACLE_PCTV_HD, |
56 | } | 52 | } |
57 | }; | 53 | }; |
diff --git a/drivers/media/rc/lirc_dev.c b/drivers/media/rc/lirc_dev.c index fd237ab120bb..27997a9ceb0d 100644 --- a/drivers/media/rc/lirc_dev.c +++ b/drivers/media/rc/lirc_dev.c | |||
@@ -55,6 +55,8 @@ struct irctl { | |||
55 | struct lirc_buffer *buf; | 55 | struct lirc_buffer *buf; |
56 | unsigned int chunk_size; | 56 | unsigned int chunk_size; |
57 | 57 | ||
58 | struct cdev *cdev; | ||
59 | |||
58 | struct task_struct *task; | 60 | struct task_struct *task; |
59 | long jiffies_to_wait; | 61 | long jiffies_to_wait; |
60 | }; | 62 | }; |
@@ -62,7 +64,6 @@ struct irctl { | |||
62 | static DEFINE_MUTEX(lirc_dev_lock); | 64 | static DEFINE_MUTEX(lirc_dev_lock); |
63 | 65 | ||
64 | static struct irctl *irctls[MAX_IRCTL_DEVICES]; | 66 | static struct irctl *irctls[MAX_IRCTL_DEVICES]; |
65 | static struct cdev cdevs[MAX_IRCTL_DEVICES]; | ||
66 | 67 | ||
67 | /* Only used for sysfs but defined to void otherwise */ | 68 | /* Only used for sysfs but defined to void otherwise */ |
68 | static struct class *lirc_class; | 69 | static struct class *lirc_class; |
@@ -167,9 +168,13 @@ static struct file_operations lirc_dev_fops = { | |||
167 | 168 | ||
168 | static int lirc_cdev_add(struct irctl *ir) | 169 | static int lirc_cdev_add(struct irctl *ir) |
169 | { | 170 | { |
170 | int retval; | 171 | int retval = -ENOMEM; |
171 | struct lirc_driver *d = &ir->d; | 172 | struct lirc_driver *d = &ir->d; |
172 | struct cdev *cdev = &cdevs[d->minor]; | 173 | struct cdev *cdev; |
174 | |||
175 | cdev = kzalloc(sizeof(*cdev), GFP_KERNEL); | ||
176 | if (!cdev) | ||
177 | goto err_out; | ||
173 | 178 | ||
174 | if (d->fops) { | 179 | if (d->fops) { |
175 | cdev_init(cdev, d->fops); | 180 | cdev_init(cdev, d->fops); |
@@ -180,12 +185,20 @@ static int lirc_cdev_add(struct irctl *ir) | |||
180 | } | 185 | } |
181 | retval = kobject_set_name(&cdev->kobj, "lirc%d", d->minor); | 186 | retval = kobject_set_name(&cdev->kobj, "lirc%d", d->minor); |
182 | if (retval) | 187 | if (retval) |
183 | return retval; | 188 | goto err_out; |
184 | 189 | ||
185 | retval = cdev_add(cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1); | 190 | retval = cdev_add(cdev, MKDEV(MAJOR(lirc_base_dev), d->minor), 1); |
186 | if (retval) | 191 | if (retval) { |
187 | kobject_put(&cdev->kobj); | 192 | kobject_put(&cdev->kobj); |
193 | goto err_out; | ||
194 | } | ||
195 | |||
196 | ir->cdev = cdev; | ||
197 | |||
198 | return 0; | ||
188 | 199 | ||
200 | err_out: | ||
201 | kfree(cdev); | ||
189 | return retval; | 202 | return retval; |
190 | } | 203 | } |
191 | 204 | ||
@@ -214,7 +227,7 @@ int lirc_register_driver(struct lirc_driver *d) | |||
214 | if (MAX_IRCTL_DEVICES <= d->minor) { | 227 | if (MAX_IRCTL_DEVICES <= d->minor) { |
215 | dev_err(d->dev, "lirc_dev: lirc_register_driver: " | 228 | dev_err(d->dev, "lirc_dev: lirc_register_driver: " |
216 | "\"minor\" must be between 0 and %d (%d)!\n", | 229 | "\"minor\" must be between 0 and %d (%d)!\n", |
217 | MAX_IRCTL_DEVICES-1, d->minor); | 230 | MAX_IRCTL_DEVICES - 1, d->minor); |
218 | err = -EBADRQC; | 231 | err = -EBADRQC; |
219 | goto out; | 232 | goto out; |
220 | } | 233 | } |
@@ -369,7 +382,7 @@ int lirc_unregister_driver(int minor) | |||
369 | 382 | ||
370 | if (minor < 0 || minor >= MAX_IRCTL_DEVICES) { | 383 | if (minor < 0 || minor >= MAX_IRCTL_DEVICES) { |
371 | printk(KERN_ERR "lirc_dev: %s: minor (%d) must be between " | 384 | printk(KERN_ERR "lirc_dev: %s: minor (%d) must be between " |
372 | "0 and %d!\n", __func__, minor, MAX_IRCTL_DEVICES-1); | 385 | "0 and %d!\n", __func__, minor, MAX_IRCTL_DEVICES - 1); |
373 | return -EBADRQC; | 386 | return -EBADRQC; |
374 | } | 387 | } |
375 | 388 | ||
@@ -380,7 +393,7 @@ int lirc_unregister_driver(int minor) | |||
380 | return -ENOENT; | 393 | return -ENOENT; |
381 | } | 394 | } |
382 | 395 | ||
383 | cdev = &cdevs[minor]; | 396 | cdev = ir->cdev; |
384 | 397 | ||
385 | mutex_lock(&lirc_dev_lock); | 398 | mutex_lock(&lirc_dev_lock); |
386 | 399 | ||
@@ -410,6 +423,7 @@ int lirc_unregister_driver(int minor) | |||
410 | } else { | 423 | } else { |
411 | lirc_irctl_cleanup(ir); | 424 | lirc_irctl_cleanup(ir); |
412 | cdev_del(cdev); | 425 | cdev_del(cdev); |
426 | kfree(cdev); | ||
413 | kfree(ir); | 427 | kfree(ir); |
414 | irctls[minor] = NULL; | 428 | irctls[minor] = NULL; |
415 | } | 429 | } |
@@ -453,7 +467,7 @@ int lirc_dev_fop_open(struct inode *inode, struct file *file) | |||
453 | goto error; | 467 | goto error; |
454 | } | 468 | } |
455 | 469 | ||
456 | cdev = &cdevs[iminor(inode)]; | 470 | cdev = ir->cdev; |
457 | if (try_module_get(cdev->owner)) { | 471 | if (try_module_get(cdev->owner)) { |
458 | ir->open++; | 472 | ir->open++; |
459 | retval = ir->d.set_use_inc(ir->d.data); | 473 | retval = ir->d.set_use_inc(ir->d.data); |
@@ -484,13 +498,15 @@ EXPORT_SYMBOL(lirc_dev_fop_open); | |||
484 | int lirc_dev_fop_close(struct inode *inode, struct file *file) | 498 | int lirc_dev_fop_close(struct inode *inode, struct file *file) |
485 | { | 499 | { |
486 | struct irctl *ir = irctls[iminor(inode)]; | 500 | struct irctl *ir = irctls[iminor(inode)]; |
487 | struct cdev *cdev = &cdevs[iminor(inode)]; | 501 | struct cdev *cdev; |
488 | 502 | ||
489 | if (!ir) { | 503 | if (!ir) { |
490 | printk(KERN_ERR "%s: called with invalid irctl\n", __func__); | 504 | printk(KERN_ERR "%s: called with invalid irctl\n", __func__); |
491 | return -EINVAL; | 505 | return -EINVAL; |
492 | } | 506 | } |
493 | 507 | ||
508 | cdev = ir->cdev; | ||
509 | |||
494 | dev_dbg(ir->d.dev, LOGHEAD "close called\n", ir->d.name, ir->d.minor); | 510 | dev_dbg(ir->d.dev, LOGHEAD "close called\n", ir->d.name, ir->d.minor); |
495 | 511 | ||
496 | WARN_ON(mutex_lock_killable(&lirc_dev_lock)); | 512 | WARN_ON(mutex_lock_killable(&lirc_dev_lock)); |
@@ -503,6 +519,7 @@ int lirc_dev_fop_close(struct inode *inode, struct file *file) | |||
503 | lirc_irctl_cleanup(ir); | 519 | lirc_irctl_cleanup(ir); |
504 | cdev_del(cdev); | 520 | cdev_del(cdev); |
505 | irctls[ir->d.minor] = NULL; | 521 | irctls[ir->d.minor] = NULL; |
522 | kfree(cdev); | ||
506 | kfree(ir); | 523 | kfree(ir); |
507 | } | 524 | } |
508 | 525 | ||
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index ad927fcaa020..ec972dc25790 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c | |||
@@ -108,6 +108,12 @@ static int debug = 1; | |||
108 | static int debug; | 108 | static int debug; |
109 | #endif | 109 | #endif |
110 | 110 | ||
111 | #define mce_dbg(dev, fmt, ...) \ | ||
112 | do { \ | ||
113 | if (debug) \ | ||
114 | dev_info(dev, fmt, ## __VA_ARGS__); \ | ||
115 | } while (0) | ||
116 | |||
111 | /* general constants */ | 117 | /* general constants */ |
112 | #define SEND_FLAG_IN_PROGRESS 1 | 118 | #define SEND_FLAG_IN_PROGRESS 1 |
113 | #define SEND_FLAG_COMPLETE 2 | 119 | #define SEND_FLAG_COMPLETE 2 |
@@ -246,6 +252,9 @@ static struct usb_device_id mceusb_dev_table[] = { | |||
246 | .driver_info = MCE_GEN2_TX_INV }, | 252 | .driver_info = MCE_GEN2_TX_INV }, |
247 | /* SMK eHome Infrared Transceiver */ | 253 | /* SMK eHome Infrared Transceiver */ |
248 | { USB_DEVICE(VENDOR_SMK, 0x0338) }, | 254 | { USB_DEVICE(VENDOR_SMK, 0x0338) }, |
255 | /* SMK/I-O Data GV-MC7/RCKIT Receiver */ | ||
256 | { USB_DEVICE(VENDOR_SMK, 0x0353), | ||
257 | .driver_info = MCE_GEN2_NO_TX }, | ||
249 | /* Tatung eHome Infrared Transceiver */ | 258 | /* Tatung eHome Infrared Transceiver */ |
250 | { USB_DEVICE(VENDOR_TATUNG, 0x9150) }, | 259 | { USB_DEVICE(VENDOR_TATUNG, 0x9150) }, |
251 | /* Shuttle eHome Infrared Transceiver */ | 260 | /* Shuttle eHome Infrared Transceiver */ |
@@ -549,9 +558,10 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf, | |||
549 | inout, data1); | 558 | inout, data1); |
550 | break; | 559 | break; |
551 | case MCE_CMD_S_TIMEOUT: | 560 | case MCE_CMD_S_TIMEOUT: |
552 | /* value is in units of 50us, so x*50/100 or x/2 ms */ | 561 | /* value is in units of 50us, so x*50/1000 ms */ |
553 | dev_info(dev, "%s receive timeout of %d ms\n", | 562 | dev_info(dev, "%s receive timeout of %d ms\n", |
554 | inout, ((data1 << 8) | data2) / 2); | 563 | inout, |
564 | ((data1 << 8) | data2) * MCE_TIME_UNIT / 1000); | ||
555 | break; | 565 | break; |
556 | case MCE_CMD_G_TIMEOUT: | 566 | case MCE_CMD_G_TIMEOUT: |
557 | dev_info(dev, "Get receive timeout\n"); | 567 | dev_info(dev, "Get receive timeout\n"); |
@@ -606,12 +616,15 @@ static void mce_async_callback(struct urb *urb, struct pt_regs *regs) | |||
606 | if (ir) { | 616 | if (ir) { |
607 | len = urb->actual_length; | 617 | len = urb->actual_length; |
608 | 618 | ||
609 | dev_dbg(ir->dev, "callback called (status=%d len=%d)\n", | 619 | mce_dbg(ir->dev, "callback called (status=%d len=%d)\n", |
610 | urb->status, len); | 620 | urb->status, len); |
611 | 621 | ||
612 | mceusb_dev_printdata(ir, urb->transfer_buffer, 0, len, true); | 622 | mceusb_dev_printdata(ir, urb->transfer_buffer, 0, len, true); |
613 | } | 623 | } |
614 | 624 | ||
625 | /* the transfer buffer and urb were allocated in mce_request_packet */ | ||
626 | kfree(urb->transfer_buffer); | ||
627 | usb_free_urb(urb); | ||
615 | } | 628 | } |
616 | 629 | ||
617 | /* request incoming or send outgoing usb packet - used to initialize remote */ | 630 | /* request incoming or send outgoing usb packet - used to initialize remote */ |
@@ -655,17 +668,17 @@ static void mce_request_packet(struct mceusb_dev *ir, unsigned char *data, | |||
655 | return; | 668 | return; |
656 | } | 669 | } |
657 | 670 | ||
658 | dev_dbg(dev, "receive request called (size=%#x)\n", size); | 671 | mce_dbg(dev, "receive request called (size=%#x)\n", size); |
659 | 672 | ||
660 | async_urb->transfer_buffer_length = size; | 673 | async_urb->transfer_buffer_length = size; |
661 | async_urb->dev = ir->usbdev; | 674 | async_urb->dev = ir->usbdev; |
662 | 675 | ||
663 | res = usb_submit_urb(async_urb, GFP_ATOMIC); | 676 | res = usb_submit_urb(async_urb, GFP_ATOMIC); |
664 | if (res) { | 677 | if (res) { |
665 | dev_dbg(dev, "receive request FAILED! (res=%d)\n", res); | 678 | mce_dbg(dev, "receive request FAILED! (res=%d)\n", res); |
666 | return; | 679 | return; |
667 | } | 680 | } |
668 | dev_dbg(dev, "receive request complete (res=%d)\n", res); | 681 | mce_dbg(dev, "receive request complete (res=%d)\n", res); |
669 | } | 682 | } |
670 | 683 | ||
671 | static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size) | 684 | static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size) |
@@ -673,9 +686,9 @@ static void mce_async_out(struct mceusb_dev *ir, unsigned char *data, int size) | |||
673 | mce_request_packet(ir, data, size, MCEUSB_TX); | 686 | mce_request_packet(ir, data, size, MCEUSB_TX); |
674 | } | 687 | } |
675 | 688 | ||
676 | static void mce_sync_in(struct mceusb_dev *ir, unsigned char *data, int size) | 689 | static void mce_flush_rx_buffer(struct mceusb_dev *ir, int size) |
677 | { | 690 | { |
678 | mce_request_packet(ir, data, size, MCEUSB_RX); | 691 | mce_request_packet(ir, NULL, size, MCEUSB_RX); |
679 | } | 692 | } |
680 | 693 | ||
681 | /* Send data out the IR blaster port(s) */ | 694 | /* Send data out the IR blaster port(s) */ |
@@ -794,7 +807,7 @@ static int mceusb_set_tx_carrier(struct rc_dev *dev, u32 carrier) | |||
794 | ir->carrier = carrier; | 807 | ir->carrier = carrier; |
795 | cmdbuf[2] = MCE_CMD_SIG_END; | 808 | cmdbuf[2] = MCE_CMD_SIG_END; |
796 | cmdbuf[3] = MCE_IRDATA_TRAILER; | 809 | cmdbuf[3] = MCE_IRDATA_TRAILER; |
797 | dev_dbg(ir->dev, "%s: disabling carrier " | 810 | mce_dbg(ir->dev, "%s: disabling carrier " |
798 | "modulation\n", __func__); | 811 | "modulation\n", __func__); |
799 | mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); | 812 | mce_async_out(ir, cmdbuf, sizeof(cmdbuf)); |
800 | return carrier; | 813 | return carrier; |
@@ -806,7 +819,7 @@ static int mceusb_set_tx_carrier(struct rc_dev *dev, u32 carrier) | |||
806 | ir->carrier = carrier; | 819 | ir->carrier = carrier; |
807 | cmdbuf[2] = prescaler; | 820 | cmdbuf[2] = prescaler; |
808 | cmdbuf[3] = divisor; | 821 | cmdbuf[3] = divisor; |
809 | dev_dbg(ir->dev, "%s: requesting %u HZ " | 822 | mce_dbg(ir->dev, "%s: requesting %u HZ " |
810 | "carrier\n", __func__, carrier); | 823 | "carrier\n", __func__, carrier); |
811 | 824 | ||
812 | /* Transmit new carrier to mce device */ | 825 | /* Transmit new carrier to mce device */ |
@@ -835,7 +848,7 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index) | |||
835 | switch (ir->buf_in[index]) { | 848 | switch (ir->buf_in[index]) { |
836 | /* 2-byte return value commands */ | 849 | /* 2-byte return value commands */ |
837 | case MCE_CMD_S_TIMEOUT: | 850 | case MCE_CMD_S_TIMEOUT: |
838 | ir->rc->timeout = US_TO_NS((hi << 8 | lo) / 2); | 851 | ir->rc->timeout = US_TO_NS((hi << 8 | lo) * MCE_TIME_UNIT); |
839 | break; | 852 | break; |
840 | 853 | ||
841 | /* 1-byte return value commands */ | 854 | /* 1-byte return value commands */ |
@@ -879,7 +892,7 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) | |||
879 | rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK) | 892 | rawir.duration = (ir->buf_in[i] & MCE_PULSE_MASK) |
880 | * US_TO_NS(MCE_TIME_UNIT); | 893 | * US_TO_NS(MCE_TIME_UNIT); |
881 | 894 | ||
882 | dev_dbg(ir->dev, "Storing %s with duration %d\n", | 895 | mce_dbg(ir->dev, "Storing %s with duration %d\n", |
883 | rawir.pulse ? "pulse" : "space", | 896 | rawir.pulse ? "pulse" : "space", |
884 | rawir.duration); | 897 | rawir.duration); |
885 | 898 | ||
@@ -911,7 +924,7 @@ static void mceusb_process_ir_data(struct mceusb_dev *ir, int buf_len) | |||
911 | if (ir->parser_state != CMD_HEADER && !ir->rem) | 924 | if (ir->parser_state != CMD_HEADER && !ir->rem) |
912 | ir->parser_state = CMD_HEADER; | 925 | ir->parser_state = CMD_HEADER; |
913 | } | 926 | } |
914 | dev_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n"); | 927 | mce_dbg(ir->dev, "processed IR data, calling ir_raw_event_handle\n"); |
915 | ir_raw_event_handle(ir->rc); | 928 | ir_raw_event_handle(ir->rc); |
916 | } | 929 | } |
917 | 930 | ||
@@ -933,7 +946,7 @@ static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs) | |||
933 | 946 | ||
934 | if (ir->send_flags == RECV_FLAG_IN_PROGRESS) { | 947 | if (ir->send_flags == RECV_FLAG_IN_PROGRESS) { |
935 | ir->send_flags = SEND_FLAG_COMPLETE; | 948 | ir->send_flags = SEND_FLAG_COMPLETE; |
936 | dev_dbg(ir->dev, "setup answer received %d bytes\n", | 949 | mce_dbg(ir->dev, "setup answer received %d bytes\n", |
937 | buf_len); | 950 | buf_len); |
938 | } | 951 | } |
939 | 952 | ||
@@ -951,7 +964,7 @@ static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs) | |||
951 | 964 | ||
952 | case -EPIPE: | 965 | case -EPIPE: |
953 | default: | 966 | default: |
954 | dev_dbg(ir->dev, "Error: urb status = %d\n", urb->status); | 967 | mce_dbg(ir->dev, "Error: urb status = %d\n", urb->status); |
955 | break; | 968 | break; |
956 | } | 969 | } |
957 | 970 | ||
@@ -961,7 +974,6 @@ static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs) | |||
961 | static void mceusb_gen1_init(struct mceusb_dev *ir) | 974 | static void mceusb_gen1_init(struct mceusb_dev *ir) |
962 | { | 975 | { |
963 | int ret; | 976 | int ret; |
964 | int maxp = ir->len_in; | ||
965 | struct device *dev = ir->dev; | 977 | struct device *dev = ir->dev; |
966 | char *data; | 978 | char *data; |
967 | 979 | ||
@@ -978,8 +990,8 @@ static void mceusb_gen1_init(struct mceusb_dev *ir) | |||
978 | ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), | 990 | ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), |
979 | USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0, | 991 | USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0, |
980 | data, USB_CTRL_MSG_SZ, HZ * 3); | 992 | data, USB_CTRL_MSG_SZ, HZ * 3); |
981 | dev_dbg(dev, "%s - ret = %d\n", __func__, ret); | 993 | mce_dbg(dev, "%s - ret = %d\n", __func__, ret); |
982 | dev_dbg(dev, "%s - data[0] = %d, data[1] = %d\n", | 994 | mce_dbg(dev, "%s - data[0] = %d, data[1] = %d\n", |
983 | __func__, data[0], data[1]); | 995 | __func__, data[0], data[1]); |
984 | 996 | ||
985 | /* set feature: bit rate 38400 bps */ | 997 | /* set feature: bit rate 38400 bps */ |
@@ -987,71 +999,56 @@ static void mceusb_gen1_init(struct mceusb_dev *ir) | |||
987 | USB_REQ_SET_FEATURE, USB_TYPE_VENDOR, | 999 | USB_REQ_SET_FEATURE, USB_TYPE_VENDOR, |
988 | 0xc04e, 0x0000, NULL, 0, HZ * 3); | 1000 | 0xc04e, 0x0000, NULL, 0, HZ * 3); |
989 | 1001 | ||
990 | dev_dbg(dev, "%s - ret = %d\n", __func__, ret); | 1002 | mce_dbg(dev, "%s - ret = %d\n", __func__, ret); |
991 | 1003 | ||
992 | /* bRequest 4: set char length to 8 bits */ | 1004 | /* bRequest 4: set char length to 8 bits */ |
993 | ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), | 1005 | ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), |
994 | 4, USB_TYPE_VENDOR, | 1006 | 4, USB_TYPE_VENDOR, |
995 | 0x0808, 0x0000, NULL, 0, HZ * 3); | 1007 | 0x0808, 0x0000, NULL, 0, HZ * 3); |
996 | dev_dbg(dev, "%s - retB = %d\n", __func__, ret); | 1008 | mce_dbg(dev, "%s - retB = %d\n", __func__, ret); |
997 | 1009 | ||
998 | /* bRequest 2: set handshaking to use DTR/DSR */ | 1010 | /* bRequest 2: set handshaking to use DTR/DSR */ |
999 | ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), | 1011 | ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), |
1000 | 2, USB_TYPE_VENDOR, | 1012 | 2, USB_TYPE_VENDOR, |
1001 | 0x0000, 0x0100, NULL, 0, HZ * 3); | 1013 | 0x0000, 0x0100, NULL, 0, HZ * 3); |
1002 | dev_dbg(dev, "%s - retC = %d\n", __func__, ret); | 1014 | mce_dbg(dev, "%s - retC = %d\n", __func__, ret); |
1003 | 1015 | ||
1004 | /* device reset */ | 1016 | /* device reset */ |
1005 | mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET)); | 1017 | mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET)); |
1006 | mce_sync_in(ir, NULL, maxp); | ||
1007 | 1018 | ||
1008 | /* get hw/sw revision? */ | 1019 | /* get hw/sw revision? */ |
1009 | mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION)); | 1020 | mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION)); |
1010 | mce_sync_in(ir, NULL, maxp); | ||
1011 | 1021 | ||
1012 | kfree(data); | 1022 | kfree(data); |
1013 | }; | 1023 | }; |
1014 | 1024 | ||
1015 | static void mceusb_gen2_init(struct mceusb_dev *ir) | 1025 | static void mceusb_gen2_init(struct mceusb_dev *ir) |
1016 | { | 1026 | { |
1017 | int maxp = ir->len_in; | ||
1018 | |||
1019 | /* device reset */ | 1027 | /* device reset */ |
1020 | mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET)); | 1028 | mce_async_out(ir, DEVICE_RESET, sizeof(DEVICE_RESET)); |
1021 | mce_sync_in(ir, NULL, maxp); | ||
1022 | 1029 | ||
1023 | /* get hw/sw revision? */ | 1030 | /* get hw/sw revision? */ |
1024 | mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION)); | 1031 | mce_async_out(ir, GET_REVISION, sizeof(GET_REVISION)); |
1025 | mce_sync_in(ir, NULL, maxp); | ||
1026 | 1032 | ||
1027 | /* unknown what the next two actually return... */ | 1033 | /* unknown what the next two actually return... */ |
1028 | mce_async_out(ir, GET_UNKNOWN, sizeof(GET_UNKNOWN)); | 1034 | mce_async_out(ir, GET_UNKNOWN, sizeof(GET_UNKNOWN)); |
1029 | mce_sync_in(ir, NULL, maxp); | ||
1030 | mce_async_out(ir, GET_UNKNOWN2, sizeof(GET_UNKNOWN2)); | 1035 | mce_async_out(ir, GET_UNKNOWN2, sizeof(GET_UNKNOWN2)); |
1031 | mce_sync_in(ir, NULL, maxp); | ||
1032 | } | 1036 | } |
1033 | 1037 | ||
1034 | static void mceusb_get_parameters(struct mceusb_dev *ir) | 1038 | static void mceusb_get_parameters(struct mceusb_dev *ir) |
1035 | { | 1039 | { |
1036 | int maxp = ir->len_in; | ||
1037 | |||
1038 | /* get the carrier and frequency */ | 1040 | /* get the carrier and frequency */ |
1039 | mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ)); | 1041 | mce_async_out(ir, GET_CARRIER_FREQ, sizeof(GET_CARRIER_FREQ)); |
1040 | mce_sync_in(ir, NULL, maxp); | ||
1041 | 1042 | ||
1042 | if (!ir->flags.no_tx) { | 1043 | if (!ir->flags.no_tx) |
1043 | /* get the transmitter bitmask */ | 1044 | /* get the transmitter bitmask */ |
1044 | mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK)); | 1045 | mce_async_out(ir, GET_TX_BITMASK, sizeof(GET_TX_BITMASK)); |
1045 | mce_sync_in(ir, NULL, maxp); | ||
1046 | } | ||
1047 | 1046 | ||
1048 | /* get receiver timeout value */ | 1047 | /* get receiver timeout value */ |
1049 | mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT)); | 1048 | mce_async_out(ir, GET_RX_TIMEOUT, sizeof(GET_RX_TIMEOUT)); |
1050 | mce_sync_in(ir, NULL, maxp); | ||
1051 | 1049 | ||
1052 | /* get receiver sensor setting */ | 1050 | /* get receiver sensor setting */ |
1053 | mce_async_out(ir, GET_RX_SENSOR, sizeof(GET_RX_SENSOR)); | 1051 | mce_async_out(ir, GET_RX_SENSOR, sizeof(GET_RX_SENSOR)); |
1054 | mce_sync_in(ir, NULL, maxp); | ||
1055 | } | 1052 | } |
1056 | 1053 | ||
1057 | static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir) | 1054 | static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir) |
@@ -1082,7 +1079,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir) | |||
1082 | rc->priv = ir; | 1079 | rc->priv = ir; |
1083 | rc->driver_type = RC_DRIVER_IR_RAW; | 1080 | rc->driver_type = RC_DRIVER_IR_RAW; |
1084 | rc->allowed_protos = RC_TYPE_ALL; | 1081 | rc->allowed_protos = RC_TYPE_ALL; |
1085 | rc->timeout = US_TO_NS(1000); | 1082 | rc->timeout = MS_TO_NS(100); |
1086 | if (!ir->flags.no_tx) { | 1083 | if (!ir->flags.no_tx) { |
1087 | rc->s_tx_mask = mceusb_set_tx_mask; | 1084 | rc->s_tx_mask = mceusb_set_tx_mask; |
1088 | rc->s_tx_carrier = mceusb_set_tx_carrier; | 1085 | rc->s_tx_carrier = mceusb_set_tx_carrier; |
@@ -1122,7 +1119,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, | |||
1122 | bool tx_mask_normal; | 1119 | bool tx_mask_normal; |
1123 | int ir_intfnum; | 1120 | int ir_intfnum; |
1124 | 1121 | ||
1125 | dev_dbg(&intf->dev, "%s called\n", __func__); | 1122 | mce_dbg(&intf->dev, "%s called\n", __func__); |
1126 | 1123 | ||
1127 | idesc = intf->cur_altsetting; | 1124 | idesc = intf->cur_altsetting; |
1128 | 1125 | ||
@@ -1150,7 +1147,7 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, | |||
1150 | ep_in = ep; | 1147 | ep_in = ep; |
1151 | ep_in->bmAttributes = USB_ENDPOINT_XFER_INT; | 1148 | ep_in->bmAttributes = USB_ENDPOINT_XFER_INT; |
1152 | ep_in->bInterval = 1; | 1149 | ep_in->bInterval = 1; |
1153 | dev_dbg(&intf->dev, "acceptable inbound endpoint " | 1150 | mce_dbg(&intf->dev, "acceptable inbound endpoint " |
1154 | "found\n"); | 1151 | "found\n"); |
1155 | } | 1152 | } |
1156 | 1153 | ||
@@ -1165,12 +1162,12 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, | |||
1165 | ep_out = ep; | 1162 | ep_out = ep; |
1166 | ep_out->bmAttributes = USB_ENDPOINT_XFER_INT; | 1163 | ep_out->bmAttributes = USB_ENDPOINT_XFER_INT; |
1167 | ep_out->bInterval = 1; | 1164 | ep_out->bInterval = 1; |
1168 | dev_dbg(&intf->dev, "acceptable outbound endpoint " | 1165 | mce_dbg(&intf->dev, "acceptable outbound endpoint " |
1169 | "found\n"); | 1166 | "found\n"); |
1170 | } | 1167 | } |
1171 | } | 1168 | } |
1172 | if (ep_in == NULL) { | 1169 | if (ep_in == NULL) { |
1173 | dev_dbg(&intf->dev, "inbound and/or endpoint not found\n"); | 1170 | mce_dbg(&intf->dev, "inbound and/or endpoint not found\n"); |
1174 | return -ENODEV; | 1171 | return -ENODEV; |
1175 | } | 1172 | } |
1176 | 1173 | ||
@@ -1215,16 +1212,16 @@ static int __devinit mceusb_dev_probe(struct usb_interface *intf, | |||
1215 | if (!ir->rc) | 1212 | if (!ir->rc) |
1216 | goto rc_dev_fail; | 1213 | goto rc_dev_fail; |
1217 | 1214 | ||
1218 | /* flush buffers on the device */ | ||
1219 | mce_sync_in(ir, NULL, maxp); | ||
1220 | mce_sync_in(ir, NULL, maxp); | ||
1221 | |||
1222 | /* wire up inbound data handler */ | 1215 | /* wire up inbound data handler */ |
1223 | usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, | 1216 | usb_fill_int_urb(ir->urb_in, dev, pipe, ir->buf_in, |
1224 | maxp, (usb_complete_t) mceusb_dev_recv, ir, ep_in->bInterval); | 1217 | maxp, (usb_complete_t) mceusb_dev_recv, ir, ep_in->bInterval); |
1225 | ir->urb_in->transfer_dma = ir->dma_in; | 1218 | ir->urb_in->transfer_dma = ir->dma_in; |
1226 | ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 1219 | ir->urb_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
1227 | 1220 | ||
1221 | /* flush buffers on the device */ | ||
1222 | mce_dbg(&intf->dev, "Flushing receive buffers\n"); | ||
1223 | mce_flush_rx_buffer(ir, maxp); | ||
1224 | |||
1228 | /* initialize device */ | 1225 | /* initialize device */ |
1229 | if (ir->flags.microsoft_gen1) | 1226 | if (ir->flags.microsoft_gen1) |
1230 | mceusb_gen1_init(ir); | 1227 | mceusb_gen1_init(ir); |
diff --git a/drivers/media/rc/nuvoton-cir.c b/drivers/media/rc/nuvoton-cir.c index bf3060ea6107..ce595f9ab4c7 100644 --- a/drivers/media/rc/nuvoton-cir.c +++ b/drivers/media/rc/nuvoton-cir.c | |||
@@ -991,7 +991,6 @@ static int nvt_open(struct rc_dev *dev) | |||
991 | unsigned long flags; | 991 | unsigned long flags; |
992 | 992 | ||
993 | spin_lock_irqsave(&nvt->nvt_lock, flags); | 993 | spin_lock_irqsave(&nvt->nvt_lock, flags); |
994 | nvt->in_use = true; | ||
995 | nvt_enable_cir(nvt); | 994 | nvt_enable_cir(nvt); |
996 | spin_unlock_irqrestore(&nvt->nvt_lock, flags); | 995 | spin_unlock_irqrestore(&nvt->nvt_lock, flags); |
997 | 996 | ||
@@ -1004,7 +1003,6 @@ static void nvt_close(struct rc_dev *dev) | |||
1004 | unsigned long flags; | 1003 | unsigned long flags; |
1005 | 1004 | ||
1006 | spin_lock_irqsave(&nvt->nvt_lock, flags); | 1005 | spin_lock_irqsave(&nvt->nvt_lock, flags); |
1007 | nvt->in_use = false; | ||
1008 | nvt_disable_cir(nvt); | 1006 | nvt_disable_cir(nvt); |
1009 | spin_unlock_irqrestore(&nvt->nvt_lock, flags); | 1007 | spin_unlock_irqrestore(&nvt->nvt_lock, flags); |
1010 | } | 1008 | } |
@@ -1112,7 +1110,7 @@ static int nvt_probe(struct pnp_dev *pdev, const struct pnp_device_id *dev_id) | |||
1112 | rdev->dev.parent = &pdev->dev; | 1110 | rdev->dev.parent = &pdev->dev; |
1113 | rdev->driver_name = NVT_DRIVER_NAME; | 1111 | rdev->driver_name = NVT_DRIVER_NAME; |
1114 | rdev->map_name = RC_MAP_RC6_MCE; | 1112 | rdev->map_name = RC_MAP_RC6_MCE; |
1115 | rdev->timeout = US_TO_NS(1000); | 1113 | rdev->timeout = MS_TO_NS(100); |
1116 | /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */ | 1114 | /* rx resolution is hardwired to 50us atm, 1, 25, 100 also possible */ |
1117 | rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD); | 1115 | rdev->rx_resolution = US_TO_NS(CIR_SAMPLE_PERIOD); |
1118 | #if 0 | 1116 | #if 0 |
diff --git a/drivers/media/rc/nuvoton-cir.h b/drivers/media/rc/nuvoton-cir.h index 379795d61ea7..1241fc89a36c 100644 --- a/drivers/media/rc/nuvoton-cir.h +++ b/drivers/media/rc/nuvoton-cir.h | |||
@@ -70,7 +70,6 @@ struct nvt_dev { | |||
70 | struct ir_raw_event rawir; | 70 | struct ir_raw_event rawir; |
71 | 71 | ||
72 | spinlock_t nvt_lock; | 72 | spinlock_t nvt_lock; |
73 | bool in_use; | ||
74 | 73 | ||
75 | /* for rx */ | 74 | /* for rx */ |
76 | u8 buf[RX_BUF_LEN]; | 75 | u8 buf[RX_BUF_LEN]; |
diff --git a/drivers/media/rc/rc-main.c b/drivers/media/rc/rc-main.c index f57cd5677ac2..3186ac7c2c10 100644 --- a/drivers/media/rc/rc-main.c +++ b/drivers/media/rc/rc-main.c | |||
@@ -522,18 +522,20 @@ EXPORT_SYMBOL_GPL(rc_g_keycode_from_table); | |||
522 | /** | 522 | /** |
523 | * ir_do_keyup() - internal function to signal the release of a keypress | 523 | * ir_do_keyup() - internal function to signal the release of a keypress |
524 | * @dev: the struct rc_dev descriptor of the device | 524 | * @dev: the struct rc_dev descriptor of the device |
525 | * @sync: whether or not to call input_sync | ||
525 | * | 526 | * |
526 | * This function is used internally to release a keypress, it must be | 527 | * This function is used internally to release a keypress, it must be |
527 | * called with keylock held. | 528 | * called with keylock held. |
528 | */ | 529 | */ |
529 | static void ir_do_keyup(struct rc_dev *dev) | 530 | static void ir_do_keyup(struct rc_dev *dev, bool sync) |
530 | { | 531 | { |
531 | if (!dev->keypressed) | 532 | if (!dev->keypressed) |
532 | return; | 533 | return; |
533 | 534 | ||
534 | IR_dprintk(1, "keyup key 0x%04x\n", dev->last_keycode); | 535 | IR_dprintk(1, "keyup key 0x%04x\n", dev->last_keycode); |
535 | input_report_key(dev->input_dev, dev->last_keycode, 0); | 536 | input_report_key(dev->input_dev, dev->last_keycode, 0); |
536 | input_sync(dev->input_dev); | 537 | if (sync) |
538 | input_sync(dev->input_dev); | ||
537 | dev->keypressed = false; | 539 | dev->keypressed = false; |
538 | } | 540 | } |
539 | 541 | ||
@@ -549,7 +551,7 @@ void rc_keyup(struct rc_dev *dev) | |||
549 | unsigned long flags; | 551 | unsigned long flags; |
550 | 552 | ||
551 | spin_lock_irqsave(&dev->keylock, flags); | 553 | spin_lock_irqsave(&dev->keylock, flags); |
552 | ir_do_keyup(dev); | 554 | ir_do_keyup(dev, true); |
553 | spin_unlock_irqrestore(&dev->keylock, flags); | 555 | spin_unlock_irqrestore(&dev->keylock, flags); |
554 | } | 556 | } |
555 | EXPORT_SYMBOL_GPL(rc_keyup); | 557 | EXPORT_SYMBOL_GPL(rc_keyup); |
@@ -578,7 +580,7 @@ static void ir_timer_keyup(unsigned long cookie) | |||
578 | */ | 580 | */ |
579 | spin_lock_irqsave(&dev->keylock, flags); | 581 | spin_lock_irqsave(&dev->keylock, flags); |
580 | if (time_is_before_eq_jiffies(dev->keyup_jiffies)) | 582 | if (time_is_before_eq_jiffies(dev->keyup_jiffies)) |
581 | ir_do_keyup(dev); | 583 | ir_do_keyup(dev, true); |
582 | spin_unlock_irqrestore(&dev->keylock, flags); | 584 | spin_unlock_irqrestore(&dev->keylock, flags); |
583 | } | 585 | } |
584 | 586 | ||
@@ -597,6 +599,7 @@ void rc_repeat(struct rc_dev *dev) | |||
597 | spin_lock_irqsave(&dev->keylock, flags); | 599 | spin_lock_irqsave(&dev->keylock, flags); |
598 | 600 | ||
599 | input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode); | 601 | input_event(dev->input_dev, EV_MSC, MSC_SCAN, dev->last_scancode); |
602 | input_sync(dev->input_dev); | ||
600 | 603 | ||
601 | if (!dev->keypressed) | 604 | if (!dev->keypressed) |
602 | goto out; | 605 | goto out; |
@@ -622,29 +625,28 @@ EXPORT_SYMBOL_GPL(rc_repeat); | |||
622 | static void ir_do_keydown(struct rc_dev *dev, int scancode, | 625 | static void ir_do_keydown(struct rc_dev *dev, int scancode, |
623 | u32 keycode, u8 toggle) | 626 | u32 keycode, u8 toggle) |
624 | { | 627 | { |
625 | input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode); | 628 | bool new_event = !dev->keypressed || |
626 | 629 | dev->last_scancode != scancode || | |
627 | /* Repeat event? */ | 630 | dev->last_toggle != toggle; |
628 | if (dev->keypressed && | ||
629 | dev->last_scancode == scancode && | ||
630 | dev->last_toggle == toggle) | ||
631 | return; | ||
632 | 631 | ||
633 | /* Release old keypress */ | 632 | if (new_event && dev->keypressed) |
634 | ir_do_keyup(dev); | 633 | ir_do_keyup(dev, false); |
635 | 634 | ||
636 | dev->last_scancode = scancode; | 635 | input_event(dev->input_dev, EV_MSC, MSC_SCAN, scancode); |
637 | dev->last_toggle = toggle; | ||
638 | dev->last_keycode = keycode; | ||
639 | 636 | ||
640 | if (keycode == KEY_RESERVED) | 637 | if (new_event && keycode != KEY_RESERVED) { |
641 | return; | 638 | /* Register a keypress */ |
639 | dev->keypressed = true; | ||
640 | dev->last_scancode = scancode; | ||
641 | dev->last_toggle = toggle; | ||
642 | dev->last_keycode = keycode; | ||
643 | |||
644 | IR_dprintk(1, "%s: key down event, " | ||
645 | "key 0x%04x, scancode 0x%04x\n", | ||
646 | dev->input_name, keycode, scancode); | ||
647 | input_report_key(dev->input_dev, keycode, 1); | ||
648 | } | ||
642 | 649 | ||
643 | /* Register a keypress */ | ||
644 | dev->keypressed = true; | ||
645 | IR_dprintk(1, "%s: key down event, key 0x%04x, scancode 0x%04x\n", | ||
646 | dev->input_name, keycode, scancode); | ||
647 | input_report_key(dev->input_dev, dev->last_keycode, 1); | ||
648 | input_sync(dev->input_dev); | 650 | input_sync(dev->input_dev); |
649 | } | 651 | } |
650 | 652 | ||
diff --git a/drivers/media/video/bt8xx/bttv-driver.c b/drivers/media/video/bt8xx/bttv-driver.c index a97cf2750bd9..834a48394bce 100644 --- a/drivers/media/video/bt8xx/bttv-driver.c +++ b/drivers/media/video/bt8xx/bttv-driver.c | |||
@@ -3474,7 +3474,7 @@ static int radio_s_tuner(struct file *file, void *priv, | |||
3474 | if (0 != t->index) | 3474 | if (0 != t->index) |
3475 | return -EINVAL; | 3475 | return -EINVAL; |
3476 | 3476 | ||
3477 | bttv_call_all(btv, tuner, g_tuner, t); | 3477 | bttv_call_all(btv, tuner, s_tuner, t); |
3478 | return 0; | 3478 | return 0; |
3479 | } | 3479 | } |
3480 | 3480 | ||
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index 1933d4d11bf2..e80134f52ef5 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c | |||
@@ -695,14 +695,10 @@ static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) | |||
695 | 695 | ||
696 | cx18_call_all(cx, tuner, g_tuner, vt); | 696 | cx18_call_all(cx, tuner, g_tuner, vt); |
697 | 697 | ||
698 | if (test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) { | 698 | if (vt->type == V4L2_TUNER_RADIO) |
699 | strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name)); | 699 | strlcpy(vt->name, "cx18 Radio Tuner", sizeof(vt->name)); |
700 | vt->type = V4L2_TUNER_RADIO; | 700 | else |
701 | } else { | ||
702 | strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name)); | 701 | strlcpy(vt->name, "cx18 TV Tuner", sizeof(vt->name)); |
703 | vt->type = V4L2_TUNER_ANALOG_TV; | ||
704 | } | ||
705 | |||
706 | return 0; | 702 | return 0; |
707 | } | 703 | } |
708 | 704 | ||
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c index 64d9b2136ff6..419777a832ee 100644 --- a/drivers/media/video/cx23885/cx23885-core.c +++ b/drivers/media/video/cx23885/cx23885-core.c | |||
@@ -2060,12 +2060,8 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev, | |||
2060 | goto fail_irq; | 2060 | goto fail_irq; |
2061 | } | 2061 | } |
2062 | 2062 | ||
2063 | if (!pci_enable_msi(pci_dev)) | 2063 | err = request_irq(pci_dev->irq, cx23885_irq, |
2064 | err = request_irq(pci_dev->irq, cx23885_irq, | 2064 | IRQF_SHARED | IRQF_DISABLED, dev->name, dev); |
2065 | IRQF_DISABLED, dev->name, dev); | ||
2066 | else | ||
2067 | err = request_irq(pci_dev->irq, cx23885_irq, | ||
2068 | IRQF_SHARED | IRQF_DISABLED, dev->name, dev); | ||
2069 | if (err < 0) { | 2065 | if (err < 0) { |
2070 | printk(KERN_ERR "%s: can't get IRQ %d\n", | 2066 | printk(KERN_ERR "%s: can't get IRQ %d\n", |
2071 | dev->name, pci_dev->irq); | 2067 | dev->name, pci_dev->irq); |
@@ -2114,7 +2110,6 @@ static void __devexit cx23885_finidev(struct pci_dev *pci_dev) | |||
2114 | 2110 | ||
2115 | /* unregister stuff */ | 2111 | /* unregister stuff */ |
2116 | free_irq(pci_dev->irq, dev); | 2112 | free_irq(pci_dev->irq, dev); |
2117 | pci_disable_msi(pci_dev); | ||
2118 | 2113 | ||
2119 | cx23885_dev_unregister(dev); | 2114 | cx23885_dev_unregister(dev); |
2120 | v4l2_device_unregister(v4l2_dev); | 2115 | v4l2_device_unregister(v4l2_dev); |
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index f9e347dae739..120c7d8e0895 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c | |||
@@ -1184,14 +1184,10 @@ static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) | |||
1184 | 1184 | ||
1185 | ivtv_call_all(itv, tuner, g_tuner, vt); | 1185 | ivtv_call_all(itv, tuner, g_tuner, vt); |
1186 | 1186 | ||
1187 | if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) { | 1187 | if (vt->type == V4L2_TUNER_RADIO) |
1188 | strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name)); | 1188 | strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name)); |
1189 | vt->type = V4L2_TUNER_RADIO; | 1189 | else |
1190 | } else { | ||
1191 | strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name)); | 1190 | strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name)); |
1192 | vt->type = V4L2_TUNER_ANALOG_TV; | ||
1193 | } | ||
1194 | |||
1195 | return 0; | 1191 | return 0; |
1196 | } | 1192 | } |
1197 | 1193 | ||
diff --git a/drivers/media/video/m5mols/m5mols.h b/drivers/media/video/m5mols/m5mols.h index 10b55c854487..89d09a8914f8 100644 --- a/drivers/media/video/m5mols/m5mols.h +++ b/drivers/media/video/m5mols/m5mols.h | |||
@@ -2,10 +2,10 @@ | |||
2 | * Header for M-5MOLS 8M Pixel camera sensor with ISP | 2 | * Header for M-5MOLS 8M Pixel camera sensor with ISP |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. | 4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. |
5 | * Author: HeungJun Kim, riverful.kim@samsung.com | 5 | * Author: HeungJun Kim <riverful.kim@samsung.com> |
6 | * | 6 | * |
7 | * Copyright (C) 2009 Samsung Electronics Co., Ltd. | 7 | * Copyright (C) 2009 Samsung Electronics Co., Ltd. |
8 | * Author: Dongsoo Nathaniel Kim, dongsoo45.kim@samsung.com | 8 | * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com> |
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 as published by | 11 | * it under the terms of the GNU General Public License as published by |
@@ -106,23 +106,23 @@ struct m5mols_capture { | |||
106 | * The each value according to each scenemode is recommended in the documents. | 106 | * The each value according to each scenemode is recommended in the documents. |
107 | */ | 107 | */ |
108 | struct m5mols_scenemode { | 108 | struct m5mols_scenemode { |
109 | u32 metering; | 109 | u8 metering; |
110 | u32 ev_bias; | 110 | u8 ev_bias; |
111 | u32 wb_mode; | 111 | u8 wb_mode; |
112 | u32 wb_preset; | 112 | u8 wb_preset; |
113 | u32 chroma_en; | 113 | u8 chroma_en; |
114 | u32 chroma_lvl; | 114 | u8 chroma_lvl; |
115 | u32 edge_en; | 115 | u8 edge_en; |
116 | u32 edge_lvl; | 116 | u8 edge_lvl; |
117 | u32 af_range; | 117 | u8 af_range; |
118 | u32 fd_mode; | 118 | u8 fd_mode; |
119 | u32 mcc; | 119 | u8 mcc; |
120 | u32 light; | 120 | u8 light; |
121 | u32 flash; | 121 | u8 flash; |
122 | u32 tone; | 122 | u8 tone; |
123 | u32 iso; | 123 | u8 iso; |
124 | u32 capt_mode; | 124 | u8 capt_mode; |
125 | u32 wdr; | 125 | u8 wdr; |
126 | }; | 126 | }; |
127 | 127 | ||
128 | /** | 128 | /** |
@@ -154,7 +154,6 @@ struct m5mols_version { | |||
154 | u8 str[VERSION_STRING_SIZE]; | 154 | u8 str[VERSION_STRING_SIZE]; |
155 | u8 af; | 155 | u8 af; |
156 | }; | 156 | }; |
157 | #define VERSION_SIZE sizeof(struct m5mols_version) | ||
158 | 157 | ||
159 | /** | 158 | /** |
160 | * struct m5mols_info - M-5MOLS driver data structure | 159 | * struct m5mols_info - M-5MOLS driver data structure |
@@ -216,9 +215,9 @@ struct m5mols_info { | |||
216 | bool lock_ae; | 215 | bool lock_ae; |
217 | bool lock_awb; | 216 | bool lock_awb; |
218 | u8 resolution; | 217 | u8 resolution; |
219 | u32 interrupt; | 218 | u8 interrupt; |
220 | u32 mode; | 219 | u8 mode; |
221 | u32 mode_save; | 220 | u8 mode_save; |
222 | int (*set_power)(struct device *dev, int on); | 221 | int (*set_power)(struct device *dev, int on); |
223 | }; | 222 | }; |
224 | 223 | ||
@@ -256,9 +255,11 @@ struct m5mols_info { | |||
256 | * +-------+---+----------+-----+------+------+------+------+ | 255 | * +-------+---+----------+-----+------+------+------+------+ |
257 | * - d[0..3]: according to size1 | 256 | * - d[0..3]: according to size1 |
258 | */ | 257 | */ |
259 | int m5mols_read(struct v4l2_subdev *sd, u32 reg_comb, u32 *val); | 258 | int m5mols_read_u8(struct v4l2_subdev *sd, u32 reg_comb, u8 *val); |
259 | int m5mols_read_u16(struct v4l2_subdev *sd, u32 reg_comb, u16 *val); | ||
260 | int m5mols_read_u32(struct v4l2_subdev *sd, u32 reg_comb, u32 *val); | ||
260 | int m5mols_write(struct v4l2_subdev *sd, u32 reg_comb, u32 val); | 261 | int m5mols_write(struct v4l2_subdev *sd, u32 reg_comb, u32 val); |
261 | int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u32 value); | 262 | int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u8 value); |
262 | 263 | ||
263 | /* | 264 | /* |
264 | * Mode operation of the M-5MOLS | 265 | * Mode operation of the M-5MOLS |
@@ -280,12 +281,12 @@ int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u32 value); | |||
280 | * The available executing order between each modes are as follows: | 281 | * The available executing order between each modes are as follows: |
281 | * PARAMETER <---> MONITOR <---> CAPTURE | 282 | * PARAMETER <---> MONITOR <---> CAPTURE |
282 | */ | 283 | */ |
283 | int m5mols_mode(struct m5mols_info *info, u32 mode); | 284 | int m5mols_mode(struct m5mols_info *info, u8 mode); |
284 | 285 | ||
285 | int m5mols_enable_interrupt(struct v4l2_subdev *sd, u32 reg); | 286 | int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg); |
286 | int m5mols_sync_controls(struct m5mols_info *info); | 287 | int m5mols_sync_controls(struct m5mols_info *info); |
287 | int m5mols_start_capture(struct m5mols_info *info); | 288 | int m5mols_start_capture(struct m5mols_info *info); |
288 | int m5mols_do_scenemode(struct m5mols_info *info, u32 mode); | 289 | int m5mols_do_scenemode(struct m5mols_info *info, u8 mode); |
289 | int m5mols_lock_3a(struct m5mols_info *info, bool lock); | 290 | int m5mols_lock_3a(struct m5mols_info *info, bool lock); |
290 | int m5mols_set_ctrl(struct v4l2_ctrl *ctrl); | 291 | int m5mols_set_ctrl(struct v4l2_ctrl *ctrl); |
291 | 292 | ||
diff --git a/drivers/media/video/m5mols/m5mols_capture.c b/drivers/media/video/m5mols/m5mols_capture.c index d71a3903b60f..d9471928369d 100644 --- a/drivers/media/video/m5mols/m5mols_capture.c +++ b/drivers/media/video/m5mols/m5mols_capture.c | |||
@@ -2,10 +2,10 @@ | |||
2 | * The Capture code for Fujitsu M-5MOLS ISP | 2 | * The Capture code for Fujitsu M-5MOLS ISP |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. | 4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. |
5 | * Author: HeungJun Kim, riverful.kim@samsung.com | 5 | * Author: HeungJun Kim <riverful.kim@samsung.com> |
6 | * | 6 | * |
7 | * Copyright (C) 2009 Samsung Electronics Co., Ltd. | 7 | * Copyright (C) 2009 Samsung Electronics Co., Ltd. |
8 | * Author: Dongsoo Nathaniel Kim, dongsoo45.kim@samsung.com | 8 | * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com> |
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 as published by | 11 | * it under the terms of the GNU General Public License as published by |
@@ -58,9 +58,9 @@ static int m5mols_read_rational(struct v4l2_subdev *sd, u32 addr_num, | |||
58 | { | 58 | { |
59 | u32 num, den; | 59 | u32 num, den; |
60 | 60 | ||
61 | int ret = m5mols_read(sd, addr_num, &num); | 61 | int ret = m5mols_read_u32(sd, addr_num, &num); |
62 | if (!ret) | 62 | if (!ret) |
63 | ret = m5mols_read(sd, addr_den, &den); | 63 | ret = m5mols_read_u32(sd, addr_den, &den); |
64 | if (ret) | 64 | if (ret) |
65 | return ret; | 65 | return ret; |
66 | *val = den == 0 ? 0 : num / den; | 66 | *val = den == 0 ? 0 : num / den; |
@@ -99,20 +99,20 @@ static int m5mols_capture_info(struct m5mols_info *info) | |||
99 | if (ret) | 99 | if (ret) |
100 | return ret; | 100 | return ret; |
101 | 101 | ||
102 | ret = m5mols_read(sd, EXIF_INFO_ISO, (u32 *)&exif->iso_speed); | 102 | ret = m5mols_read_u16(sd, EXIF_INFO_ISO, &exif->iso_speed); |
103 | if (!ret) | 103 | if (!ret) |
104 | ret = m5mols_read(sd, EXIF_INFO_FLASH, (u32 *)&exif->flash); | 104 | ret = m5mols_read_u16(sd, EXIF_INFO_FLASH, &exif->flash); |
105 | if (!ret) | 105 | if (!ret) |
106 | ret = m5mols_read(sd, EXIF_INFO_SDR, (u32 *)&exif->sdr); | 106 | ret = m5mols_read_u16(sd, EXIF_INFO_SDR, &exif->sdr); |
107 | if (!ret) | 107 | if (!ret) |
108 | ret = m5mols_read(sd, EXIF_INFO_QVAL, (u32 *)&exif->qval); | 108 | ret = m5mols_read_u16(sd, EXIF_INFO_QVAL, &exif->qval); |
109 | if (ret) | 109 | if (ret) |
110 | return ret; | 110 | return ret; |
111 | 111 | ||
112 | if (!ret) | 112 | if (!ret) |
113 | ret = m5mols_read(sd, CAPC_IMAGE_SIZE, &info->cap.main); | 113 | ret = m5mols_read_u32(sd, CAPC_IMAGE_SIZE, &info->cap.main); |
114 | if (!ret) | 114 | if (!ret) |
115 | ret = m5mols_read(sd, CAPC_THUMB_SIZE, &info->cap.thumb); | 115 | ret = m5mols_read_u32(sd, CAPC_THUMB_SIZE, &info->cap.thumb); |
116 | if (!ret) | 116 | if (!ret) |
117 | info->cap.total = info->cap.main + info->cap.thumb; | 117 | info->cap.total = info->cap.main + info->cap.thumb; |
118 | 118 | ||
@@ -122,7 +122,7 @@ static int m5mols_capture_info(struct m5mols_info *info) | |||
122 | int m5mols_start_capture(struct m5mols_info *info) | 122 | int m5mols_start_capture(struct m5mols_info *info) |
123 | { | 123 | { |
124 | struct v4l2_subdev *sd = &info->sd; | 124 | struct v4l2_subdev *sd = &info->sd; |
125 | u32 resolution = info->resolution; | 125 | u8 resolution = info->resolution; |
126 | int timeout; | 126 | int timeout; |
127 | int ret; | 127 | int ret; |
128 | 128 | ||
diff --git a/drivers/media/video/m5mols/m5mols_controls.c b/drivers/media/video/m5mols/m5mols_controls.c index 817c16fec368..d135d20d09cf 100644 --- a/drivers/media/video/m5mols/m5mols_controls.c +++ b/drivers/media/video/m5mols/m5mols_controls.c | |||
@@ -2,10 +2,10 @@ | |||
2 | * Controls for M-5MOLS 8M Pixel camera sensor with ISP | 2 | * Controls for M-5MOLS 8M Pixel camera sensor with ISP |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. | 4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. |
5 | * Author: HeungJun Kim, riverful.kim@samsung.com | 5 | * Author: HeungJun Kim <riverful.kim@samsung.com> |
6 | * | 6 | * |
7 | * Copyright (C) 2009 Samsung Electronics Co., Ltd. | 7 | * Copyright (C) 2009 Samsung Electronics Co., Ltd. |
8 | * Author: Dongsoo Nathaniel Kim, dongsoo45.kim@samsung.com | 8 | * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com> |
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 as published by | 11 | * it under the terms of the GNU General Public License as published by |
@@ -130,7 +130,7 @@ static struct m5mols_scenemode m5mols_default_scenemode[] = { | |||
130 | * | 130 | * |
131 | * WARNING: The execution order is important. Do not change the order. | 131 | * WARNING: The execution order is important. Do not change the order. |
132 | */ | 132 | */ |
133 | int m5mols_do_scenemode(struct m5mols_info *info, u32 mode) | 133 | int m5mols_do_scenemode(struct m5mols_info *info, u8 mode) |
134 | { | 134 | { |
135 | struct v4l2_subdev *sd = &info->sd; | 135 | struct v4l2_subdev *sd = &info->sd; |
136 | struct m5mols_scenemode scenemode = m5mols_default_scenemode[mode]; | 136 | struct m5mols_scenemode scenemode = m5mols_default_scenemode[mode]; |
diff --git a/drivers/media/video/m5mols/m5mols_core.c b/drivers/media/video/m5mols/m5mols_core.c index 76eac26e84ae..43c68f51c5ce 100644 --- a/drivers/media/video/m5mols/m5mols_core.c +++ b/drivers/media/video/m5mols/m5mols_core.c | |||
@@ -2,10 +2,10 @@ | |||
2 | * Driver for M-5MOLS 8M Pixel camera sensor with ISP | 2 | * Driver for M-5MOLS 8M Pixel camera sensor with ISP |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. | 4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. |
5 | * Author: HeungJun Kim, riverful.kim@samsung.com | 5 | * Author: HeungJun Kim <riverful.kim@samsung.com> |
6 | * | 6 | * |
7 | * Copyright (C) 2009 Samsung Electronics Co., Ltd. | 7 | * Copyright (C) 2009 Samsung Electronics Co., Ltd. |
8 | * Author: Dongsoo Nathaniel Kim, dongsoo45.kim@samsung.com | 8 | * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com> |
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 as published by | 11 | * it under the terms of the GNU General Public License as published by |
@@ -133,13 +133,13 @@ static u32 m5mols_swap_byte(u8 *data, u8 length) | |||
133 | /** | 133 | /** |
134 | * m5mols_read - I2C read function | 134 | * m5mols_read - I2C read function |
135 | * @reg: combination of size, category and command for the I2C packet | 135 | * @reg: combination of size, category and command for the I2C packet |
136 | * @size: desired size of I2C packet | ||
136 | * @val: read value | 137 | * @val: read value |
137 | */ | 138 | */ |
138 | int m5mols_read(struct v4l2_subdev *sd, u32 reg, u32 *val) | 139 | static int m5mols_read(struct v4l2_subdev *sd, u32 size, u32 reg, u32 *val) |
139 | { | 140 | { |
140 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 141 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
141 | u8 rbuf[M5MOLS_I2C_MAX_SIZE + 1]; | 142 | u8 rbuf[M5MOLS_I2C_MAX_SIZE + 1]; |
142 | u8 size = I2C_SIZE(reg); | ||
143 | u8 category = I2C_CATEGORY(reg); | 143 | u8 category = I2C_CATEGORY(reg); |
144 | u8 cmd = I2C_COMMAND(reg); | 144 | u8 cmd = I2C_COMMAND(reg); |
145 | struct i2c_msg msg[2]; | 145 | struct i2c_msg msg[2]; |
@@ -149,11 +149,6 @@ int m5mols_read(struct v4l2_subdev *sd, u32 reg, u32 *val) | |||
149 | if (!client->adapter) | 149 | if (!client->adapter) |
150 | return -ENODEV; | 150 | return -ENODEV; |
151 | 151 | ||
152 | if (size != 1 && size != 2 && size != 4) { | ||
153 | v4l2_err(sd, "Wrong data size\n"); | ||
154 | return -EINVAL; | ||
155 | } | ||
156 | |||
157 | msg[0].addr = client->addr; | 152 | msg[0].addr = client->addr; |
158 | msg[0].flags = 0; | 153 | msg[0].flags = 0; |
159 | msg[0].len = 5; | 154 | msg[0].len = 5; |
@@ -184,6 +179,52 @@ int m5mols_read(struct v4l2_subdev *sd, u32 reg, u32 *val) | |||
184 | return 0; | 179 | return 0; |
185 | } | 180 | } |
186 | 181 | ||
182 | int m5mols_read_u8(struct v4l2_subdev *sd, u32 reg, u8 *val) | ||
183 | { | ||
184 | u32 val_32; | ||
185 | int ret; | ||
186 | |||
187 | if (I2C_SIZE(reg) != 1) { | ||
188 | v4l2_err(sd, "Wrong data size\n"); | ||
189 | return -EINVAL; | ||
190 | } | ||
191 | |||
192 | ret = m5mols_read(sd, I2C_SIZE(reg), reg, &val_32); | ||
193 | if (ret) | ||
194 | return ret; | ||
195 | |||
196 | *val = (u8)val_32; | ||
197 | return ret; | ||
198 | } | ||
199 | |||
200 | int m5mols_read_u16(struct v4l2_subdev *sd, u32 reg, u16 *val) | ||
201 | { | ||
202 | u32 val_32; | ||
203 | int ret; | ||
204 | |||
205 | if (I2C_SIZE(reg) != 2) { | ||
206 | v4l2_err(sd, "Wrong data size\n"); | ||
207 | return -EINVAL; | ||
208 | } | ||
209 | |||
210 | ret = m5mols_read(sd, I2C_SIZE(reg), reg, &val_32); | ||
211 | if (ret) | ||
212 | return ret; | ||
213 | |||
214 | *val = (u16)val_32; | ||
215 | return ret; | ||
216 | } | ||
217 | |||
218 | int m5mols_read_u32(struct v4l2_subdev *sd, u32 reg, u32 *val) | ||
219 | { | ||
220 | if (I2C_SIZE(reg) != 4) { | ||
221 | v4l2_err(sd, "Wrong data size\n"); | ||
222 | return -EINVAL; | ||
223 | } | ||
224 | |||
225 | return m5mols_read(sd, I2C_SIZE(reg), reg, val); | ||
226 | } | ||
227 | |||
187 | /** | 228 | /** |
188 | * m5mols_write - I2C command write function | 229 | * m5mols_write - I2C command write function |
189 | * @reg: combination of size, category and command for the I2C packet | 230 | * @reg: combination of size, category and command for the I2C packet |
@@ -231,13 +272,14 @@ int m5mols_write(struct v4l2_subdev *sd, u32 reg, u32 val) | |||
231 | return 0; | 272 | return 0; |
232 | } | 273 | } |
233 | 274 | ||
234 | int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u32 mask) | 275 | int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u8 mask) |
235 | { | 276 | { |
236 | u32 busy, i; | 277 | u8 busy; |
278 | int i; | ||
237 | int ret; | 279 | int ret; |
238 | 280 | ||
239 | for (i = 0; i < M5MOLS_I2C_CHECK_RETRY; i++) { | 281 | for (i = 0; i < M5MOLS_I2C_CHECK_RETRY; i++) { |
240 | ret = m5mols_read(sd, I2C_REG(category, cmd, 1), &busy); | 282 | ret = m5mols_read_u8(sd, I2C_REG(category, cmd, 1), &busy); |
241 | if (ret < 0) | 283 | if (ret < 0) |
242 | return ret; | 284 | return ret; |
243 | if ((busy & mask) == mask) | 285 | if ((busy & mask) == mask) |
@@ -252,14 +294,14 @@ int m5mols_busy(struct v4l2_subdev *sd, u8 category, u8 cmd, u32 mask) | |||
252 | * Before writing desired interrupt value the INT_FACTOR register should | 294 | * Before writing desired interrupt value the INT_FACTOR register should |
253 | * be read to clear pending interrupts. | 295 | * be read to clear pending interrupts. |
254 | */ | 296 | */ |
255 | int m5mols_enable_interrupt(struct v4l2_subdev *sd, u32 reg) | 297 | int m5mols_enable_interrupt(struct v4l2_subdev *sd, u8 reg) |
256 | { | 298 | { |
257 | struct m5mols_info *info = to_m5mols(sd); | 299 | struct m5mols_info *info = to_m5mols(sd); |
258 | u32 mask = is_available_af(info) ? REG_INT_AF : 0; | 300 | u8 mask = is_available_af(info) ? REG_INT_AF : 0; |
259 | u32 dummy; | 301 | u8 dummy; |
260 | int ret; | 302 | int ret; |
261 | 303 | ||
262 | ret = m5mols_read(sd, SYSTEM_INT_FACTOR, &dummy); | 304 | ret = m5mols_read_u8(sd, SYSTEM_INT_FACTOR, &dummy); |
263 | if (!ret) | 305 | if (!ret) |
264 | ret = m5mols_write(sd, SYSTEM_INT_ENABLE, reg & ~mask); | 306 | ret = m5mols_write(sd, SYSTEM_INT_ENABLE, reg & ~mask); |
265 | return ret; | 307 | return ret; |
@@ -271,7 +313,7 @@ int m5mols_enable_interrupt(struct v4l2_subdev *sd, u32 reg) | |||
271 | * It always accompanies a little delay changing the M-5MOLS mode, so it is | 313 | * It always accompanies a little delay changing the M-5MOLS mode, so it is |
272 | * needed checking current busy status to guarantee right mode. | 314 | * needed checking current busy status to guarantee right mode. |
273 | */ | 315 | */ |
274 | static int m5mols_reg_mode(struct v4l2_subdev *sd, u32 mode) | 316 | static int m5mols_reg_mode(struct v4l2_subdev *sd, u8 mode) |
275 | { | 317 | { |
276 | int ret = m5mols_write(sd, SYSTEM_SYSMODE, mode); | 318 | int ret = m5mols_write(sd, SYSTEM_SYSMODE, mode); |
277 | 319 | ||
@@ -286,16 +328,16 @@ static int m5mols_reg_mode(struct v4l2_subdev *sd, u32 mode) | |||
286 | * can be guaranteed only when the sensor is operating in mode which which | 328 | * can be guaranteed only when the sensor is operating in mode which which |
287 | * a command belongs to. | 329 | * a command belongs to. |
288 | */ | 330 | */ |
289 | int m5mols_mode(struct m5mols_info *info, u32 mode) | 331 | int m5mols_mode(struct m5mols_info *info, u8 mode) |
290 | { | 332 | { |
291 | struct v4l2_subdev *sd = &info->sd; | 333 | struct v4l2_subdev *sd = &info->sd; |
292 | int ret = -EINVAL; | 334 | int ret = -EINVAL; |
293 | u32 reg; | 335 | u8 reg; |
294 | 336 | ||
295 | if (mode < REG_PARAMETER && mode > REG_CAPTURE) | 337 | if (mode < REG_PARAMETER && mode > REG_CAPTURE) |
296 | return ret; | 338 | return ret; |
297 | 339 | ||
298 | ret = m5mols_read(sd, SYSTEM_SYSMODE, ®); | 340 | ret = m5mols_read_u8(sd, SYSTEM_SYSMODE, ®); |
299 | if ((!ret && reg == mode) || ret) | 341 | if ((!ret && reg == mode) || ret) |
300 | return ret; | 342 | return ret; |
301 | 343 | ||
@@ -344,41 +386,37 @@ int m5mols_mode(struct m5mols_info *info, u32 mode) | |||
344 | static int m5mols_get_version(struct v4l2_subdev *sd) | 386 | static int m5mols_get_version(struct v4l2_subdev *sd) |
345 | { | 387 | { |
346 | struct m5mols_info *info = to_m5mols(sd); | 388 | struct m5mols_info *info = to_m5mols(sd); |
347 | union { | 389 | struct m5mols_version *ver = &info->ver; |
348 | struct m5mols_version ver; | 390 | u8 *str = ver->str; |
349 | u8 bytes[VERSION_SIZE]; | 391 | int i; |
350 | } version; | ||
351 | u32 *value; | ||
352 | u8 cmd = CAT0_VER_CUSTOMER; | ||
353 | int ret; | 392 | int ret; |
354 | 393 | ||
355 | do { | 394 | ret = m5mols_read_u8(sd, SYSTEM_VER_CUSTOMER, &ver->customer); |
356 | value = (u32 *)&version.bytes[cmd]; | 395 | if (!ret) |
357 | ret = m5mols_read(sd, SYSTEM_CMD(cmd), value); | 396 | ret = m5mols_read_u8(sd, SYSTEM_VER_PROJECT, &ver->project); |
358 | if (ret) | 397 | if (!ret) |
359 | return ret; | 398 | ret = m5mols_read_u16(sd, SYSTEM_VER_FIRMWARE, &ver->fw); |
360 | } while (cmd++ != CAT0_VER_AWB); | 399 | if (!ret) |
400 | ret = m5mols_read_u16(sd, SYSTEM_VER_HARDWARE, &ver->hw); | ||
401 | if (!ret) | ||
402 | ret = m5mols_read_u16(sd, SYSTEM_VER_PARAMETER, &ver->param); | ||
403 | if (!ret) | ||
404 | ret = m5mols_read_u16(sd, SYSTEM_VER_AWB, &ver->awb); | ||
405 | if (!ret) | ||
406 | ret = m5mols_read_u8(sd, AF_VERSION, &ver->af); | ||
407 | if (ret) | ||
408 | return ret; | ||
361 | 409 | ||
362 | do { | 410 | for (i = 0; i < VERSION_STRING_SIZE; i++) { |
363 | value = (u32 *)&version.bytes[cmd]; | 411 | ret = m5mols_read_u8(sd, SYSTEM_VER_STRING, &str[i]); |
364 | ret = m5mols_read(sd, SYSTEM_VER_STRING, value); | ||
365 | if (ret) | 412 | if (ret) |
366 | return ret; | 413 | return ret; |
367 | if (cmd >= VERSION_SIZE - 1) | 414 | } |
368 | return -EINVAL; | ||
369 | } while (version.bytes[cmd++]); | ||
370 | |||
371 | value = (u32 *)&version.bytes[cmd]; | ||
372 | ret = m5mols_read(sd, AF_VERSION, value); | ||
373 | if (ret) | ||
374 | return ret; | ||
375 | 415 | ||
376 | /* store version information swapped for being readable */ | 416 | ver->fw = be16_to_cpu(ver->fw); |
377 | info->ver = version.ver; | 417 | ver->hw = be16_to_cpu(ver->hw); |
378 | info->ver.fw = be16_to_cpu(info->ver.fw); | 418 | ver->param = be16_to_cpu(ver->param); |
379 | info->ver.hw = be16_to_cpu(info->ver.hw); | 419 | ver->awb = be16_to_cpu(ver->awb); |
380 | info->ver.param = be16_to_cpu(info->ver.param); | ||
381 | info->ver.awb = be16_to_cpu(info->ver.awb); | ||
382 | 420 | ||
383 | v4l2_info(sd, "Manufacturer\t[%s]\n", | 421 | v4l2_info(sd, "Manufacturer\t[%s]\n", |
384 | is_manufacturer(info, REG_SAMSUNG_ELECTRO) ? | 422 | is_manufacturer(info, REG_SAMSUNG_ELECTRO) ? |
@@ -722,7 +760,7 @@ static int m5mols_init_controls(struct m5mols_info *info) | |||
722 | int ret; | 760 | int ret; |
723 | 761 | ||
724 | /* Determine value's range & step of controls for various FW version */ | 762 | /* Determine value's range & step of controls for various FW version */ |
725 | ret = m5mols_read(sd, AE_MAX_GAIN_MON, (u32 *)&max_exposure); | 763 | ret = m5mols_read_u16(sd, AE_MAX_GAIN_MON, &max_exposure); |
726 | if (!ret) | 764 | if (!ret) |
727 | step_zoom = is_manufacturer(info, REG_SAMSUNG_OPTICS) ? 31 : 1; | 765 | step_zoom = is_manufacturer(info, REG_SAMSUNG_OPTICS) ? 31 : 1; |
728 | if (ret) | 766 | if (ret) |
@@ -842,18 +880,18 @@ static void m5mols_irq_work(struct work_struct *work) | |||
842 | struct m5mols_info *info = | 880 | struct m5mols_info *info = |
843 | container_of(work, struct m5mols_info, work_irq); | 881 | container_of(work, struct m5mols_info, work_irq); |
844 | struct v4l2_subdev *sd = &info->sd; | 882 | struct v4l2_subdev *sd = &info->sd; |
845 | u32 reg; | 883 | u8 reg; |
846 | int ret; | 884 | int ret; |
847 | 885 | ||
848 | if (!is_powered(info) || | 886 | if (!is_powered(info) || |
849 | m5mols_read(sd, SYSTEM_INT_FACTOR, &info->interrupt)) | 887 | m5mols_read_u8(sd, SYSTEM_INT_FACTOR, &info->interrupt)) |
850 | return; | 888 | return; |
851 | 889 | ||
852 | switch (info->interrupt & REG_INT_MASK) { | 890 | switch (info->interrupt & REG_INT_MASK) { |
853 | case REG_INT_AF: | 891 | case REG_INT_AF: |
854 | if (!is_available_af(info)) | 892 | if (!is_available_af(info)) |
855 | break; | 893 | break; |
856 | ret = m5mols_read(sd, AF_STATUS, ®); | 894 | ret = m5mols_read_u8(sd, AF_STATUS, ®); |
857 | v4l2_dbg(2, m5mols_debug, sd, "AF %s\n", | 895 | v4l2_dbg(2, m5mols_debug, sd, "AF %s\n", |
858 | reg == REG_AF_FAIL ? "Failed" : | 896 | reg == REG_AF_FAIL ? "Failed" : |
859 | reg == REG_AF_SUCCESS ? "Success" : | 897 | reg == REG_AF_SUCCESS ? "Success" : |
diff --git a/drivers/media/video/m5mols/m5mols_reg.h b/drivers/media/video/m5mols/m5mols_reg.h index b83e36fc6ac6..c755bd6edfe9 100644 --- a/drivers/media/video/m5mols/m5mols_reg.h +++ b/drivers/media/video/m5mols/m5mols_reg.h | |||
@@ -2,10 +2,10 @@ | |||
2 | * Register map for M-5MOLS 8M Pixel camera sensor with ISP | 2 | * Register map for M-5MOLS 8M Pixel camera sensor with ISP |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. | 4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. |
5 | * Author: HeungJun Kim, riverful.kim@samsung.com | 5 | * Author: HeungJun Kim <riverful.kim@samsung.com> |
6 | * | 6 | * |
7 | * Copyright (C) 2009 Samsung Electronics Co., Ltd. | 7 | * Copyright (C) 2009 Samsung Electronics Co., Ltd. |
8 | * Author: Dongsoo Nathaniel Kim, dongsoo45.kim@samsung.com | 8 | * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com> |
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 as published by | 11 | * it under the terms of the GNU General Public License as published by |
@@ -56,13 +56,24 @@ | |||
56 | * more specific contents, see definition if file m5mols.h. | 56 | * more specific contents, see definition if file m5mols.h. |
57 | */ | 57 | */ |
58 | #define CAT0_VER_CUSTOMER 0x00 /* customer version */ | 58 | #define CAT0_VER_CUSTOMER 0x00 /* customer version */ |
59 | #define CAT0_VER_AWB 0x09 /* Auto WB version */ | 59 | #define CAT0_VER_PROJECT 0x01 /* project version */ |
60 | #define CAT0_VER_FIRMWARE 0x02 /* Firmware version */ | ||
61 | #define CAT0_VER_HARDWARE 0x04 /* Hardware version */ | ||
62 | #define CAT0_VER_PARAMETER 0x06 /* Parameter version */ | ||
63 | #define CAT0_VER_AWB 0x08 /* Auto WB version */ | ||
60 | #define CAT0_VER_STRING 0x0a /* string including M-5MOLS */ | 64 | #define CAT0_VER_STRING 0x0a /* string including M-5MOLS */ |
61 | #define CAT0_SYSMODE 0x0b /* SYSTEM mode register */ | 65 | #define CAT0_SYSMODE 0x0b /* SYSTEM mode register */ |
62 | #define CAT0_STATUS 0x0c /* SYSTEM mode status register */ | 66 | #define CAT0_STATUS 0x0c /* SYSTEM mode status register */ |
63 | #define CAT0_INT_FACTOR 0x10 /* interrupt pending register */ | 67 | #define CAT0_INT_FACTOR 0x10 /* interrupt pending register */ |
64 | #define CAT0_INT_ENABLE 0x11 /* interrupt enable register */ | 68 | #define CAT0_INT_ENABLE 0x11 /* interrupt enable register */ |
65 | 69 | ||
70 | #define SYSTEM_VER_CUSTOMER I2C_REG(CAT_SYSTEM, CAT0_VER_CUSTOMER, 1) | ||
71 | #define SYSTEM_VER_PROJECT I2C_REG(CAT_SYSTEM, CAT0_VER_PROJECT, 1) | ||
72 | #define SYSTEM_VER_FIRMWARE I2C_REG(CAT_SYSTEM, CAT0_VER_FIRMWARE, 2) | ||
73 | #define SYSTEM_VER_HARDWARE I2C_REG(CAT_SYSTEM, CAT0_VER_HARDWARE, 2) | ||
74 | #define SYSTEM_VER_PARAMETER I2C_REG(CAT_SYSTEM, CAT0_VER_PARAMETER, 2) | ||
75 | #define SYSTEM_VER_AWB I2C_REG(CAT_SYSTEM, CAT0_VER_AWB, 2) | ||
76 | |||
66 | #define SYSTEM_SYSMODE I2C_REG(CAT_SYSTEM, CAT0_SYSMODE, 1) | 77 | #define SYSTEM_SYSMODE I2C_REG(CAT_SYSTEM, CAT0_SYSMODE, 1) |
67 | #define REG_SYSINIT 0x00 /* SYSTEM mode */ | 78 | #define REG_SYSINIT 0x00 /* SYSTEM mode */ |
68 | #define REG_PARAMETER 0x01 /* PARAMETER mode */ | 79 | #define REG_PARAMETER 0x01 /* PARAMETER mode */ |
@@ -382,8 +393,8 @@ | |||
382 | #define REG_CAP_START_MAIN 0x01 | 393 | #define REG_CAP_START_MAIN 0x01 |
383 | #define REG_CAP_START_THUMB 0x03 | 394 | #define REG_CAP_START_THUMB 0x03 |
384 | 395 | ||
385 | #define CAPC_IMAGE_SIZE I2C_REG(CAT_CAPT_CTRL, CATC_CAP_IMAGE_SIZE, 1) | 396 | #define CAPC_IMAGE_SIZE I2C_REG(CAT_CAPT_CTRL, CATC_CAP_IMAGE_SIZE, 4) |
386 | #define CAPC_THUMB_SIZE I2C_REG(CAT_CAPT_CTRL, CATC_CAP_THUMB_SIZE, 1) | 397 | #define CAPC_THUMB_SIZE I2C_REG(CAT_CAPT_CTRL, CATC_CAP_THUMB_SIZE, 4) |
387 | 398 | ||
388 | /* | 399 | /* |
389 | * Category F - Flash | 400 | * Category F - Flash |
diff --git a/drivers/media/video/msp3400-driver.c b/drivers/media/video/msp3400-driver.c index de5d481b0328..c43c81f5f978 100644 --- a/drivers/media/video/msp3400-driver.c +++ b/drivers/media/video/msp3400-driver.c | |||
@@ -480,12 +480,14 @@ static int msp_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) | |||
480 | struct msp_state *state = to_state(sd); | 480 | struct msp_state *state = to_state(sd); |
481 | struct i2c_client *client = v4l2_get_subdevdata(sd); | 481 | struct i2c_client *client = v4l2_get_subdevdata(sd); |
482 | 482 | ||
483 | if (state->radio) | 483 | if (vt->type != V4L2_TUNER_ANALOG_TV) |
484 | return 0; | 484 | return 0; |
485 | if (state->opmode == OPMODE_AUTOSELECT) | 485 | if (!state->radio) { |
486 | msp_detect_stereo(client); | 486 | if (state->opmode == OPMODE_AUTOSELECT) |
487 | vt->audmode = state->audmode; | 487 | msp_detect_stereo(client); |
488 | vt->rxsubchans = state->rxsubchans; | 488 | vt->rxsubchans = state->rxsubchans; |
489 | } | ||
490 | vt->audmode = state->audmode; | ||
489 | vt->capability |= V4L2_TUNER_CAP_STEREO | | 491 | vt->capability |= V4L2_TUNER_CAP_STEREO | |
490 | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; | 492 | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2; |
491 | return 0; | 493 | return 0; |
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c index bc0c23a1009c..63f8a0cc33d8 100644 --- a/drivers/media/video/mx1_camera.c +++ b/drivers/media/video/mx1_camera.c | |||
@@ -444,12 +444,9 @@ static int mx1_camera_add_device(struct soc_camera_device *icd) | |||
444 | { | 444 | { |
445 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); | 445 | struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); |
446 | struct mx1_camera_dev *pcdev = ici->priv; | 446 | struct mx1_camera_dev *pcdev = ici->priv; |
447 | int ret; | ||
448 | 447 | ||
449 | if (pcdev->icd) { | 448 | if (pcdev->icd) |
450 | ret = -EBUSY; | 449 | return -EBUSY; |
451 | goto ebusy; | ||
452 | } | ||
453 | 450 | ||
454 | dev_info(icd->dev.parent, "MX1 Camera driver attached to camera %d\n", | 451 | dev_info(icd->dev.parent, "MX1 Camera driver attached to camera %d\n", |
455 | icd->devnum); | 452 | icd->devnum); |
@@ -458,8 +455,7 @@ static int mx1_camera_add_device(struct soc_camera_device *icd) | |||
458 | 455 | ||
459 | pcdev->icd = icd; | 456 | pcdev->icd = icd; |
460 | 457 | ||
461 | ebusy: | 458 | return 0; |
462 | return ret; | ||
463 | } | 459 | } |
464 | 460 | ||
465 | static void mx1_camera_remove_device(struct soc_camera_device *icd) | 461 | static void mx1_camera_remove_device(struct soc_camera_device *icd) |
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 4ada9be1d430..4d07c5844402 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c | |||
@@ -982,6 +982,14 @@ static int omap_vout_buffer_setup(struct videobuf_queue *q, unsigned int *count, | |||
982 | startindex = (vout->vid == OMAP_VIDEO1) ? | 982 | startindex = (vout->vid == OMAP_VIDEO1) ? |
983 | video1_numbuffers : video2_numbuffers; | 983 | video1_numbuffers : video2_numbuffers; |
984 | 984 | ||
985 | /* Check the size of the buffer */ | ||
986 | if (*size > vout->buffer_size) { | ||
987 | v4l2_err(&vout->vid_dev->v4l2_dev, | ||
988 | "buffer allocation mismatch [%u] [%u]\n", | ||
989 | *size, vout->buffer_size); | ||
990 | return -ENOMEM; | ||
991 | } | ||
992 | |||
985 | for (i = startindex; i < *count; i++) { | 993 | for (i = startindex; i < *count; i++) { |
986 | vout->buffer_size = *size; | 994 | vout->buffer_size = *size; |
987 | 995 | ||
@@ -1228,6 +1236,14 @@ static int omap_vout_mmap(struct file *file, struct vm_area_struct *vma) | |||
1228 | (vma->vm_pgoff << PAGE_SHIFT)); | 1236 | (vma->vm_pgoff << PAGE_SHIFT)); |
1229 | return -EINVAL; | 1237 | return -EINVAL; |
1230 | } | 1238 | } |
1239 | /* Check the size of the buffer */ | ||
1240 | if (size > vout->buffer_size) { | ||
1241 | v4l2_err(&vout->vid_dev->v4l2_dev, | ||
1242 | "insufficient memory [%lu] [%u]\n", | ||
1243 | size, vout->buffer_size); | ||
1244 | return -ENOMEM; | ||
1245 | } | ||
1246 | |||
1231 | q->bufs[i]->baddr = vma->vm_start; | 1247 | q->bufs[i]->baddr = vma->vm_start; |
1232 | 1248 | ||
1233 | vma->vm_flags |= VM_RESERVED; | 1249 | vma->vm_flags |= VM_RESERVED; |
@@ -2391,7 +2407,7 @@ static int __init omap_vout_create_video_devices(struct platform_device *pdev) | |||
2391 | /* Register the Video device with V4L2 | 2407 | /* Register the Video device with V4L2 |
2392 | */ | 2408 | */ |
2393 | vfd = vout->vfd; | 2409 | vfd = vout->vfd; |
2394 | if (video_register_device(vfd, VFL_TYPE_GRABBER, k + 1) < 0) { | 2410 | if (video_register_device(vfd, VFL_TYPE_GRABBER, -1) < 0) { |
2395 | dev_err(&pdev->dev, ": Could not register " | 2411 | dev_err(&pdev->dev, ": Could not register " |
2396 | "Video for Linux device\n"); | 2412 | "Video for Linux device\n"); |
2397 | vfd->minor = -1; | 2413 | vfd->minor = -1; |
diff --git a/drivers/media/video/omap/omap_voutlib.c b/drivers/media/video/omap/omap_voutlib.c index 2aa6a76c5e59..8ae74817a110 100644 --- a/drivers/media/video/omap/omap_voutlib.c +++ b/drivers/media/video/omap/omap_voutlib.c | |||
@@ -193,7 +193,7 @@ int omap_vout_new_crop(struct v4l2_pix_format *pix, | |||
193 | return -EINVAL; | 193 | return -EINVAL; |
194 | 194 | ||
195 | if (cpu_is_omap24xx()) { | 195 | if (cpu_is_omap24xx()) { |
196 | if (crop->height != win->w.height) { | 196 | if (try_crop.height != win->w.height) { |
197 | /* If we're resizing vertically, we can't support a | 197 | /* If we're resizing vertically, we can't support a |
198 | * crop width wider than 768 pixels. | 198 | * crop width wider than 768 pixels. |
199 | */ | 199 | */ |
@@ -202,7 +202,7 @@ int omap_vout_new_crop(struct v4l2_pix_format *pix, | |||
202 | } | 202 | } |
203 | } | 203 | } |
204 | /* vertical resizing */ | 204 | /* vertical resizing */ |
205 | vresize = (1024 * crop->height) / win->w.height; | 205 | vresize = (1024 * try_crop.height) / win->w.height; |
206 | if (cpu_is_omap24xx() && (vresize > 2048)) | 206 | if (cpu_is_omap24xx() && (vresize > 2048)) |
207 | vresize = 2048; | 207 | vresize = 2048; |
208 | else if (cpu_is_omap34xx() && (vresize > 4096)) | 208 | else if (cpu_is_omap34xx() && (vresize > 4096)) |
@@ -221,7 +221,7 @@ int omap_vout_new_crop(struct v4l2_pix_format *pix, | |||
221 | try_crop.height = 2; | 221 | try_crop.height = 2; |
222 | } | 222 | } |
223 | /* horizontal resizing */ | 223 | /* horizontal resizing */ |
224 | hresize = (1024 * crop->width) / win->w.width; | 224 | hresize = (1024 * try_crop.width) / win->w.width; |
225 | if (cpu_is_omap24xx() && (hresize > 2048)) | 225 | if (cpu_is_omap24xx() && (hresize > 2048)) |
226 | hresize = 2048; | 226 | hresize = 2048; |
227 | else if (cpu_is_omap34xx() && (hresize > 4096)) | 227 | else if (cpu_is_omap34xx() && (hresize > 4096)) |
diff --git a/drivers/media/video/omap3isp/isp.c b/drivers/media/video/omap3isp/isp.c index c9fd04ee70a8..94b6ed89e195 100644 --- a/drivers/media/video/omap3isp/isp.c +++ b/drivers/media/video/omap3isp/isp.c | |||
@@ -1748,7 +1748,7 @@ static int isp_register_entities(struct isp_device *isp) | |||
1748 | goto done; | 1748 | goto done; |
1749 | 1749 | ||
1750 | /* Register external entities */ | 1750 | /* Register external entities */ |
1751 | for (subdevs = pdata->subdevs; subdevs->subdevs; ++subdevs) { | 1751 | for (subdevs = pdata->subdevs; subdevs && subdevs->subdevs; ++subdevs) { |
1752 | struct v4l2_subdev *sensor; | 1752 | struct v4l2_subdev *sensor; |
1753 | struct media_entity *input; | 1753 | struct media_entity *input; |
1754 | unsigned int flags; | 1754 | unsigned int flags; |
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c index 9d0dd08f57f8..e98d38212791 100644 --- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c +++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c | |||
@@ -3046,6 +3046,8 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw) | |||
3046 | if (hdw->input_dirty || hdw->audiomode_dirty || hdw->force_dirty) { | 3046 | if (hdw->input_dirty || hdw->audiomode_dirty || hdw->force_dirty) { |
3047 | struct v4l2_tuner vt; | 3047 | struct v4l2_tuner vt; |
3048 | memset(&vt, 0, sizeof(vt)); | 3048 | memset(&vt, 0, sizeof(vt)); |
3049 | vt.type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ? | ||
3050 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
3049 | vt.audmode = hdw->audiomode_val; | 3051 | vt.audmode = hdw->audiomode_val; |
3050 | v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, s_tuner, &vt); | 3052 | v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, s_tuner, &vt); |
3051 | } | 3053 | } |
@@ -5171,6 +5173,8 @@ void pvr2_hdw_status_poll(struct pvr2_hdw *hdw) | |||
5171 | { | 5173 | { |
5172 | struct v4l2_tuner *vtp = &hdw->tuner_signal_info; | 5174 | struct v4l2_tuner *vtp = &hdw->tuner_signal_info; |
5173 | memset(vtp, 0, sizeof(*vtp)); | 5175 | memset(vtp, 0, sizeof(*vtp)); |
5176 | vtp->type = (hdw->input_val == PVR2_CVAL_INPUT_RADIO) ? | ||
5177 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
5174 | hdw->tuner_signal_stale = 0; | 5178 | hdw->tuner_signal_stale = 0; |
5175 | /* Note: There apparently is no replacement for VIDIOC_CROPCAP | 5179 | /* Note: There apparently is no replacement for VIDIOC_CROPCAP |
5176 | using v4l2-subdev - therefore we can't support that AT ALL right | 5180 | using v4l2-subdev - therefore we can't support that AT ALL right |
diff --git a/drivers/media/video/pwc/pwc-ctrl.c b/drivers/media/video/pwc/pwc-ctrl.c index 1593f8deb810..760b4de13adf 100644 --- a/drivers/media/video/pwc/pwc-ctrl.c +++ b/drivers/media/video/pwc/pwc-ctrl.c | |||
@@ -1414,7 +1414,7 @@ long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg) | |||
1414 | { | 1414 | { |
1415 | ARG_DEF(struct pwc_probe, probe) | 1415 | ARG_DEF(struct pwc_probe, probe) |
1416 | 1416 | ||
1417 | strcpy(ARGR(probe).name, pdev->vdev->name); | 1417 | strcpy(ARGR(probe).name, pdev->vdev.name); |
1418 | ARGR(probe).type = pdev->type; | 1418 | ARGR(probe).type = pdev->type; |
1419 | ARG_OUT(probe) | 1419 | ARG_OUT(probe) |
1420 | break; | 1420 | break; |
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 356cd42b593b..b0bde5a87c8a 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c | |||
@@ -40,7 +40,7 @@ | |||
40 | Oh yes, convention: to disctinguish between all the various pointers to | 40 | Oh yes, convention: to disctinguish between all the various pointers to |
41 | device-structures, I use these names for the pointer variables: | 41 | device-structures, I use these names for the pointer variables: |
42 | udev: struct usb_device * | 42 | udev: struct usb_device * |
43 | vdev: struct video_device * | 43 | vdev: struct video_device (member of pwc_dev) |
44 | pdev: struct pwc_devive * | 44 | pdev: struct pwc_devive * |
45 | */ | 45 | */ |
46 | 46 | ||
@@ -152,6 +152,7 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf, | |||
152 | size_t count, loff_t *ppos); | 152 | size_t count, loff_t *ppos); |
153 | static unsigned int pwc_video_poll(struct file *file, poll_table *wait); | 153 | static unsigned int pwc_video_poll(struct file *file, poll_table *wait); |
154 | static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma); | 154 | static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma); |
155 | static void pwc_video_release(struct video_device *vfd); | ||
155 | 156 | ||
156 | static const struct v4l2_file_operations pwc_fops = { | 157 | static const struct v4l2_file_operations pwc_fops = { |
157 | .owner = THIS_MODULE, | 158 | .owner = THIS_MODULE, |
@@ -164,42 +165,12 @@ static const struct v4l2_file_operations pwc_fops = { | |||
164 | }; | 165 | }; |
165 | static struct video_device pwc_template = { | 166 | static struct video_device pwc_template = { |
166 | .name = "Philips Webcam", /* Filled in later */ | 167 | .name = "Philips Webcam", /* Filled in later */ |
167 | .release = video_device_release, | 168 | .release = pwc_video_release, |
168 | .fops = &pwc_fops, | 169 | .fops = &pwc_fops, |
170 | .ioctl_ops = &pwc_ioctl_ops, | ||
169 | }; | 171 | }; |
170 | 172 | ||
171 | /***************************************************************************/ | 173 | /***************************************************************************/ |
172 | |||
173 | /* Okay, this is some magic that I worked out and the reasoning behind it... | ||
174 | |||
175 | The biggest problem with any USB device is of course: "what to do | ||
176 | when the user unplugs the device while it is in use by an application?" | ||
177 | We have several options: | ||
178 | 1) Curse them with the 7 plagues when they do (requires divine intervention) | ||
179 | 2) Tell them not to (won't work: they'll do it anyway) | ||
180 | 3) Oops the kernel (this will have a negative effect on a user's uptime) | ||
181 | 4) Do something sensible. | ||
182 | |||
183 | Of course, we go for option 4. | ||
184 | |||
185 | It happens that this device will be linked to two times, once from | ||
186 | usb_device and once from the video_device in their respective 'private' | ||
187 | pointers. This is done when the device is probed() and all initialization | ||
188 | succeeded. The pwc_device struct links back to both structures. | ||
189 | |||
190 | When a device is unplugged while in use it will be removed from the | ||
191 | list of known USB devices; I also de-register it as a V4L device, but | ||
192 | unfortunately I can't free the memory since the struct is still in use | ||
193 | by the file descriptor. This free-ing is then deferend until the first | ||
194 | opportunity. Crude, but it works. | ||
195 | |||
196 | A small 'advantage' is that if a user unplugs the cam and plugs it back | ||
197 | in, it should get assigned the same video device minor, but unfortunately | ||
198 | it's non-trivial to re-link the cam back to the video device... (that | ||
199 | would surely be magic! :)) | ||
200 | */ | ||
201 | |||
202 | /***************************************************************************/ | ||
203 | /* Private functions */ | 174 | /* Private functions */ |
204 | 175 | ||
205 | /* Here we want the physical address of the memory. | 176 | /* Here we want the physical address of the memory. |
@@ -1016,16 +987,15 @@ static ssize_t show_snapshot_button_status(struct device *class_dev, | |||
1016 | static DEVICE_ATTR(button, S_IRUGO | S_IWUSR, show_snapshot_button_status, | 987 | static DEVICE_ATTR(button, S_IRUGO | S_IWUSR, show_snapshot_button_status, |
1017 | NULL); | 988 | NULL); |
1018 | 989 | ||
1019 | static int pwc_create_sysfs_files(struct video_device *vdev) | 990 | static int pwc_create_sysfs_files(struct pwc_device *pdev) |
1020 | { | 991 | { |
1021 | struct pwc_device *pdev = video_get_drvdata(vdev); | ||
1022 | int rc; | 992 | int rc; |
1023 | 993 | ||
1024 | rc = device_create_file(&vdev->dev, &dev_attr_button); | 994 | rc = device_create_file(&pdev->vdev.dev, &dev_attr_button); |
1025 | if (rc) | 995 | if (rc) |
1026 | goto err; | 996 | goto err; |
1027 | if (pdev->features & FEATURE_MOTOR_PANTILT) { | 997 | if (pdev->features & FEATURE_MOTOR_PANTILT) { |
1028 | rc = device_create_file(&vdev->dev, &dev_attr_pan_tilt); | 998 | rc = device_create_file(&pdev->vdev.dev, &dev_attr_pan_tilt); |
1029 | if (rc) | 999 | if (rc) |
1030 | goto err_button; | 1000 | goto err_button; |
1031 | } | 1001 | } |
@@ -1033,19 +1003,17 @@ static int pwc_create_sysfs_files(struct video_device *vdev) | |||
1033 | return 0; | 1003 | return 0; |
1034 | 1004 | ||
1035 | err_button: | 1005 | err_button: |
1036 | device_remove_file(&vdev->dev, &dev_attr_button); | 1006 | device_remove_file(&pdev->vdev.dev, &dev_attr_button); |
1037 | err: | 1007 | err: |
1038 | PWC_ERROR("Could not create sysfs files.\n"); | 1008 | PWC_ERROR("Could not create sysfs files.\n"); |
1039 | return rc; | 1009 | return rc; |
1040 | } | 1010 | } |
1041 | 1011 | ||
1042 | static void pwc_remove_sysfs_files(struct video_device *vdev) | 1012 | static void pwc_remove_sysfs_files(struct pwc_device *pdev) |
1043 | { | 1013 | { |
1044 | struct pwc_device *pdev = video_get_drvdata(vdev); | ||
1045 | |||
1046 | if (pdev->features & FEATURE_MOTOR_PANTILT) | 1014 | if (pdev->features & FEATURE_MOTOR_PANTILT) |
1047 | device_remove_file(&vdev->dev, &dev_attr_pan_tilt); | 1015 | device_remove_file(&pdev->vdev.dev, &dev_attr_pan_tilt); |
1048 | device_remove_file(&vdev->dev, &dev_attr_button); | 1016 | device_remove_file(&pdev->vdev.dev, &dev_attr_button); |
1049 | } | 1017 | } |
1050 | 1018 | ||
1051 | #ifdef CONFIG_USB_PWC_DEBUG | 1019 | #ifdef CONFIG_USB_PWC_DEBUG |
@@ -1106,7 +1074,7 @@ static int pwc_video_open(struct file *file) | |||
1106 | if (ret >= 0) | 1074 | if (ret >= 0) |
1107 | { | 1075 | { |
1108 | PWC_DEBUG_OPEN("This %s camera is equipped with a %s (%d).\n", | 1076 | PWC_DEBUG_OPEN("This %s camera is equipped with a %s (%d).\n", |
1109 | pdev->vdev->name, | 1077 | pdev->vdev.name, |
1110 | pwc_sensor_type_to_string(i), i); | 1078 | pwc_sensor_type_to_string(i), i); |
1111 | } | 1079 | } |
1112 | } | 1080 | } |
@@ -1180,16 +1148,15 @@ static int pwc_video_open(struct file *file) | |||
1180 | return 0; | 1148 | return 0; |
1181 | } | 1149 | } |
1182 | 1150 | ||
1183 | 1151 | static void pwc_video_release(struct video_device *vfd) | |
1184 | static void pwc_cleanup(struct pwc_device *pdev) | ||
1185 | { | 1152 | { |
1186 | pwc_remove_sysfs_files(pdev->vdev); | 1153 | struct pwc_device *pdev = container_of(vfd, struct pwc_device, vdev); |
1187 | video_unregister_device(pdev->vdev); | 1154 | int hint; |
1188 | 1155 | ||
1189 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV | 1156 | /* search device_hint[] table if we occupy a slot, by any chance */ |
1190 | if (pdev->button_dev) | 1157 | for (hint = 0; hint < MAX_DEV_HINTS; hint++) |
1191 | input_unregister_device(pdev->button_dev); | 1158 | if (device_hint[hint].pdev == pdev) |
1192 | #endif | 1159 | device_hint[hint].pdev = NULL; |
1193 | 1160 | ||
1194 | kfree(pdev); | 1161 | kfree(pdev); |
1195 | } | 1162 | } |
@@ -1199,7 +1166,7 @@ static int pwc_video_close(struct file *file) | |||
1199 | { | 1166 | { |
1200 | struct video_device *vdev = file->private_data; | 1167 | struct video_device *vdev = file->private_data; |
1201 | struct pwc_device *pdev; | 1168 | struct pwc_device *pdev; |
1202 | int i, hint; | 1169 | int i; |
1203 | 1170 | ||
1204 | PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); | 1171 | PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); |
1205 | 1172 | ||
@@ -1234,12 +1201,6 @@ static int pwc_video_close(struct file *file) | |||
1234 | } | 1201 | } |
1235 | pdev->vopen--; | 1202 | pdev->vopen--; |
1236 | PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen); | 1203 | PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen); |
1237 | } else { | ||
1238 | pwc_cleanup(pdev); | ||
1239 | /* search device_hint[] table if we occupy a slot, by any chance */ | ||
1240 | for (hint = 0; hint < MAX_DEV_HINTS; hint++) | ||
1241 | if (device_hint[hint].pdev == pdev) | ||
1242 | device_hint[hint].pdev = NULL; | ||
1243 | } | 1204 | } |
1244 | 1205 | ||
1245 | return 0; | 1206 | return 0; |
@@ -1715,19 +1676,12 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1715 | init_waitqueue_head(&pdev->frameq); | 1676 | init_waitqueue_head(&pdev->frameq); |
1716 | pdev->vcompression = pwc_preferred_compression; | 1677 | pdev->vcompression = pwc_preferred_compression; |
1717 | 1678 | ||
1718 | /* Allocate video_device structure */ | 1679 | /* Init video_device structure */ |
1719 | pdev->vdev = video_device_alloc(); | 1680 | memcpy(&pdev->vdev, &pwc_template, sizeof(pwc_template)); |
1720 | if (!pdev->vdev) { | 1681 | pdev->vdev.parent = &intf->dev; |
1721 | PWC_ERROR("Err, cannot allocate video_device struture. Failing probe."); | 1682 | pdev->vdev.lock = &pdev->modlock; |
1722 | rc = -ENOMEM; | 1683 | strcpy(pdev->vdev.name, name); |
1723 | goto err_free_mem; | 1684 | video_set_drvdata(&pdev->vdev, pdev); |
1724 | } | ||
1725 | memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template)); | ||
1726 | pdev->vdev->parent = &intf->dev; | ||
1727 | pdev->vdev->lock = &pdev->modlock; | ||
1728 | pdev->vdev->ioctl_ops = &pwc_ioctl_ops; | ||
1729 | strcpy(pdev->vdev->name, name); | ||
1730 | video_set_drvdata(pdev->vdev, pdev); | ||
1731 | 1685 | ||
1732 | pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); | 1686 | pdev->release = le16_to_cpu(udev->descriptor.bcdDevice); |
1733 | PWC_DEBUG_PROBE("Release: %04x\n", pdev->release); | 1687 | PWC_DEBUG_PROBE("Release: %04x\n", pdev->release); |
@@ -1746,8 +1700,6 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1746 | } | 1700 | } |
1747 | } | 1701 | } |
1748 | 1702 | ||
1749 | pdev->vdev->release = video_device_release; | ||
1750 | |||
1751 | /* occupy slot */ | 1703 | /* occupy slot */ |
1752 | if (hint < MAX_DEV_HINTS) | 1704 | if (hint < MAX_DEV_HINTS) |
1753 | device_hint[hint].pdev = pdev; | 1705 | device_hint[hint].pdev = pdev; |
@@ -1759,16 +1711,16 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1759 | pwc_set_leds(pdev, 0, 0); | 1711 | pwc_set_leds(pdev, 0, 0); |
1760 | pwc_camera_power(pdev, 0); | 1712 | pwc_camera_power(pdev, 0); |
1761 | 1713 | ||
1762 | rc = video_register_device(pdev->vdev, VFL_TYPE_GRABBER, video_nr); | 1714 | rc = video_register_device(&pdev->vdev, VFL_TYPE_GRABBER, video_nr); |
1763 | if (rc < 0) { | 1715 | if (rc < 0) { |
1764 | PWC_ERROR("Failed to register as video device (%d).\n", rc); | 1716 | PWC_ERROR("Failed to register as video device (%d).\n", rc); |
1765 | goto err_video_release; | 1717 | goto err_free_mem; |
1766 | } | 1718 | } |
1767 | rc = pwc_create_sysfs_files(pdev->vdev); | 1719 | rc = pwc_create_sysfs_files(pdev); |
1768 | if (rc) | 1720 | if (rc) |
1769 | goto err_video_unreg; | 1721 | goto err_video_unreg; |
1770 | 1722 | ||
1771 | PWC_INFO("Registered as %s.\n", video_device_node_name(pdev->vdev)); | 1723 | PWC_INFO("Registered as %s.\n", video_device_node_name(&pdev->vdev)); |
1772 | 1724 | ||
1773 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV | 1725 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV |
1774 | /* register webcam snapshot button input device */ | 1726 | /* register webcam snapshot button input device */ |
@@ -1776,7 +1728,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1776 | if (!pdev->button_dev) { | 1728 | if (!pdev->button_dev) { |
1777 | PWC_ERROR("Err, insufficient memory for webcam snapshot button device."); | 1729 | PWC_ERROR("Err, insufficient memory for webcam snapshot button device."); |
1778 | rc = -ENOMEM; | 1730 | rc = -ENOMEM; |
1779 | pwc_remove_sysfs_files(pdev->vdev); | 1731 | pwc_remove_sysfs_files(pdev); |
1780 | goto err_video_unreg; | 1732 | goto err_video_unreg; |
1781 | } | 1733 | } |
1782 | 1734 | ||
@@ -1794,7 +1746,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1794 | if (rc) { | 1746 | if (rc) { |
1795 | input_free_device(pdev->button_dev); | 1747 | input_free_device(pdev->button_dev); |
1796 | pdev->button_dev = NULL; | 1748 | pdev->button_dev = NULL; |
1797 | pwc_remove_sysfs_files(pdev->vdev); | 1749 | pwc_remove_sysfs_files(pdev); |
1798 | goto err_video_unreg; | 1750 | goto err_video_unreg; |
1799 | } | 1751 | } |
1800 | #endif | 1752 | #endif |
@@ -1804,10 +1756,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id | |||
1804 | err_video_unreg: | 1756 | err_video_unreg: |
1805 | if (hint < MAX_DEV_HINTS) | 1757 | if (hint < MAX_DEV_HINTS) |
1806 | device_hint[hint].pdev = NULL; | 1758 | device_hint[hint].pdev = NULL; |
1807 | video_unregister_device(pdev->vdev); | 1759 | video_unregister_device(&pdev->vdev); |
1808 | pdev->vdev = NULL; /* So we don't try to release it below */ | ||
1809 | err_video_release: | ||
1810 | video_device_release(pdev->vdev); | ||
1811 | err_free_mem: | 1760 | err_free_mem: |
1812 | kfree(pdev); | 1761 | kfree(pdev); |
1813 | return rc; | 1762 | return rc; |
@@ -1816,10 +1765,8 @@ err_free_mem: | |||
1816 | /* The user yanked out the cable... */ | 1765 | /* The user yanked out the cable... */ |
1817 | static void usb_pwc_disconnect(struct usb_interface *intf) | 1766 | static void usb_pwc_disconnect(struct usb_interface *intf) |
1818 | { | 1767 | { |
1819 | struct pwc_device *pdev; | 1768 | struct pwc_device *pdev = usb_get_intfdata(intf); |
1820 | int hint; | ||
1821 | 1769 | ||
1822 | pdev = usb_get_intfdata (intf); | ||
1823 | mutex_lock(&pdev->modlock); | 1770 | mutex_lock(&pdev->modlock); |
1824 | usb_set_intfdata (intf, NULL); | 1771 | usb_set_intfdata (intf, NULL); |
1825 | if (pdev == NULL) { | 1772 | if (pdev == NULL) { |
@@ -1836,30 +1783,25 @@ static void usb_pwc_disconnect(struct usb_interface *intf) | |||
1836 | } | 1783 | } |
1837 | 1784 | ||
1838 | /* We got unplugged; this is signalled by an EPIPE error code */ | 1785 | /* We got unplugged; this is signalled by an EPIPE error code */ |
1839 | if (pdev->vopen) { | 1786 | pdev->error_status = EPIPE; |
1840 | PWC_INFO("Disconnected while webcam is in use!\n"); | 1787 | pdev->unplugged = 1; |
1841 | pdev->error_status = EPIPE; | ||
1842 | } | ||
1843 | 1788 | ||
1844 | /* Alert waiting processes */ | 1789 | /* Alert waiting processes */ |
1845 | wake_up_interruptible(&pdev->frameq); | 1790 | wake_up_interruptible(&pdev->frameq); |
1846 | /* Wait until device is closed */ | ||
1847 | if (pdev->vopen) { | ||
1848 | pdev->unplugged = 1; | ||
1849 | pwc_iso_stop(pdev); | ||
1850 | } else { | ||
1851 | /* Device is closed, so we can safely unregister it */ | ||
1852 | PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n"); | ||
1853 | 1791 | ||
1854 | disconnect_out: | 1792 | /* No need to keep the urbs around after disconnection */ |
1855 | /* search device_hint[] table if we occupy a slot, by any chance */ | 1793 | pwc_isoc_cleanup(pdev); |
1856 | for (hint = 0; hint < MAX_DEV_HINTS; hint++) | ||
1857 | if (device_hint[hint].pdev == pdev) | ||
1858 | device_hint[hint].pdev = NULL; | ||
1859 | } | ||
1860 | 1794 | ||
1795 | disconnect_out: | ||
1861 | mutex_unlock(&pdev->modlock); | 1796 | mutex_unlock(&pdev->modlock); |
1862 | pwc_cleanup(pdev); | 1797 | |
1798 | pwc_remove_sysfs_files(pdev); | ||
1799 | video_unregister_device(&pdev->vdev); | ||
1800 | |||
1801 | #ifdef CONFIG_USB_PWC_INPUT_EVDEV | ||
1802 | if (pdev->button_dev) | ||
1803 | input_unregister_device(pdev->button_dev); | ||
1804 | #endif | ||
1863 | } | 1805 | } |
1864 | 1806 | ||
1865 | 1807 | ||
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index e947766337d6..083f8b15df73 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h | |||
@@ -162,9 +162,9 @@ struct pwc_imgbuf | |||
162 | 162 | ||
163 | struct pwc_device | 163 | struct pwc_device |
164 | { | 164 | { |
165 | struct video_device *vdev; | 165 | struct video_device vdev; |
166 | 166 | ||
167 | /* Pointer to our usb_device */ | 167 | /* Pointer to our usb_device, may be NULL after unplug */ |
168 | struct usb_device *udev; | 168 | struct usb_device *udev; |
169 | 169 | ||
170 | int type; /* type of cam (645, 646, 675, 680, 690, 720, 730, 740, 750) */ | 170 | int type; /* type of cam (645, 646, 675, 680, 690, 720, 730, 740, 750) */ |
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c index d142b40ea64e..81b4a826ee5e 100644 --- a/drivers/media/video/s5p-fimc/fimc-capture.c +++ b/drivers/media/video/s5p-fimc/fimc-capture.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Samsung S5P SoC series camera interface (camera capture) driver | 2 | * Samsung S5P/EXYNOS4 SoC series camera interface (camera capture) driver |
3 | * | 3 | * |
4 | * Copyright (c) 2010 Samsung Electronics Co., Ltd | 4 | * Copyright (C) 2010 - 2011 Samsung Electronics Co., Ltd. |
5 | * Author: Sylwester Nawrocki, <s.nawrocki@samsung.com> | 5 | * Author: Sylwester Nawrocki, <s.nawrocki@samsung.com> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -262,12 +262,7 @@ static unsigned int get_plane_size(struct fimc_frame *fr, unsigned int plane) | |||
262 | { | 262 | { |
263 | if (!fr || plane >= fr->fmt->memplanes) | 263 | if (!fr || plane >= fr->fmt->memplanes) |
264 | return 0; | 264 | return 0; |
265 | |||
266 | dbg("%s: w: %d. h: %d. depth[%d]: %d", | ||
267 | __func__, fr->width, fr->height, plane, fr->fmt->depth[plane]); | ||
268 | |||
269 | return fr->f_width * fr->f_height * fr->fmt->depth[plane] / 8; | 265 | return fr->f_width * fr->f_height * fr->fmt->depth[plane] / 8; |
270 | |||
271 | } | 266 | } |
272 | 267 | ||
273 | static int queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, | 268 | static int queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, |
@@ -283,24 +278,14 @@ static int queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, | |||
283 | 278 | ||
284 | *num_planes = fmt->memplanes; | 279 | *num_planes = fmt->memplanes; |
285 | 280 | ||
286 | dbg("%s, buffer count=%d, plane count=%d", | ||
287 | __func__, *num_buffers, *num_planes); | ||
288 | |||
289 | for (i = 0; i < fmt->memplanes; i++) { | 281 | for (i = 0; i < fmt->memplanes; i++) { |
290 | sizes[i] = get_plane_size(&ctx->d_frame, i); | 282 | sizes[i] = get_plane_size(&ctx->d_frame, i); |
291 | dbg("plane: %u, plane_size: %lu", i, sizes[i]); | ||
292 | allocators[i] = ctx->fimc_dev->alloc_ctx; | 283 | allocators[i] = ctx->fimc_dev->alloc_ctx; |
293 | } | 284 | } |
294 | 285 | ||
295 | return 0; | 286 | return 0; |
296 | } | 287 | } |
297 | 288 | ||
298 | static int buffer_init(struct vb2_buffer *vb) | ||
299 | { | ||
300 | /* TODO: */ | ||
301 | return 0; | ||
302 | } | ||
303 | |||
304 | static int buffer_prepare(struct vb2_buffer *vb) | 289 | static int buffer_prepare(struct vb2_buffer *vb) |
305 | { | 290 | { |
306 | struct vb2_queue *vq = vb->vb2_queue; | 291 | struct vb2_queue *vq = vb->vb2_queue; |
@@ -380,7 +365,6 @@ static struct vb2_ops fimc_capture_qops = { | |||
380 | .queue_setup = queue_setup, | 365 | .queue_setup = queue_setup, |
381 | .buf_prepare = buffer_prepare, | 366 | .buf_prepare = buffer_prepare, |
382 | .buf_queue = buffer_queue, | 367 | .buf_queue = buffer_queue, |
383 | .buf_init = buffer_init, | ||
384 | .wait_prepare = fimc_unlock, | 368 | .wait_prepare = fimc_unlock, |
385 | .wait_finish = fimc_lock, | 369 | .wait_finish = fimc_lock, |
386 | .start_streaming = start_streaming, | 370 | .start_streaming = start_streaming, |
@@ -903,6 +887,7 @@ err_vd_reg: | |||
903 | err_v4l2_reg: | 887 | err_v4l2_reg: |
904 | v4l2_device_unregister(v4l2_dev); | 888 | v4l2_device_unregister(v4l2_dev); |
905 | err_info: | 889 | err_info: |
890 | kfree(ctx); | ||
906 | dev_err(&fimc->pdev->dev, "failed to install\n"); | 891 | dev_err(&fimc->pdev->dev, "failed to install\n"); |
907 | return ret; | 892 | return ret; |
908 | } | 893 | } |
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c index dc91a8511af6..bdf19ada9172 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.c +++ b/drivers/media/video/s5p-fimc/fimc-core.c | |||
@@ -1,9 +1,8 @@ | |||
1 | /* | 1 | /* |
2 | * S5P camera interface (video postprocessor) driver | 2 | * Samsung S5P/EXYNOS4 SoC series camera interface (video postprocessor) driver |
3 | * | 3 | * |
4 | * Copyright (c) 2010 Samsung Electronics Co., Ltd | 4 | * Copyright (C) 2010-2011 Samsung Electronics Co., Ltd. |
5 | * | 5 | * Contact: Sylwester Nawrocki, <s.nawrocki@samsung.com> |
6 | * Sylwester Nawrocki, <s.nawrocki@samsung.com> | ||
7 | * | 6 | * |
8 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published | 8 | * it under the terms of the GNU General Public License as published |
@@ -42,7 +41,6 @@ static struct fimc_fmt fimc_formats[] = { | |||
42 | .color = S5P_FIMC_RGB565, | 41 | .color = S5P_FIMC_RGB565, |
43 | .memplanes = 1, | 42 | .memplanes = 1, |
44 | .colplanes = 1, | 43 | .colplanes = 1, |
45 | .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_BE, | ||
46 | .flags = FMT_FLAGS_M2M, | 44 | .flags = FMT_FLAGS_M2M, |
47 | }, { | 45 | }, { |
48 | .name = "BGR666", | 46 | .name = "BGR666", |
@@ -232,11 +230,7 @@ static int fimc_get_scaler_factor(u32 src, u32 tar, u32 *ratio, u32 *shift) | |||
232 | return 0; | 230 | return 0; |
233 | } | 231 | } |
234 | } | 232 | } |
235 | |||
236 | *shift = 0, *ratio = 1; | 233 | *shift = 0, *ratio = 1; |
237 | |||
238 | dbg("s: %d, t: %d, shift: %d, ratio: %d", | ||
239 | src, tar, *shift, *ratio); | ||
240 | return 0; | 234 | return 0; |
241 | } | 235 | } |
242 | 236 | ||
@@ -268,10 +262,8 @@ int fimc_set_scaler_info(struct fimc_ctx *ctx) | |||
268 | err("invalid source size: %d x %d", sx, sy); | 262 | err("invalid source size: %d x %d", sx, sy); |
269 | return -EINVAL; | 263 | return -EINVAL; |
270 | } | 264 | } |
271 | |||
272 | sc->real_width = sx; | 265 | sc->real_width = sx; |
273 | sc->real_height = sy; | 266 | sc->real_height = sy; |
274 | dbg("sx= %d, sy= %d, tx= %d, ty= %d", sx, sy, tx, ty); | ||
275 | 267 | ||
276 | ret = fimc_get_scaler_factor(sx, tx, &sc->pre_hratio, &sc->hfactor); | 268 | ret = fimc_get_scaler_factor(sx, tx, &sc->pre_hratio, &sc->hfactor); |
277 | if (ret) | 269 | if (ret) |
@@ -711,22 +703,18 @@ static int fimc_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, | |||
711 | f = ctx_get_frame(ctx, vq->type); | 703 | f = ctx_get_frame(ctx, vq->type); |
712 | if (IS_ERR(f)) | 704 | if (IS_ERR(f)) |
713 | return PTR_ERR(f); | 705 | return PTR_ERR(f); |
714 | |||
715 | /* | 706 | /* |
716 | * Return number of non-contigous planes (plane buffers) | 707 | * Return number of non-contigous planes (plane buffers) |
717 | * depending on the configured color format. | 708 | * depending on the configured color format. |
718 | */ | 709 | */ |
719 | if (f->fmt) | 710 | if (!f->fmt) |
720 | *num_planes = f->fmt->memplanes; | 711 | return -EINVAL; |
721 | 712 | ||
713 | *num_planes = f->fmt->memplanes; | ||
722 | for (i = 0; i < f->fmt->memplanes; i++) { | 714 | for (i = 0; i < f->fmt->memplanes; i++) { |
723 | sizes[i] = (f->width * f->height * f->fmt->depth[i]) >> 3; | 715 | sizes[i] = (f->f_width * f->f_height * f->fmt->depth[i]) / 8; |
724 | allocators[i] = ctx->fimc_dev->alloc_ctx; | 716 | allocators[i] = ctx->fimc_dev->alloc_ctx; |
725 | } | 717 | } |
726 | |||
727 | if (*num_buffers == 0) | ||
728 | *num_buffers = 1; | ||
729 | |||
730 | return 0; | 718 | return 0; |
731 | } | 719 | } |
732 | 720 | ||
@@ -852,7 +840,7 @@ struct fimc_fmt *find_format(struct v4l2_format *f, unsigned int mask) | |||
852 | 840 | ||
853 | for (i = 0; i < ARRAY_SIZE(fimc_formats); ++i) { | 841 | for (i = 0; i < ARRAY_SIZE(fimc_formats); ++i) { |
854 | fmt = &fimc_formats[i]; | 842 | fmt = &fimc_formats[i]; |
855 | if (fmt->fourcc == f->fmt.pix.pixelformat && | 843 | if (fmt->fourcc == f->fmt.pix_mp.pixelformat && |
856 | (fmt->flags & mask)) | 844 | (fmt->flags & mask)) |
857 | break; | 845 | break; |
858 | } | 846 | } |
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h index 3beb1e5320ce..1f70772daaf0 100644 --- a/drivers/media/video/s5p-fimc/fimc-core.h +++ b/drivers/media/video/s5p-fimc/fimc-core.h | |||
@@ -1,7 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2010 Samsung Electronics | 2 | * Copyright (C) 2010 - 2011 Samsung Electronics Co., Ltd. |
3 | * | ||
4 | * Sylwester Nawrocki, <s.nawrocki@samsung.com> | ||
5 | * | 3 | * |
6 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 5 | * it under the terms of the GNU General Public License version 2 as |
@@ -135,9 +133,10 @@ enum fimc_color_fmt { | |||
135 | * @name: format description | 133 | * @name: format description |
136 | * @fourcc: the fourcc code for this format, 0 if not applicable | 134 | * @fourcc: the fourcc code for this format, 0 if not applicable |
137 | * @color: the corresponding fimc_color_fmt | 135 | * @color: the corresponding fimc_color_fmt |
138 | * @depth: per plane driver's private 'number of bits per pixel' | ||
139 | * @memplanes: number of physically non-contiguous data planes | 136 | * @memplanes: number of physically non-contiguous data planes |
140 | * @colplanes: number of physically contiguous data planes | 137 | * @colplanes: number of physically contiguous data planes |
138 | * @depth: per plane driver's private 'number of bits per pixel' | ||
139 | * @flags: flags indicating which operation mode format applies to | ||
141 | */ | 140 | */ |
142 | struct fimc_fmt { | 141 | struct fimc_fmt { |
143 | enum v4l2_mbus_pixelcode mbus_code; | 142 | enum v4l2_mbus_pixelcode mbus_code; |
@@ -171,7 +170,7 @@ struct fimc_dma_offset { | |||
171 | }; | 170 | }; |
172 | 171 | ||
173 | /** | 172 | /** |
174 | * struct fimc_effect - the configuration data for the "Arbitrary" image effect | 173 | * struct fimc_effect - color effect information |
175 | * @type: effect type | 174 | * @type: effect type |
176 | * @pat_cb: cr value when type is "arbitrary" | 175 | * @pat_cb: cr value when type is "arbitrary" |
177 | * @pat_cr: cr value when type is "arbitrary" | 176 | * @pat_cr: cr value when type is "arbitrary" |
@@ -184,7 +183,6 @@ struct fimc_effect { | |||
184 | 183 | ||
185 | /** | 184 | /** |
186 | * struct fimc_scaler - the configuration data for FIMC inetrnal scaler | 185 | * struct fimc_scaler - the configuration data for FIMC inetrnal scaler |
187 | * | ||
188 | * @scaleup_h: flag indicating scaling up horizontally | 186 | * @scaleup_h: flag indicating scaling up horizontally |
189 | * @scaleup_v: flag indicating scaling up vertically | 187 | * @scaleup_v: flag indicating scaling up vertically |
190 | * @copy_mode: flag indicating transparent DMA transfer (no scaling | 188 | * @copy_mode: flag indicating transparent DMA transfer (no scaling |
@@ -220,7 +218,6 @@ struct fimc_scaler { | |||
220 | 218 | ||
221 | /** | 219 | /** |
222 | * struct fimc_addr - the FIMC physical address set for DMA | 220 | * struct fimc_addr - the FIMC physical address set for DMA |
223 | * | ||
224 | * @y: luminance plane physical address | 221 | * @y: luminance plane physical address |
225 | * @cb: Cb plane physical address | 222 | * @cb: Cb plane physical address |
226 | * @cr: Cr plane physical address | 223 | * @cr: Cr plane physical address |
@@ -234,6 +231,7 @@ struct fimc_addr { | |||
234 | /** | 231 | /** |
235 | * struct fimc_vid_buffer - the driver's video buffer | 232 | * struct fimc_vid_buffer - the driver's video buffer |
236 | * @vb: v4l videobuf buffer | 233 | * @vb: v4l videobuf buffer |
234 | * @list: linked list structure for buffer queue | ||
237 | * @paddr: precalculated physical address set | 235 | * @paddr: precalculated physical address set |
238 | * @index: buffer index for the output DMA engine | 236 | * @index: buffer index for the output DMA engine |
239 | */ | 237 | */ |
@@ -254,11 +252,10 @@ struct fimc_vid_buffer { | |||
254 | * @offs_v: image vertical pixel offset | 252 | * @offs_v: image vertical pixel offset |
255 | * @width: image pixel width | 253 | * @width: image pixel width |
256 | * @height: image pixel weight | 254 | * @height: image pixel weight |
257 | * @paddr: image frame buffer physical addresses | ||
258 | * @buf_cnt: number of buffers depending on a color format | ||
259 | * @payload: image size in bytes (w x h x bpp) | 255 | * @payload: image size in bytes (w x h x bpp) |
260 | * @color: color format | 256 | * @paddr: image frame buffer physical addresses |
261 | * @dma_offset: DMA offset in bytes | 257 | * @dma_offset: DMA offset in bytes |
258 | * @fmt: fimc color format pointer | ||
262 | */ | 259 | */ |
263 | struct fimc_frame { | 260 | struct fimc_frame { |
264 | u32 f_width; | 261 | u32 f_width; |
@@ -390,21 +387,22 @@ struct fimc_ctx; | |||
390 | 387 | ||
391 | /** | 388 | /** |
392 | * struct fimc_dev - abstraction for FIMC entity | 389 | * struct fimc_dev - abstraction for FIMC entity |
393 | * | ||
394 | * @slock: the spinlock protecting this data structure | 390 | * @slock: the spinlock protecting this data structure |
395 | * @lock: the mutex protecting this data structure | 391 | * @lock: the mutex protecting this data structure |
396 | * @pdev: pointer to the FIMC platform device | 392 | * @pdev: pointer to the FIMC platform device |
397 | * @pdata: pointer to the device platform data | 393 | * @pdata: pointer to the device platform data |
394 | * @variant: the IP variant information | ||
398 | * @id: FIMC device index (0..FIMC_MAX_DEVS) | 395 | * @id: FIMC device index (0..FIMC_MAX_DEVS) |
399 | * @num_clocks: the number of clocks managed by this device instance | 396 | * @num_clocks: the number of clocks managed by this device instance |
400 | * @clock[]: the clocks required for FIMC operation | 397 | * @clock: clocks required for FIMC operation |
401 | * @regs: the mapped hardware registers | 398 | * @regs: the mapped hardware registers |
402 | * @regs_res: the resource claimed for IO registers | 399 | * @regs_res: the resource claimed for IO registers |
403 | * @irq: interrupt number of the FIMC subdevice | 400 | * @irq: FIMC interrupt number |
404 | * @irq_queue: | 401 | * @irq_queue: interrupt handler waitqueue |
405 | * @m2m: memory-to-memory V4L2 device information | 402 | * @m2m: memory-to-memory V4L2 device information |
406 | * @vid_cap: camera capture device information | 403 | * @vid_cap: camera capture device information |
407 | * @state: flags used to synchronize m2m and capture mode operation | 404 | * @state: flags used to synchronize m2m and capture mode operation |
405 | * @alloc_ctx: videobuf2 memory allocator context | ||
408 | */ | 406 | */ |
409 | struct fimc_dev { | 407 | struct fimc_dev { |
410 | spinlock_t slock; | 408 | spinlock_t slock; |
@@ -427,8 +425,7 @@ struct fimc_dev { | |||
427 | 425 | ||
428 | /** | 426 | /** |
429 | * fimc_ctx - the device context data | 427 | * fimc_ctx - the device context data |
430 | * | 428 | * @slock: spinlock protecting this data structure |
431 | * @lock: mutex protecting this data structure | ||
432 | * @s_frame: source frame properties | 429 | * @s_frame: source frame properties |
433 | * @d_frame: destination frame properties | 430 | * @d_frame: destination frame properties |
434 | * @out_order_1p: output 1-plane YCBCR order | 431 | * @out_order_1p: output 1-plane YCBCR order |
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c index ff6c0e97563e..d4ee24bf6928 100644 --- a/drivers/media/video/saa7134/saa7134-input.c +++ b/drivers/media/video/saa7134/saa7134-input.c | |||
@@ -963,7 +963,7 @@ static int saa7134_raw_decode_irq(struct saa7134_dev *dev) | |||
963 | * to work with other protocols. | 963 | * to work with other protocols. |
964 | */ | 964 | */ |
965 | if (!ir->active) { | 965 | if (!ir->active) { |
966 | timeout = jiffies + jiffies_to_msecs(15); | 966 | timeout = jiffies + msecs_to_jiffies(15); |
967 | mod_timer(&ir->timer, timeout); | 967 | mod_timer(&ir->timer, timeout); |
968 | ir->active = true; | 968 | ir->active = true; |
969 | } | 969 | } |
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 9363ed91a4cb..a03945ab9f08 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
@@ -714,29 +714,34 @@ static int tuner_remove(struct i2c_client *client) | |||
714 | * returns 0. | 714 | * returns 0. |
715 | * This function is needed for boards that have a separate tuner for | 715 | * This function is needed for boards that have a separate tuner for |
716 | * radio (like devices with tea5767). | 716 | * radio (like devices with tea5767). |
717 | * NOTE: mt20xx uses V4L2_TUNER_DIGITAL_TV and calls set_tv_freq to | ||
718 | * select a TV frequency. So, t_mode = T_ANALOG_TV could actually | ||
719 | * be used to represent a Digital TV too. | ||
717 | */ | 720 | */ |
718 | static inline int check_mode(struct tuner *t, enum v4l2_tuner_type mode) | 721 | static inline int check_mode(struct tuner *t, enum v4l2_tuner_type mode) |
719 | { | 722 | { |
720 | if ((1 << mode & t->mode_mask) == 0) | 723 | int t_mode; |
724 | if (mode == V4L2_TUNER_RADIO) | ||
725 | t_mode = T_RADIO; | ||
726 | else | ||
727 | t_mode = T_ANALOG_TV; | ||
728 | |||
729 | if ((t_mode & t->mode_mask) == 0) | ||
721 | return -EINVAL; | 730 | return -EINVAL; |
722 | 731 | ||
723 | return 0; | 732 | return 0; |
724 | } | 733 | } |
725 | 734 | ||
726 | /** | 735 | /** |
727 | * set_mode_freq - Switch tuner to other mode. | 736 | * set_mode - Switch tuner to other mode. |
728 | * @client: struct i2c_client pointer | ||
729 | * @t: a pointer to the module's internal struct_tuner | 737 | * @t: a pointer to the module's internal struct_tuner |
730 | * @mode: enum v4l2_type (radio or TV) | 738 | * @mode: enum v4l2_type (radio or TV) |
731 | * @freq: frequency to set (0 means to use the previous one) | ||
732 | * | 739 | * |
733 | * If tuner doesn't support the needed mode (radio or TV), prints a | 740 | * If tuner doesn't support the needed mode (radio or TV), prints a |
734 | * debug message and returns -EINVAL, changing its state to standby. | 741 | * debug message and returns -EINVAL, changing its state to standby. |
735 | * Otherwise, changes the state and sets frequency to the last value, if | 742 | * Otherwise, changes the mode and returns 0. |
736 | * the tuner can sleep or if it supports both Radio and TV. | ||
737 | */ | 743 | */ |
738 | static int set_mode_freq(struct i2c_client *client, struct tuner *t, | 744 | static int set_mode(struct tuner *t, enum v4l2_tuner_type mode) |
739 | enum v4l2_tuner_type mode, unsigned int freq) | ||
740 | { | 745 | { |
741 | struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; | 746 | struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; |
742 | 747 | ||
@@ -752,17 +757,27 @@ static int set_mode_freq(struct i2c_client *client, struct tuner *t, | |||
752 | t->mode = mode; | 757 | t->mode = mode; |
753 | tuner_dbg("Changing to mode %d\n", mode); | 758 | tuner_dbg("Changing to mode %d\n", mode); |
754 | } | 759 | } |
760 | return 0; | ||
761 | } | ||
762 | |||
763 | /** | ||
764 | * set_freq - Set the tuner to the desired frequency. | ||
765 | * @t: a pointer to the module's internal struct_tuner | ||
766 | * @freq: frequency to set (0 means to use the current frequency) | ||
767 | */ | ||
768 | static void set_freq(struct tuner *t, unsigned int freq) | ||
769 | { | ||
770 | struct i2c_client *client = v4l2_get_subdevdata(&t->sd); | ||
771 | |||
755 | if (t->mode == V4L2_TUNER_RADIO) { | 772 | if (t->mode == V4L2_TUNER_RADIO) { |
756 | if (freq) | 773 | if (!freq) |
757 | t->radio_freq = freq; | 774 | freq = t->radio_freq; |
758 | set_radio_freq(client, t->radio_freq); | 775 | set_radio_freq(client, freq); |
759 | } else { | 776 | } else { |
760 | if (freq) | 777 | if (!freq) |
761 | t->tv_freq = freq; | 778 | freq = t->tv_freq; |
762 | set_tv_freq(client, t->tv_freq); | 779 | set_tv_freq(client, freq); |
763 | } | 780 | } |
764 | |||
765 | return 0; | ||
766 | } | 781 | } |
767 | 782 | ||
768 | /* | 783 | /* |
@@ -817,7 +832,8 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
817 | /** | 832 | /** |
818 | * tuner_fixup_std - force a given video standard variant | 833 | * tuner_fixup_std - force a given video standard variant |
819 | * | 834 | * |
820 | * @t: tuner internal struct | 835 | * @t: tuner internal struct |
836 | * @std: TV standard | ||
821 | * | 837 | * |
822 | * A few devices or drivers have problem to detect some standard variations. | 838 | * A few devices or drivers have problem to detect some standard variations. |
823 | * On other operational systems, the drivers generally have a per-country | 839 | * On other operational systems, the drivers generally have a per-country |
@@ -827,57 +843,39 @@ static void set_tv_freq(struct i2c_client *c, unsigned int freq) | |||
827 | * to distinguish all video standard variations, a modprobe parameter can | 843 | * to distinguish all video standard variations, a modprobe parameter can |
828 | * be used to force a video standard match. | 844 | * be used to force a video standard match. |
829 | */ | 845 | */ |
830 | static int tuner_fixup_std(struct tuner *t) | 846 | static v4l2_std_id tuner_fixup_std(struct tuner *t, v4l2_std_id std) |
831 | { | 847 | { |
832 | if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) { | 848 | if (pal[0] != '-' && (std & V4L2_STD_PAL) == V4L2_STD_PAL) { |
833 | switch (pal[0]) { | 849 | switch (pal[0]) { |
834 | case '6': | 850 | case '6': |
835 | tuner_dbg("insmod fixup: PAL => PAL-60\n"); | 851 | return V4L2_STD_PAL_60; |
836 | t->std = V4L2_STD_PAL_60; | ||
837 | break; | ||
838 | case 'b': | 852 | case 'b': |
839 | case 'B': | 853 | case 'B': |
840 | case 'g': | 854 | case 'g': |
841 | case 'G': | 855 | case 'G': |
842 | tuner_dbg("insmod fixup: PAL => PAL-BG\n"); | 856 | return V4L2_STD_PAL_BG; |
843 | t->std = V4L2_STD_PAL_BG; | ||
844 | break; | ||
845 | case 'i': | 857 | case 'i': |
846 | case 'I': | 858 | case 'I': |
847 | tuner_dbg("insmod fixup: PAL => PAL-I\n"); | 859 | return V4L2_STD_PAL_I; |
848 | t->std = V4L2_STD_PAL_I; | ||
849 | break; | ||
850 | case 'd': | 860 | case 'd': |
851 | case 'D': | 861 | case 'D': |
852 | case 'k': | 862 | case 'k': |
853 | case 'K': | 863 | case 'K': |
854 | tuner_dbg("insmod fixup: PAL => PAL-DK\n"); | 864 | return V4L2_STD_PAL_DK; |
855 | t->std = V4L2_STD_PAL_DK; | ||
856 | break; | ||
857 | case 'M': | 865 | case 'M': |
858 | case 'm': | 866 | case 'm': |
859 | tuner_dbg("insmod fixup: PAL => PAL-M\n"); | 867 | return V4L2_STD_PAL_M; |
860 | t->std = V4L2_STD_PAL_M; | ||
861 | break; | ||
862 | case 'N': | 868 | case 'N': |
863 | case 'n': | 869 | case 'n': |
864 | if (pal[1] == 'c' || pal[1] == 'C') { | 870 | if (pal[1] == 'c' || pal[1] == 'C') |
865 | tuner_dbg("insmod fixup: PAL => PAL-Nc\n"); | 871 | return V4L2_STD_PAL_Nc; |
866 | t->std = V4L2_STD_PAL_Nc; | 872 | return V4L2_STD_PAL_N; |
867 | } else { | ||
868 | tuner_dbg("insmod fixup: PAL => PAL-N\n"); | ||
869 | t->std = V4L2_STD_PAL_N; | ||
870 | } | ||
871 | break; | ||
872 | case '-': | ||
873 | /* default parameter, do nothing */ | ||
874 | break; | ||
875 | default: | 873 | default: |
876 | tuner_warn("pal= argument not recognised\n"); | 874 | tuner_warn("pal= argument not recognised\n"); |
877 | break; | 875 | break; |
878 | } | 876 | } |
879 | } | 877 | } |
880 | if ((t->std & V4L2_STD_SECAM) == V4L2_STD_SECAM) { | 878 | if (secam[0] != '-' && (std & V4L2_STD_SECAM) == V4L2_STD_SECAM) { |
881 | switch (secam[0]) { | 879 | switch (secam[0]) { |
882 | case 'b': | 880 | case 'b': |
883 | case 'B': | 881 | case 'B': |
@@ -885,63 +883,42 @@ static int tuner_fixup_std(struct tuner *t) | |||
885 | case 'G': | 883 | case 'G': |
886 | case 'h': | 884 | case 'h': |
887 | case 'H': | 885 | case 'H': |
888 | tuner_dbg("insmod fixup: SECAM => SECAM-BGH\n"); | 886 | return V4L2_STD_SECAM_B | |
889 | t->std = V4L2_STD_SECAM_B | | 887 | V4L2_STD_SECAM_G | |
890 | V4L2_STD_SECAM_G | | 888 | V4L2_STD_SECAM_H; |
891 | V4L2_STD_SECAM_H; | ||
892 | break; | ||
893 | case 'd': | 889 | case 'd': |
894 | case 'D': | 890 | case 'D': |
895 | case 'k': | 891 | case 'k': |
896 | case 'K': | 892 | case 'K': |
897 | tuner_dbg("insmod fixup: SECAM => SECAM-DK\n"); | 893 | return V4L2_STD_SECAM_DK; |
898 | t->std = V4L2_STD_SECAM_DK; | ||
899 | break; | ||
900 | case 'l': | 894 | case 'l': |
901 | case 'L': | 895 | case 'L': |
902 | if ((secam[1] == 'C') || (secam[1] == 'c')) { | 896 | if ((secam[1] == 'C') || (secam[1] == 'c')) |
903 | tuner_dbg("insmod fixup: SECAM => SECAM-L'\n"); | 897 | return V4L2_STD_SECAM_LC; |
904 | t->std = V4L2_STD_SECAM_LC; | 898 | return V4L2_STD_SECAM_L; |
905 | } else { | ||
906 | tuner_dbg("insmod fixup: SECAM => SECAM-L\n"); | ||
907 | t->std = V4L2_STD_SECAM_L; | ||
908 | } | ||
909 | break; | ||
910 | case '-': | ||
911 | /* default parameter, do nothing */ | ||
912 | break; | ||
913 | default: | 899 | default: |
914 | tuner_warn("secam= argument not recognised\n"); | 900 | tuner_warn("secam= argument not recognised\n"); |
915 | break; | 901 | break; |
916 | } | 902 | } |
917 | } | 903 | } |
918 | 904 | ||
919 | if ((t->std & V4L2_STD_NTSC) == V4L2_STD_NTSC) { | 905 | if (ntsc[0] != '-' && (std & V4L2_STD_NTSC) == V4L2_STD_NTSC) { |
920 | switch (ntsc[0]) { | 906 | switch (ntsc[0]) { |
921 | case 'm': | 907 | case 'm': |
922 | case 'M': | 908 | case 'M': |
923 | tuner_dbg("insmod fixup: NTSC => NTSC-M\n"); | 909 | return V4L2_STD_NTSC_M; |
924 | t->std = V4L2_STD_NTSC_M; | ||
925 | break; | ||
926 | case 'j': | 910 | case 'j': |
927 | case 'J': | 911 | case 'J': |
928 | tuner_dbg("insmod fixup: NTSC => NTSC_M_JP\n"); | 912 | return V4L2_STD_NTSC_M_JP; |
929 | t->std = V4L2_STD_NTSC_M_JP; | ||
930 | break; | ||
931 | case 'k': | 913 | case 'k': |
932 | case 'K': | 914 | case 'K': |
933 | tuner_dbg("insmod fixup: NTSC => NTSC_M_KR\n"); | 915 | return V4L2_STD_NTSC_M_KR; |
934 | t->std = V4L2_STD_NTSC_M_KR; | ||
935 | break; | ||
936 | case '-': | ||
937 | /* default parameter, do nothing */ | ||
938 | break; | ||
939 | default: | 916 | default: |
940 | tuner_info("ntsc= argument not recognised\n"); | 917 | tuner_info("ntsc= argument not recognised\n"); |
941 | break; | 918 | break; |
942 | } | 919 | } |
943 | } | 920 | } |
944 | return 0; | 921 | return std; |
945 | } | 922 | } |
946 | 923 | ||
947 | /* | 924 | /* |
@@ -1016,7 +993,7 @@ static void tuner_status(struct dvb_frontend *fe) | |||
1016 | case V4L2_TUNER_RADIO: | 993 | case V4L2_TUNER_RADIO: |
1017 | p = "radio"; | 994 | p = "radio"; |
1018 | break; | 995 | break; |
1019 | case V4L2_TUNER_DIGITAL_TV: | 996 | case V4L2_TUNER_DIGITAL_TV: /* Used by mt20xx */ |
1020 | p = "digital TV"; | 997 | p = "digital TV"; |
1021 | break; | 998 | break; |
1022 | case V4L2_TUNER_ANALOG_TV: | 999 | case V4L2_TUNER_ANALOG_TV: |
@@ -1058,10 +1035,9 @@ static void tuner_status(struct dvb_frontend *fe) | |||
1058 | static int tuner_s_radio(struct v4l2_subdev *sd) | 1035 | static int tuner_s_radio(struct v4l2_subdev *sd) |
1059 | { | 1036 | { |
1060 | struct tuner *t = to_tuner(sd); | 1037 | struct tuner *t = to_tuner(sd); |
1061 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1062 | 1038 | ||
1063 | if (set_mode_freq(client, t, V4L2_TUNER_RADIO, 0) == -EINVAL) | 1039 | if (set_mode(t, V4L2_TUNER_RADIO) == 0) |
1064 | return 0; | 1040 | set_freq(t, 0); |
1065 | return 0; | 1041 | return 0; |
1066 | } | 1042 | } |
1067 | 1043 | ||
@@ -1072,16 +1048,20 @@ static int tuner_s_radio(struct v4l2_subdev *sd) | |||
1072 | /** | 1048 | /** |
1073 | * tuner_s_power - controls the power state of the tuner | 1049 | * tuner_s_power - controls the power state of the tuner |
1074 | * @sd: pointer to struct v4l2_subdev | 1050 | * @sd: pointer to struct v4l2_subdev |
1075 | * @on: a zero value puts the tuner to sleep | 1051 | * @on: a zero value puts the tuner to sleep, non-zero wakes it up |
1076 | */ | 1052 | */ |
1077 | static int tuner_s_power(struct v4l2_subdev *sd, int on) | 1053 | static int tuner_s_power(struct v4l2_subdev *sd, int on) |
1078 | { | 1054 | { |
1079 | struct tuner *t = to_tuner(sd); | 1055 | struct tuner *t = to_tuner(sd); |
1080 | struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; | 1056 | struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; |
1081 | 1057 | ||
1082 | /* FIXME: Why this function don't wake the tuner if on != 0 ? */ | 1058 | if (on) { |
1083 | if (on) | 1059 | if (t->standby && set_mode(t, t->mode) == 0) { |
1060 | tuner_dbg("Waking up tuner\n"); | ||
1061 | set_freq(t, 0); | ||
1062 | } | ||
1084 | return 0; | 1063 | return 0; |
1064 | } | ||
1085 | 1065 | ||
1086 | tuner_dbg("Putting tuner to sleep\n"); | 1066 | tuner_dbg("Putting tuner to sleep\n"); |
1087 | t->standby = true; | 1067 | t->standby = true; |
@@ -1093,28 +1073,36 @@ static int tuner_s_power(struct v4l2_subdev *sd, int on) | |||
1093 | static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std) | 1073 | static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std) |
1094 | { | 1074 | { |
1095 | struct tuner *t = to_tuner(sd); | 1075 | struct tuner *t = to_tuner(sd); |
1096 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1097 | 1076 | ||
1098 | if (set_mode_freq(client, t, V4L2_TUNER_ANALOG_TV, 0) == -EINVAL) | 1077 | if (set_mode(t, V4L2_TUNER_ANALOG_TV)) |
1099 | return 0; | 1078 | return 0; |
1100 | 1079 | ||
1101 | t->std = std; | 1080 | t->std = tuner_fixup_std(t, std); |
1102 | tuner_fixup_std(t); | 1081 | if (t->std != std) |
1103 | 1082 | tuner_dbg("Fixup standard %llx to %llx\n", std, t->std); | |
1083 | set_freq(t, 0); | ||
1104 | return 0; | 1084 | return 0; |
1105 | } | 1085 | } |
1106 | 1086 | ||
1107 | static int tuner_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) | 1087 | static int tuner_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) |
1108 | { | 1088 | { |
1109 | struct tuner *t = to_tuner(sd); | 1089 | struct tuner *t = to_tuner(sd); |
1110 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1111 | |||
1112 | if (set_mode_freq(client, t, f->type, f->frequency) == -EINVAL) | ||
1113 | return 0; | ||
1114 | 1090 | ||
1091 | if (set_mode(t, f->type) == 0) | ||
1092 | set_freq(t, f->frequency); | ||
1115 | return 0; | 1093 | return 0; |
1116 | } | 1094 | } |
1117 | 1095 | ||
1096 | /** | ||
1097 | * tuner_g_frequency - Get the tuned frequency for the tuner | ||
1098 | * @sd: pointer to struct v4l2_subdev | ||
1099 | * @f: pointer to struct v4l2_frequency | ||
1100 | * | ||
1101 | * At return, the structure f will be filled with tuner frequency | ||
1102 | * if the tuner matches the f->type. | ||
1103 | * Note: f->type should be initialized before calling it. | ||
1104 | * This is done by either video_ioctl2 or by the bridge driver. | ||
1105 | */ | ||
1118 | static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) | 1106 | static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) |
1119 | { | 1107 | { |
1120 | struct tuner *t = to_tuner(sd); | 1108 | struct tuner *t = to_tuner(sd); |
@@ -1122,8 +1110,7 @@ static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) | |||
1122 | 1110 | ||
1123 | if (check_mode(t, f->type) == -EINVAL) | 1111 | if (check_mode(t, f->type) == -EINVAL) |
1124 | return 0; | 1112 | return 0; |
1125 | f->type = t->mode; | 1113 | if (f->type == t->mode && fe_tuner_ops->get_frequency && !t->standby) { |
1126 | if (fe_tuner_ops->get_frequency && !t->standby) { | ||
1127 | u32 abs_freq; | 1114 | u32 abs_freq; |
1128 | 1115 | ||
1129 | fe_tuner_ops->get_frequency(&t->fe, &abs_freq); | 1116 | fe_tuner_ops->get_frequency(&t->fe, &abs_freq); |
@@ -1131,12 +1118,22 @@ static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f) | |||
1131 | DIV_ROUND_CLOSEST(abs_freq * 2, 125) : | 1118 | DIV_ROUND_CLOSEST(abs_freq * 2, 125) : |
1132 | DIV_ROUND_CLOSEST(abs_freq, 62500); | 1119 | DIV_ROUND_CLOSEST(abs_freq, 62500); |
1133 | } else { | 1120 | } else { |
1134 | f->frequency = (V4L2_TUNER_RADIO == t->mode) ? | 1121 | f->frequency = (V4L2_TUNER_RADIO == f->type) ? |
1135 | t->radio_freq : t->tv_freq; | 1122 | t->radio_freq : t->tv_freq; |
1136 | } | 1123 | } |
1137 | return 0; | 1124 | return 0; |
1138 | } | 1125 | } |
1139 | 1126 | ||
1127 | /** | ||
1128 | * tuner_g_tuner - Fill in tuner information | ||
1129 | * @sd: pointer to struct v4l2_subdev | ||
1130 | * @vt: pointer to struct v4l2_tuner | ||
1131 | * | ||
1132 | * At return, the structure vt will be filled with tuner information | ||
1133 | * if the tuner matches vt->type. | ||
1134 | * Note: vt->type should be initialized before calling it. | ||
1135 | * This is done by either video_ioctl2 or by the bridge driver. | ||
1136 | */ | ||
1140 | static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) | 1137 | static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) |
1141 | { | 1138 | { |
1142 | struct tuner *t = to_tuner(sd); | 1139 | struct tuner *t = to_tuner(sd); |
@@ -1145,48 +1142,57 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) | |||
1145 | 1142 | ||
1146 | if (check_mode(t, vt->type) == -EINVAL) | 1143 | if (check_mode(t, vt->type) == -EINVAL) |
1147 | return 0; | 1144 | return 0; |
1148 | vt->type = t->mode; | 1145 | if (vt->type == t->mode && analog_ops->get_afc) |
1149 | if (analog_ops->get_afc) | ||
1150 | vt->afc = analog_ops->get_afc(&t->fe); | 1146 | vt->afc = analog_ops->get_afc(&t->fe); |
1151 | if (t->mode == V4L2_TUNER_ANALOG_TV) | ||
1152 | vt->capability |= V4L2_TUNER_CAP_NORM; | ||
1153 | if (t->mode != V4L2_TUNER_RADIO) { | 1147 | if (t->mode != V4L2_TUNER_RADIO) { |
1148 | vt->capability |= V4L2_TUNER_CAP_NORM; | ||
1154 | vt->rangelow = tv_range[0] * 16; | 1149 | vt->rangelow = tv_range[0] * 16; |
1155 | vt->rangehigh = tv_range[1] * 16; | 1150 | vt->rangehigh = tv_range[1] * 16; |
1156 | return 0; | 1151 | return 0; |
1157 | } | 1152 | } |
1158 | 1153 | ||
1159 | /* radio mode */ | 1154 | /* radio mode */ |
1160 | vt->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; | 1155 | if (vt->type == t->mode) { |
1161 | if (fe_tuner_ops->get_status) { | 1156 | vt->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; |
1162 | u32 tuner_status; | 1157 | if (fe_tuner_ops->get_status) { |
1163 | 1158 | u32 tuner_status; | |
1164 | fe_tuner_ops->get_status(&t->fe, &tuner_status); | 1159 | |
1165 | vt->rxsubchans = | 1160 | fe_tuner_ops->get_status(&t->fe, &tuner_status); |
1166 | (tuner_status & TUNER_STATUS_STEREO) ? | 1161 | vt->rxsubchans = |
1167 | V4L2_TUNER_SUB_STEREO : | 1162 | (tuner_status & TUNER_STATUS_STEREO) ? |
1168 | V4L2_TUNER_SUB_MONO; | 1163 | V4L2_TUNER_SUB_STEREO : |
1164 | V4L2_TUNER_SUB_MONO; | ||
1165 | } | ||
1166 | if (analog_ops->has_signal) | ||
1167 | vt->signal = analog_ops->has_signal(&t->fe); | ||
1168 | vt->audmode = t->audmode; | ||
1169 | } | 1169 | } |
1170 | if (analog_ops->has_signal) | ||
1171 | vt->signal = analog_ops->has_signal(&t->fe); | ||
1172 | vt->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; | 1170 | vt->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; |
1173 | vt->audmode = t->audmode; | ||
1174 | vt->rangelow = radio_range[0] * 16000; | 1171 | vt->rangelow = radio_range[0] * 16000; |
1175 | vt->rangehigh = radio_range[1] * 16000; | 1172 | vt->rangehigh = radio_range[1] * 16000; |
1176 | 1173 | ||
1177 | return 0; | 1174 | return 0; |
1178 | } | 1175 | } |
1179 | 1176 | ||
1177 | /** | ||
1178 | * tuner_s_tuner - Set the tuner's audio mode | ||
1179 | * @sd: pointer to struct v4l2_subdev | ||
1180 | * @vt: pointer to struct v4l2_tuner | ||
1181 | * | ||
1182 | * Sets the audio mode if the tuner matches vt->type. | ||
1183 | * Note: vt->type should be initialized before calling it. | ||
1184 | * This is done by either video_ioctl2 or by the bridge driver. | ||
1185 | */ | ||
1180 | static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) | 1186 | static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt) |
1181 | { | 1187 | { |
1182 | struct tuner *t = to_tuner(sd); | 1188 | struct tuner *t = to_tuner(sd); |
1183 | struct i2c_client *client = v4l2_get_subdevdata(sd); | ||
1184 | 1189 | ||
1185 | if (set_mode_freq(client, t, vt->type, 0) == -EINVAL) | 1190 | if (set_mode(t, vt->type)) |
1186 | return 0; | 1191 | return 0; |
1187 | 1192 | ||
1188 | if (t->mode == V4L2_TUNER_RADIO) | 1193 | if (t->mode == V4L2_TUNER_RADIO) |
1189 | t->audmode = vt->audmode; | 1194 | t->audmode = vt->audmode; |
1195 | set_freq(t, 0); | ||
1190 | 1196 | ||
1191 | return 0; | 1197 | return 0; |
1192 | } | 1198 | } |
@@ -1221,7 +1227,8 @@ static int tuner_resume(struct i2c_client *c) | |||
1221 | tuner_dbg("resume\n"); | 1227 | tuner_dbg("resume\n"); |
1222 | 1228 | ||
1223 | if (!t->standby) | 1229 | if (!t->standby) |
1224 | set_mode_freq(c, t, t->type, 0); | 1230 | if (set_mode(t, t->mode) == 0) |
1231 | set_freq(t, 0); | ||
1225 | 1232 | ||
1226 | return 0; | 1233 | return 0; |
1227 | } | 1234 | } |
diff --git a/drivers/media/video/uvc/uvc_entity.c b/drivers/media/video/uvc/uvc_entity.c index c3ab0c813be2..48fea373c25a 100644 --- a/drivers/media/video/uvc/uvc_entity.c +++ b/drivers/media/video/uvc/uvc_entity.c | |||
@@ -27,14 +27,20 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain, | |||
27 | struct uvc_entity *entity) | 27 | struct uvc_entity *entity) |
28 | { | 28 | { |
29 | const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE; | 29 | const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE; |
30 | struct uvc_entity *remote; | 30 | struct media_entity *sink; |
31 | unsigned int i; | 31 | unsigned int i; |
32 | u8 remote_pad; | 32 | int ret; |
33 | int ret = 0; | 33 | |
34 | sink = (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING) | ||
35 | ? (entity->vdev ? &entity->vdev->entity : NULL) | ||
36 | : &entity->subdev.entity; | ||
37 | if (sink == NULL) | ||
38 | return 0; | ||
34 | 39 | ||
35 | for (i = 0; i < entity->num_pads; ++i) { | 40 | for (i = 0; i < entity->num_pads; ++i) { |
36 | struct media_entity *source; | 41 | struct media_entity *source; |
37 | struct media_entity *sink; | 42 | struct uvc_entity *remote; |
43 | u8 remote_pad; | ||
38 | 44 | ||
39 | if (!(entity->pads[i].flags & MEDIA_PAD_FL_SINK)) | 45 | if (!(entity->pads[i].flags & MEDIA_PAD_FL_SINK)) |
40 | continue; | 46 | continue; |
@@ -43,10 +49,11 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain, | |||
43 | if (remote == NULL) | 49 | if (remote == NULL) |
44 | return -EINVAL; | 50 | return -EINVAL; |
45 | 51 | ||
46 | source = (UVC_ENTITY_TYPE(remote) == UVC_TT_STREAMING) | 52 | source = (UVC_ENTITY_TYPE(remote) != UVC_TT_STREAMING) |
47 | ? &remote->vdev->entity : &remote->subdev.entity; | 53 | ? (remote->vdev ? &remote->vdev->entity : NULL) |
48 | sink = (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING) | 54 | : &remote->subdev.entity; |
49 | ? &entity->vdev->entity : &entity->subdev.entity; | 55 | if (source == NULL) |
56 | continue; | ||
50 | 57 | ||
51 | remote_pad = remote->num_pads - 1; | 58 | remote_pad = remote->num_pads - 1; |
52 | ret = media_entity_create_link(source, remote_pad, | 59 | ret = media_entity_create_link(source, remote_pad, |
@@ -55,11 +62,10 @@ static int uvc_mc_register_entity(struct uvc_video_chain *chain, | |||
55 | return ret; | 62 | return ret; |
56 | } | 63 | } |
57 | 64 | ||
58 | if (UVC_ENTITY_TYPE(entity) != UVC_TT_STREAMING) | 65 | if (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING) |
59 | ret = v4l2_device_register_subdev(&chain->dev->vdev, | 66 | return 0; |
60 | &entity->subdev); | ||
61 | 67 | ||
62 | return ret; | 68 | return v4l2_device_register_subdev(&chain->dev->vdev, &entity->subdev); |
63 | } | 69 | } |
64 | 70 | ||
65 | static struct v4l2_subdev_ops uvc_subdev_ops = { | 71 | static struct v4l2_subdev_ops uvc_subdev_ops = { |
@@ -84,9 +90,11 @@ static int uvc_mc_init_entity(struct uvc_entity *entity) | |||
84 | 90 | ||
85 | ret = media_entity_init(&entity->subdev.entity, | 91 | ret = media_entity_init(&entity->subdev.entity, |
86 | entity->num_pads, entity->pads, 0); | 92 | entity->num_pads, entity->pads, 0); |
87 | } else | 93 | } else if (entity->vdev != NULL) { |
88 | ret = media_entity_init(&entity->vdev->entity, | 94 | ret = media_entity_init(&entity->vdev->entity, |
89 | entity->num_pads, entity->pads, 0); | 95 | entity->num_pads, entity->pads, 0); |
96 | } else | ||
97 | ret = 0; | ||
90 | 98 | ||
91 | return ret; | 99 | return ret; |
92 | } | 100 | } |
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index 109a06384a8f..f90ce9fce539 100644 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/uvc/uvc_queue.c | |||
@@ -104,6 +104,8 @@ static int __uvc_free_buffers(struct uvc_video_queue *queue) | |||
104 | } | 104 | } |
105 | 105 | ||
106 | if (queue->count) { | 106 | if (queue->count) { |
107 | uvc_queue_cancel(queue, 0); | ||
108 | INIT_LIST_HEAD(&queue->mainqueue); | ||
107 | vfree(queue->mem); | 109 | vfree(queue->mem); |
108 | queue->count = 0; | 110 | queue->count = 0; |
109 | } | 111 | } |
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c index fc766b9f24c5..49994793cc77 100644 --- a/drivers/media/video/uvc/uvc_video.c +++ b/drivers/media/video/uvc/uvc_video.c | |||
@@ -1255,8 +1255,10 @@ int uvc_video_enable(struct uvc_streaming *stream, int enable) | |||
1255 | 1255 | ||
1256 | /* Commit the streaming parameters. */ | 1256 | /* Commit the streaming parameters. */ |
1257 | ret = uvc_commit_video(stream, &stream->ctrl); | 1257 | ret = uvc_commit_video(stream, &stream->ctrl); |
1258 | if (ret < 0) | 1258 | if (ret < 0) { |
1259 | uvc_queue_enable(&stream->queue, 0); | ||
1259 | return ret; | 1260 | return ret; |
1261 | } | ||
1260 | 1262 | ||
1261 | return uvc_init_video(stream, GFP_KERNEL); | 1263 | return uvc_init_video(stream, GFP_KERNEL); |
1262 | } | 1264 | } |
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 19d5ae293780..06f14008b346 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c | |||
@@ -167,6 +167,12 @@ static void v4l2_device_release(struct device *cd) | |||
167 | 167 | ||
168 | mutex_unlock(&videodev_lock); | 168 | mutex_unlock(&videodev_lock); |
169 | 169 | ||
170 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
171 | if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && | ||
172 | vdev->vfl_type != VFL_TYPE_SUBDEV) | ||
173 | media_device_unregister_entity(&vdev->entity); | ||
174 | #endif | ||
175 | |||
170 | /* Release video_device and perform other | 176 | /* Release video_device and perform other |
171 | cleanups as needed. */ | 177 | cleanups as needed. */ |
172 | vdev->release(vdev); | 178 | vdev->release(vdev); |
@@ -389,9 +395,6 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm) | |||
389 | static int v4l2_open(struct inode *inode, struct file *filp) | 395 | static int v4l2_open(struct inode *inode, struct file *filp) |
390 | { | 396 | { |
391 | struct video_device *vdev; | 397 | struct video_device *vdev; |
392 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
393 | struct media_entity *entity = NULL; | ||
394 | #endif | ||
395 | int ret = 0; | 398 | int ret = 0; |
396 | 399 | ||
397 | /* Check if the video device is available */ | 400 | /* Check if the video device is available */ |
@@ -405,17 +408,6 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
405 | /* and increase the device refcount */ | 408 | /* and increase the device refcount */ |
406 | video_get(vdev); | 409 | video_get(vdev); |
407 | mutex_unlock(&videodev_lock); | 410 | mutex_unlock(&videodev_lock); |
408 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
409 | if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && | ||
410 | vdev->vfl_type != VFL_TYPE_SUBDEV) { | ||
411 | entity = media_entity_get(&vdev->entity); | ||
412 | if (!entity) { | ||
413 | ret = -EBUSY; | ||
414 | video_put(vdev); | ||
415 | return ret; | ||
416 | } | ||
417 | } | ||
418 | #endif | ||
419 | if (vdev->fops->open) { | 411 | if (vdev->fops->open) { |
420 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) { | 412 | if (vdev->lock && mutex_lock_interruptible(vdev->lock)) { |
421 | ret = -ERESTARTSYS; | 413 | ret = -ERESTARTSYS; |
@@ -431,14 +423,8 @@ static int v4l2_open(struct inode *inode, struct file *filp) | |||
431 | 423 | ||
432 | err: | 424 | err: |
433 | /* decrease the refcount in case of an error */ | 425 | /* decrease the refcount in case of an error */ |
434 | if (ret) { | 426 | if (ret) |
435 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
436 | if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && | ||
437 | vdev->vfl_type != VFL_TYPE_SUBDEV) | ||
438 | media_entity_put(entity); | ||
439 | #endif | ||
440 | video_put(vdev); | 427 | video_put(vdev); |
441 | } | ||
442 | return ret; | 428 | return ret; |
443 | } | 429 | } |
444 | 430 | ||
@@ -455,11 +441,6 @@ static int v4l2_release(struct inode *inode, struct file *filp) | |||
455 | if (vdev->lock) | 441 | if (vdev->lock) |
456 | mutex_unlock(vdev->lock); | 442 | mutex_unlock(vdev->lock); |
457 | } | 443 | } |
458 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
459 | if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && | ||
460 | vdev->vfl_type != VFL_TYPE_SUBDEV) | ||
461 | media_entity_put(&vdev->entity); | ||
462 | #endif | ||
463 | /* decrease the refcount unconditionally since the release() | 444 | /* decrease the refcount unconditionally since the release() |
464 | return value is ignored. */ | 445 | return value is ignored. */ |
465 | video_put(vdev); | 446 | video_put(vdev); |
@@ -754,12 +735,6 @@ void video_unregister_device(struct video_device *vdev) | |||
754 | if (!vdev || !video_is_registered(vdev)) | 735 | if (!vdev || !video_is_registered(vdev)) |
755 | return; | 736 | return; |
756 | 737 | ||
757 | #if defined(CONFIG_MEDIA_CONTROLLER) | ||
758 | if (vdev->v4l2_dev && vdev->v4l2_dev->mdev && | ||
759 | vdev->vfl_type != VFL_TYPE_SUBDEV) | ||
760 | media_device_unregister_entity(&vdev->entity); | ||
761 | #endif | ||
762 | |||
763 | mutex_lock(&videodev_lock); | 738 | mutex_lock(&videodev_lock); |
764 | /* This must be in a critical section to prevent a race with v4l2_open. | 739 | /* This must be in a critical section to prevent a race with v4l2_open. |
765 | * Once this bit has been cleared video_get may never be called again. | 740 | * Once this bit has been cleared video_get may never be called again. |
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index 506edcc2ddeb..69e8c6ffcc49 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c | |||
@@ -1822,6 +1822,8 @@ static long __video_do_ioctl(struct file *file, | |||
1822 | if (!ops->vidioc_g_tuner) | 1822 | if (!ops->vidioc_g_tuner) |
1823 | break; | 1823 | break; |
1824 | 1824 | ||
1825 | p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? | ||
1826 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
1825 | ret = ops->vidioc_g_tuner(file, fh, p); | 1827 | ret = ops->vidioc_g_tuner(file, fh, p); |
1826 | if (!ret) | 1828 | if (!ret) |
1827 | dbgarg(cmd, "index=%d, name=%s, type=%d, " | 1829 | dbgarg(cmd, "index=%d, name=%s, type=%d, " |
@@ -1840,6 +1842,8 @@ static long __video_do_ioctl(struct file *file, | |||
1840 | 1842 | ||
1841 | if (!ops->vidioc_s_tuner) | 1843 | if (!ops->vidioc_s_tuner) |
1842 | break; | 1844 | break; |
1845 | p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? | ||
1846 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
1843 | dbgarg(cmd, "index=%d, name=%s, type=%d, " | 1847 | dbgarg(cmd, "index=%d, name=%s, type=%d, " |
1844 | "capability=0x%x, rangelow=%d, " | 1848 | "capability=0x%x, rangelow=%d, " |
1845 | "rangehigh=%d, signal=%d, afc=%d, " | 1849 | "rangehigh=%d, signal=%d, afc=%d, " |
@@ -1858,6 +1862,8 @@ static long __video_do_ioctl(struct file *file, | |||
1858 | if (!ops->vidioc_g_frequency) | 1862 | if (!ops->vidioc_g_frequency) |
1859 | break; | 1863 | break; |
1860 | 1864 | ||
1865 | p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ? | ||
1866 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
1861 | ret = ops->vidioc_g_frequency(file, fh, p); | 1867 | ret = ops->vidioc_g_frequency(file, fh, p); |
1862 | if (!ret) | 1868 | if (!ret) |
1863 | dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", | 1869 | dbgarg(cmd, "tuner=%d, type=%d, frequency=%d\n", |
@@ -1940,13 +1946,19 @@ static long __video_do_ioctl(struct file *file, | |||
1940 | case VIDIOC_S_HW_FREQ_SEEK: | 1946 | case VIDIOC_S_HW_FREQ_SEEK: |
1941 | { | 1947 | { |
1942 | struct v4l2_hw_freq_seek *p = arg; | 1948 | struct v4l2_hw_freq_seek *p = arg; |
1949 | enum v4l2_tuner_type type; | ||
1943 | 1950 | ||
1944 | if (!ops->vidioc_s_hw_freq_seek) | 1951 | if (!ops->vidioc_s_hw_freq_seek) |
1945 | break; | 1952 | break; |
1953 | type = (vfd->vfl_type == VFL_TYPE_RADIO) ? | ||
1954 | V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV; | ||
1946 | dbgarg(cmd, | 1955 | dbgarg(cmd, |
1947 | "tuner=%d, type=%d, seek_upward=%d, wrap_around=%d\n", | 1956 | "tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u\n", |
1948 | p->tuner, p->type, p->seek_upward, p->wrap_around); | 1957 | p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing); |
1949 | ret = ops->vidioc_s_hw_freq_seek(file, fh, p); | 1958 | if (p->type != type) |
1959 | ret = -EINVAL; | ||
1960 | else | ||
1961 | ret = ops->vidioc_s_hw_freq_seek(file, fh, p); | ||
1950 | break; | 1962 | break; |
1951 | } | 1963 | } |
1952 | case VIDIOC_ENUM_FRAMESIZES: | 1964 | case VIDIOC_ENUM_FRAMESIZES: |
diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c index 6ba1461d51ef..3015e6000946 100644 --- a/drivers/media/video/videobuf2-core.c +++ b/drivers/media/video/videobuf2-core.c | |||
@@ -492,13 +492,6 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) | |||
492 | return -EINVAL; | 492 | return -EINVAL; |
493 | } | 493 | } |
494 | 494 | ||
495 | /* | ||
496 | * If the same number of buffers and memory access method is requested | ||
497 | * then return immediately. | ||
498 | */ | ||
499 | if (q->memory == req->memory && req->count == q->num_buffers) | ||
500 | return 0; | ||
501 | |||
502 | if (req->count == 0 || q->num_buffers != 0 || q->memory != req->memory) { | 495 | if (req->count == 0 || q->num_buffers != 0 || q->memory != req->memory) { |
503 | /* | 496 | /* |
504 | * We already have buffers allocated, so first check if they | 497 | * We already have buffers allocated, so first check if they |
@@ -539,9 +532,9 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) | |||
539 | /* Finally, allocate buffers and video memory */ | 532 | /* Finally, allocate buffers and video memory */ |
540 | ret = __vb2_queue_alloc(q, req->memory, num_buffers, num_planes, | 533 | ret = __vb2_queue_alloc(q, req->memory, num_buffers, num_planes, |
541 | plane_sizes); | 534 | plane_sizes); |
542 | if (ret < 0) { | 535 | if (ret == 0) { |
543 | dprintk(1, "Memory allocation failed with error: %d\n", ret); | 536 | dprintk(1, "Memory allocation failed\n"); |
544 | return ret; | 537 | return -ENOMEM; |
545 | } | 538 | } |
546 | 539 | ||
547 | /* | 540 | /* |
@@ -1196,6 +1189,7 @@ static void __vb2_queue_cancel(struct vb2_queue *q) | |||
1196 | * has not already dequeued before initiating cancel. | 1189 | * has not already dequeued before initiating cancel. |
1197 | */ | 1190 | */ |
1198 | INIT_LIST_HEAD(&q->done_list); | 1191 | INIT_LIST_HEAD(&q->done_list); |
1192 | atomic_set(&q->queued_count, 0); | ||
1199 | wake_up_all(&q->done_wq); | 1193 | wake_up_all(&q->done_wq); |
1200 | 1194 | ||
1201 | /* | 1195 | /* |
diff --git a/drivers/media/video/videobuf2-dma-sg.c b/drivers/media/video/videobuf2-dma-sg.c index b2d9485aac75..10a20d9509d9 100644 --- a/drivers/media/video/videobuf2-dma-sg.c +++ b/drivers/media/video/videobuf2-dma-sg.c | |||
@@ -62,7 +62,7 @@ static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size) | |||
62 | goto fail_pages_array_alloc; | 62 | goto fail_pages_array_alloc; |
63 | 63 | ||
64 | for (i = 0; i < buf->sg_desc.num_pages; ++i) { | 64 | for (i = 0; i < buf->sg_desc.num_pages; ++i) { |
65 | buf->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO); | 65 | buf->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO | __GFP_NOWARN); |
66 | if (NULL == buf->pages[i]) | 66 | if (NULL == buf->pages[i]) |
67 | goto fail_pages_alloc; | 67 | goto fail_pages_alloc; |
68 | sg_set_page(&buf->sg_desc.sglist[i], | 68 | sg_set_page(&buf->sg_desc.sglist[i], |
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 0f09c057e796..6ca938a6bf94 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -728,6 +728,9 @@ config MFD_TPS65910 | |||
728 | if you say yes here you get support for the TPS65910 series of | 728 | if you say yes here you get support for the TPS65910 series of |
729 | Power Management chips. | 729 | Power Management chips. |
730 | 730 | ||
731 | config TPS65911_COMPARATOR | ||
732 | tristate | ||
733 | |||
731 | endif # MFD_SUPPORT | 734 | endif # MFD_SUPPORT |
732 | 735 | ||
733 | menu "Multimedia Capabilities Port drivers" | 736 | menu "Multimedia Capabilities Port drivers" |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index efe3cc33ed92..d7d47d2a4c76 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
@@ -94,3 +94,4 @@ obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o | |||
94 | obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o | 94 | obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o |
95 | obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o | 95 | obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o |
96 | obj-$(CONFIG_MFD_TPS65910) += tps65910.o tps65910-irq.o | 96 | obj-$(CONFIG_MFD_TPS65910) += tps65910.o tps65910-irq.o |
97 | obj-$(CONFIG_TPS65911_COMPARATOR) += tps65911-comparator.o | ||
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index c27fd1fc3b86..c71ae09430c5 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c | |||
@@ -619,6 +619,7 @@ static void asic3_clk_disable(struct asic3 *asic, struct asic3_clk *clk) | |||
619 | /* MFD cells (SPI, PWM, LED, DS1WM, MMC) */ | 619 | /* MFD cells (SPI, PWM, LED, DS1WM, MMC) */ |
620 | static struct ds1wm_driver_data ds1wm_pdata = { | 620 | static struct ds1wm_driver_data ds1wm_pdata = { |
621 | .active_high = 1, | 621 | .active_high = 1, |
622 | .reset_recover_delay = 1, | ||
622 | }; | 623 | }; |
623 | 624 | ||
624 | static struct resource ds1wm_resources[] = { | 625 | static struct resource ds1wm_resources[] = { |
diff --git a/drivers/mfd/htc-pasic3.c b/drivers/mfd/htc-pasic3.c index 2808bd125d13..04c7093d6499 100644 --- a/drivers/mfd/htc-pasic3.c +++ b/drivers/mfd/htc-pasic3.c | |||
@@ -99,6 +99,7 @@ static int ds1wm_disable(struct platform_device *pdev) | |||
99 | 99 | ||
100 | static struct ds1wm_driver_data ds1wm_pdata = { | 100 | static struct ds1wm_driver_data ds1wm_pdata = { |
101 | .active_high = 0, | 101 | .active_high = 0, |
102 | .reset_recover_delay = 1, | ||
102 | }; | 103 | }; |
103 | 104 | ||
104 | static struct resource ds1wm_resources[] __initdata = { | 105 | static struct resource ds1wm_resources[] __initdata = { |
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c index 855219526ccb..1717144fe7f4 100644 --- a/drivers/mfd/omap-usb-host.c +++ b/drivers/mfd/omap-usb-host.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/spinlock.h> | 26 | #include <linux/spinlock.h> |
27 | #include <linux/gpio.h> | 27 | #include <linux/gpio.h> |
28 | #include <plat/usb.h> | 28 | #include <plat/usb.h> |
29 | #include <linux/pm_runtime.h> | ||
30 | 29 | ||
31 | #define USBHS_DRIVER_NAME "usbhs-omap" | 30 | #define USBHS_DRIVER_NAME "usbhs-omap" |
32 | #define OMAP_EHCI_DEVICE "ehci-omap" | 31 | #define OMAP_EHCI_DEVICE "ehci-omap" |
@@ -147,6 +146,9 @@ | |||
147 | 146 | ||
148 | 147 | ||
149 | struct usbhs_hcd_omap { | 148 | struct usbhs_hcd_omap { |
149 | struct clk *usbhost_ick; | ||
150 | struct clk *usbhost_hs_fck; | ||
151 | struct clk *usbhost_fs_fck; | ||
150 | struct clk *xclk60mhsp1_ck; | 152 | struct clk *xclk60mhsp1_ck; |
151 | struct clk *xclk60mhsp2_ck; | 153 | struct clk *xclk60mhsp2_ck; |
152 | struct clk *utmi_p1_fck; | 154 | struct clk *utmi_p1_fck; |
@@ -156,6 +158,8 @@ struct usbhs_hcd_omap { | |||
156 | struct clk *usbhost_p2_fck; | 158 | struct clk *usbhost_p2_fck; |
157 | struct clk *usbtll_p2_fck; | 159 | struct clk *usbtll_p2_fck; |
158 | struct clk *init_60m_fclk; | 160 | struct clk *init_60m_fclk; |
161 | struct clk *usbtll_fck; | ||
162 | struct clk *usbtll_ick; | ||
159 | 163 | ||
160 | void __iomem *uhh_base; | 164 | void __iomem *uhh_base; |
161 | void __iomem *tll_base; | 165 | void __iomem *tll_base; |
@@ -349,13 +353,46 @@ static int __devinit usbhs_omap_probe(struct platform_device *pdev) | |||
349 | omap->platdata.ehci_data = pdata->ehci_data; | 353 | omap->platdata.ehci_data = pdata->ehci_data; |
350 | omap->platdata.ohci_data = pdata->ohci_data; | 354 | omap->platdata.ohci_data = pdata->ohci_data; |
351 | 355 | ||
352 | pm_runtime_enable(&pdev->dev); | 356 | omap->usbhost_ick = clk_get(dev, "usbhost_ick"); |
357 | if (IS_ERR(omap->usbhost_ick)) { | ||
358 | ret = PTR_ERR(omap->usbhost_ick); | ||
359 | dev_err(dev, "usbhost_ick failed error:%d\n", ret); | ||
360 | goto err_end; | ||
361 | } | ||
362 | |||
363 | omap->usbhost_hs_fck = clk_get(dev, "hs_fck"); | ||
364 | if (IS_ERR(omap->usbhost_hs_fck)) { | ||
365 | ret = PTR_ERR(omap->usbhost_hs_fck); | ||
366 | dev_err(dev, "usbhost_hs_fck failed error:%d\n", ret); | ||
367 | goto err_usbhost_ick; | ||
368 | } | ||
369 | |||
370 | omap->usbhost_fs_fck = clk_get(dev, "fs_fck"); | ||
371 | if (IS_ERR(omap->usbhost_fs_fck)) { | ||
372 | ret = PTR_ERR(omap->usbhost_fs_fck); | ||
373 | dev_err(dev, "usbhost_fs_fck failed error:%d\n", ret); | ||
374 | goto err_usbhost_hs_fck; | ||
375 | } | ||
376 | |||
377 | omap->usbtll_fck = clk_get(dev, "usbtll_fck"); | ||
378 | if (IS_ERR(omap->usbtll_fck)) { | ||
379 | ret = PTR_ERR(omap->usbtll_fck); | ||
380 | dev_err(dev, "usbtll_fck failed error:%d\n", ret); | ||
381 | goto err_usbhost_fs_fck; | ||
382 | } | ||
383 | |||
384 | omap->usbtll_ick = clk_get(dev, "usbtll_ick"); | ||
385 | if (IS_ERR(omap->usbtll_ick)) { | ||
386 | ret = PTR_ERR(omap->usbtll_ick); | ||
387 | dev_err(dev, "usbtll_ick failed error:%d\n", ret); | ||
388 | goto err_usbtll_fck; | ||
389 | } | ||
353 | 390 | ||
354 | omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk"); | 391 | omap->utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk"); |
355 | if (IS_ERR(omap->utmi_p1_fck)) { | 392 | if (IS_ERR(omap->utmi_p1_fck)) { |
356 | ret = PTR_ERR(omap->utmi_p1_fck); | 393 | ret = PTR_ERR(omap->utmi_p1_fck); |
357 | dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); | 394 | dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); |
358 | goto err_end; | 395 | goto err_usbtll_ick; |
359 | } | 396 | } |
360 | 397 | ||
361 | omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck"); | 398 | omap->xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck"); |
@@ -485,8 +522,22 @@ err_xclk60mhsp1_ck: | |||
485 | err_utmi_p1_fck: | 522 | err_utmi_p1_fck: |
486 | clk_put(omap->utmi_p1_fck); | 523 | clk_put(omap->utmi_p1_fck); |
487 | 524 | ||
525 | err_usbtll_ick: | ||
526 | clk_put(omap->usbtll_ick); | ||
527 | |||
528 | err_usbtll_fck: | ||
529 | clk_put(omap->usbtll_fck); | ||
530 | |||
531 | err_usbhost_fs_fck: | ||
532 | clk_put(omap->usbhost_fs_fck); | ||
533 | |||
534 | err_usbhost_hs_fck: | ||
535 | clk_put(omap->usbhost_hs_fck); | ||
536 | |||
537 | err_usbhost_ick: | ||
538 | clk_put(omap->usbhost_ick); | ||
539 | |||
488 | err_end: | 540 | err_end: |
489 | pm_runtime_disable(&pdev->dev); | ||
490 | kfree(omap); | 541 | kfree(omap); |
491 | 542 | ||
492 | end_probe: | 543 | end_probe: |
@@ -520,7 +571,11 @@ static int __devexit usbhs_omap_remove(struct platform_device *pdev) | |||
520 | clk_put(omap->utmi_p2_fck); | 571 | clk_put(omap->utmi_p2_fck); |
521 | clk_put(omap->xclk60mhsp1_ck); | 572 | clk_put(omap->xclk60mhsp1_ck); |
522 | clk_put(omap->utmi_p1_fck); | 573 | clk_put(omap->utmi_p1_fck); |
523 | pm_runtime_disable(&pdev->dev); | 574 | clk_put(omap->usbtll_ick); |
575 | clk_put(omap->usbtll_fck); | ||
576 | clk_put(omap->usbhost_fs_fck); | ||
577 | clk_put(omap->usbhost_hs_fck); | ||
578 | clk_put(omap->usbhost_ick); | ||
524 | kfree(omap); | 579 | kfree(omap); |
525 | 580 | ||
526 | return 0; | 581 | return 0; |
@@ -640,6 +695,7 @@ static int usbhs_enable(struct device *dev) | |||
640 | struct usbhs_omap_platform_data *pdata = &omap->platdata; | 695 | struct usbhs_omap_platform_data *pdata = &omap->platdata; |
641 | unsigned long flags = 0; | 696 | unsigned long flags = 0; |
642 | int ret = 0; | 697 | int ret = 0; |
698 | unsigned long timeout; | ||
643 | unsigned reg; | 699 | unsigned reg; |
644 | 700 | ||
645 | dev_dbg(dev, "starting TI HSUSB Controller\n"); | 701 | dev_dbg(dev, "starting TI HSUSB Controller\n"); |
@@ -652,7 +708,11 @@ static int usbhs_enable(struct device *dev) | |||
652 | if (omap->count > 0) | 708 | if (omap->count > 0) |
653 | goto end_count; | 709 | goto end_count; |
654 | 710 | ||
655 | pm_runtime_get_sync(dev); | 711 | clk_enable(omap->usbhost_ick); |
712 | clk_enable(omap->usbhost_hs_fck); | ||
713 | clk_enable(omap->usbhost_fs_fck); | ||
714 | clk_enable(omap->usbtll_fck); | ||
715 | clk_enable(omap->usbtll_ick); | ||
656 | 716 | ||
657 | if (pdata->ehci_data->phy_reset) { | 717 | if (pdata->ehci_data->phy_reset) { |
658 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) { | 718 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) { |
@@ -676,6 +736,50 @@ static int usbhs_enable(struct device *dev) | |||
676 | omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); | 736 | omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION); |
677 | dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); | 737 | dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev); |
678 | 738 | ||
739 | /* perform TLL soft reset, and wait until reset is complete */ | ||
740 | usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, | ||
741 | OMAP_USBTLL_SYSCONFIG_SOFTRESET); | ||
742 | |||
743 | /* Wait for TLL reset to complete */ | ||
744 | timeout = jiffies + msecs_to_jiffies(1000); | ||
745 | while (!(usbhs_read(omap->tll_base, OMAP_USBTLL_SYSSTATUS) | ||
746 | & OMAP_USBTLL_SYSSTATUS_RESETDONE)) { | ||
747 | cpu_relax(); | ||
748 | |||
749 | if (time_after(jiffies, timeout)) { | ||
750 | dev_dbg(dev, "operation timed out\n"); | ||
751 | ret = -EINVAL; | ||
752 | goto err_tll; | ||
753 | } | ||
754 | } | ||
755 | |||
756 | dev_dbg(dev, "TLL RESET DONE\n"); | ||
757 | |||
758 | /* (1<<3) = no idle mode only for initial debugging */ | ||
759 | usbhs_write(omap->tll_base, OMAP_USBTLL_SYSCONFIG, | ||
760 | OMAP_USBTLL_SYSCONFIG_ENAWAKEUP | | ||
761 | OMAP_USBTLL_SYSCONFIG_SIDLEMODE | | ||
762 | OMAP_USBTLL_SYSCONFIG_AUTOIDLE); | ||
763 | |||
764 | /* Put UHH in NoIdle/NoStandby mode */ | ||
765 | reg = usbhs_read(omap->uhh_base, OMAP_UHH_SYSCONFIG); | ||
766 | if (is_omap_usbhs_rev1(omap)) { | ||
767 | reg |= (OMAP_UHH_SYSCONFIG_ENAWAKEUP | ||
768 | | OMAP_UHH_SYSCONFIG_SIDLEMODE | ||
769 | | OMAP_UHH_SYSCONFIG_CACTIVITY | ||
770 | | OMAP_UHH_SYSCONFIG_MIDLEMODE); | ||
771 | reg &= ~OMAP_UHH_SYSCONFIG_AUTOIDLE; | ||
772 | |||
773 | |||
774 | } else if (is_omap_usbhs_rev2(omap)) { | ||
775 | reg &= ~OMAP4_UHH_SYSCONFIG_IDLEMODE_CLEAR; | ||
776 | reg |= OMAP4_UHH_SYSCONFIG_NOIDLE; | ||
777 | reg &= ~OMAP4_UHH_SYSCONFIG_STDBYMODE_CLEAR; | ||
778 | reg |= OMAP4_UHH_SYSCONFIG_NOSTDBY; | ||
779 | } | ||
780 | |||
781 | usbhs_write(omap->uhh_base, OMAP_UHH_SYSCONFIG, reg); | ||
782 | |||
679 | reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG); | 783 | reg = usbhs_read(omap->uhh_base, OMAP_UHH_HOSTCONFIG); |
680 | /* setup ULPI bypass and burst configurations */ | 784 | /* setup ULPI bypass and burst configurations */ |
681 | reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN | 785 | reg |= (OMAP_UHH_HOSTCONFIG_INCR4_BURST_EN |
@@ -815,8 +919,6 @@ end_count: | |||
815 | return 0; | 919 | return 0; |
816 | 920 | ||
817 | err_tll: | 921 | err_tll: |
818 | pm_runtime_put_sync(dev); | ||
819 | spin_unlock_irqrestore(&omap->lock, flags); | ||
820 | if (pdata->ehci_data->phy_reset) { | 922 | if (pdata->ehci_data->phy_reset) { |
821 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) | 923 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0])) |
822 | gpio_free(pdata->ehci_data->reset_gpio_port[0]); | 924 | gpio_free(pdata->ehci_data->reset_gpio_port[0]); |
@@ -824,6 +926,13 @@ err_tll: | |||
824 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) | 926 | if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[1])) |
825 | gpio_free(pdata->ehci_data->reset_gpio_port[1]); | 927 | gpio_free(pdata->ehci_data->reset_gpio_port[1]); |
826 | } | 928 | } |
929 | |||
930 | clk_disable(omap->usbtll_ick); | ||
931 | clk_disable(omap->usbtll_fck); | ||
932 | clk_disable(omap->usbhost_fs_fck); | ||
933 | clk_disable(omap->usbhost_hs_fck); | ||
934 | clk_disable(omap->usbhost_ick); | ||
935 | spin_unlock_irqrestore(&omap->lock, flags); | ||
827 | return ret; | 936 | return ret; |
828 | } | 937 | } |
829 | 938 | ||
@@ -896,7 +1005,11 @@ static void usbhs_disable(struct device *dev) | |||
896 | clk_disable(omap->utmi_p1_fck); | 1005 | clk_disable(omap->utmi_p1_fck); |
897 | } | 1006 | } |
898 | 1007 | ||
899 | pm_runtime_put_sync(dev); | 1008 | clk_disable(omap->usbtll_ick); |
1009 | clk_disable(omap->usbtll_fck); | ||
1010 | clk_disable(omap->usbhost_fs_fck); | ||
1011 | clk_disable(omap->usbhost_hs_fck); | ||
1012 | clk_disable(omap->usbhost_ick); | ||
900 | 1013 | ||
901 | /* The gpio_free migh sleep; so unlock the spinlock */ | 1014 | /* The gpio_free migh sleep; so unlock the spinlock */ |
902 | spin_unlock_irqrestore(&omap->lock, flags); | 1015 | spin_unlock_irqrestore(&omap->lock, flags); |
diff --git a/drivers/mfd/tps65911-comparator.c b/drivers/mfd/tps65911-comparator.c index 3d2dc56a3d40..283ac6759757 100644 --- a/drivers/mfd/tps65911-comparator.c +++ b/drivers/mfd/tps65911-comparator.c | |||
@@ -125,7 +125,7 @@ static DEVICE_ATTR(comp2_threshold, S_IRUGO, comp_threshold_show, NULL); | |||
125 | static __devinit int tps65911_comparator_probe(struct platform_device *pdev) | 125 | static __devinit int tps65911_comparator_probe(struct platform_device *pdev) |
126 | { | 126 | { |
127 | struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); | 127 | struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); |
128 | struct tps65910_platform_data *pdata = dev_get_platdata(tps65910->dev); | 128 | struct tps65910_board *pdata = dev_get_platdata(tps65910->dev); |
129 | int ret; | 129 | int ret; |
130 | 130 | ||
131 | ret = comp_threshold_set(tps65910, COMP1, pdata->vmbch_threshold); | 131 | ret = comp_threshold_set(tps65910, COMP1, pdata->vmbch_threshold); |
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 2a7e43bc796d..aa7d1d79b8c5 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c | |||
@@ -247,12 +247,12 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
247 | return 0; | 247 | return 0; |
248 | 248 | ||
249 | /* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */ | 249 | /* Version is coded in the CSD_STRUCTURE byte in the EXT_CSD register */ |
250 | card->ext_csd.raw_ext_csd_structure = ext_csd[EXT_CSD_STRUCTURE]; | ||
250 | if (card->csd.structure == 3) { | 251 | if (card->csd.structure == 3) { |
251 | int ext_csd_struct = ext_csd[EXT_CSD_STRUCTURE]; | 252 | if (card->ext_csd.raw_ext_csd_structure > 2) { |
252 | if (ext_csd_struct > 2) { | ||
253 | printk(KERN_ERR "%s: unrecognised EXT_CSD structure " | 253 | printk(KERN_ERR "%s: unrecognised EXT_CSD structure " |
254 | "version %d\n", mmc_hostname(card->host), | 254 | "version %d\n", mmc_hostname(card->host), |
255 | ext_csd_struct); | 255 | card->ext_csd.raw_ext_csd_structure); |
256 | err = -EINVAL; | 256 | err = -EINVAL; |
257 | goto out; | 257 | goto out; |
258 | } | 258 | } |
@@ -266,6 +266,10 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
266 | goto out; | 266 | goto out; |
267 | } | 267 | } |
268 | 268 | ||
269 | card->ext_csd.raw_sectors[0] = ext_csd[EXT_CSD_SEC_CNT + 0]; | ||
270 | card->ext_csd.raw_sectors[1] = ext_csd[EXT_CSD_SEC_CNT + 1]; | ||
271 | card->ext_csd.raw_sectors[2] = ext_csd[EXT_CSD_SEC_CNT + 2]; | ||
272 | card->ext_csd.raw_sectors[3] = ext_csd[EXT_CSD_SEC_CNT + 3]; | ||
269 | if (card->ext_csd.rev >= 2) { | 273 | if (card->ext_csd.rev >= 2) { |
270 | card->ext_csd.sectors = | 274 | card->ext_csd.sectors = |
271 | ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | | 275 | ext_csd[EXT_CSD_SEC_CNT + 0] << 0 | |
@@ -277,7 +281,7 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
277 | if (card->ext_csd.sectors > (2u * 1024 * 1024 * 1024) / 512) | 281 | if (card->ext_csd.sectors > (2u * 1024 * 1024 * 1024) / 512) |
278 | mmc_card_set_blockaddr(card); | 282 | mmc_card_set_blockaddr(card); |
279 | } | 283 | } |
280 | 284 | card->ext_csd.raw_card_type = ext_csd[EXT_CSD_CARD_TYPE]; | |
281 | switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) { | 285 | switch (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_MASK) { |
282 | case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 | | 286 | case EXT_CSD_CARD_TYPE_DDR_52 | EXT_CSD_CARD_TYPE_52 | |
283 | EXT_CSD_CARD_TYPE_26: | 287 | EXT_CSD_CARD_TYPE_26: |
@@ -307,6 +311,11 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
307 | mmc_hostname(card->host)); | 311 | mmc_hostname(card->host)); |
308 | } | 312 | } |
309 | 313 | ||
314 | card->ext_csd.raw_s_a_timeout = ext_csd[EXT_CSD_S_A_TIMEOUT]; | ||
315 | card->ext_csd.raw_erase_timeout_mult = | ||
316 | ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]; | ||
317 | card->ext_csd.raw_hc_erase_grp_size = | ||
318 | ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; | ||
310 | if (card->ext_csd.rev >= 3) { | 319 | if (card->ext_csd.rev >= 3) { |
311 | u8 sa_shift = ext_csd[EXT_CSD_S_A_TIMEOUT]; | 320 | u8 sa_shift = ext_csd[EXT_CSD_S_A_TIMEOUT]; |
312 | card->ext_csd.part_config = ext_csd[EXT_CSD_PART_CONFIG]; | 321 | card->ext_csd.part_config = ext_csd[EXT_CSD_PART_CONFIG]; |
@@ -334,6 +343,16 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
334 | card->ext_csd.boot_size = ext_csd[EXT_CSD_BOOT_MULT] << 17; | 343 | card->ext_csd.boot_size = ext_csd[EXT_CSD_BOOT_MULT] << 17; |
335 | } | 344 | } |
336 | 345 | ||
346 | card->ext_csd.raw_hc_erase_gap_size = | ||
347 | ext_csd[EXT_CSD_PARTITION_ATTRIBUTE]; | ||
348 | card->ext_csd.raw_sec_trim_mult = | ||
349 | ext_csd[EXT_CSD_SEC_TRIM_MULT]; | ||
350 | card->ext_csd.raw_sec_erase_mult = | ||
351 | ext_csd[EXT_CSD_SEC_ERASE_MULT]; | ||
352 | card->ext_csd.raw_sec_feature_support = | ||
353 | ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]; | ||
354 | card->ext_csd.raw_trim_mult = | ||
355 | ext_csd[EXT_CSD_TRIM_MULT]; | ||
337 | if (card->ext_csd.rev >= 4) { | 356 | if (card->ext_csd.rev >= 4) { |
338 | /* | 357 | /* |
339 | * Enhanced area feature support -- check whether the eMMC | 358 | * Enhanced area feature support -- check whether the eMMC |
@@ -341,7 +360,7 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) | |||
341 | * area offset and size to user by adding sysfs interface. | 360 | * area offset and size to user by adding sysfs interface. |
342 | */ | 361 | */ |
343 | if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) && | 362 | if ((ext_csd[EXT_CSD_PARTITION_SUPPORT] & 0x2) && |
344 | (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) { | 363 | (ext_csd[EXT_CSD_PARTITION_ATTRIBUTE] & 0x1)) { |
345 | u8 hc_erase_grp_sz = | 364 | u8 hc_erase_grp_sz = |
346 | ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; | 365 | ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]; |
347 | u8 hc_wp_grp_sz = | 366 | u8 hc_wp_grp_sz = |
@@ -401,17 +420,17 @@ static inline void mmc_free_ext_csd(u8 *ext_csd) | |||
401 | } | 420 | } |
402 | 421 | ||
403 | 422 | ||
404 | static int mmc_compare_ext_csds(struct mmc_card *card, u8 *ext_csd, | 423 | static int mmc_compare_ext_csds(struct mmc_card *card, unsigned bus_width) |
405 | unsigned bus_width) | ||
406 | { | 424 | { |
407 | u8 *bw_ext_csd; | 425 | u8 *bw_ext_csd; |
408 | int err; | 426 | int err; |
409 | 427 | ||
428 | if (bus_width == MMC_BUS_WIDTH_1) | ||
429 | return 0; | ||
430 | |||
410 | err = mmc_get_ext_csd(card, &bw_ext_csd); | 431 | err = mmc_get_ext_csd(card, &bw_ext_csd); |
411 | if (err) | ||
412 | return err; | ||
413 | 432 | ||
414 | if ((ext_csd == NULL || bw_ext_csd == NULL)) { | 433 | if (err || bw_ext_csd == NULL) { |
415 | if (bus_width != MMC_BUS_WIDTH_1) | 434 | if (bus_width != MMC_BUS_WIDTH_1) |
416 | err = -EINVAL; | 435 | err = -EINVAL; |
417 | goto out; | 436 | goto out; |
@@ -421,35 +440,40 @@ static int mmc_compare_ext_csds(struct mmc_card *card, u8 *ext_csd, | |||
421 | goto out; | 440 | goto out; |
422 | 441 | ||
423 | /* only compare read only fields */ | 442 | /* only compare read only fields */ |
424 | err = (!(ext_csd[EXT_CSD_PARTITION_SUPPORT] == | 443 | err = (!(card->ext_csd.raw_partition_support == |
425 | bw_ext_csd[EXT_CSD_PARTITION_SUPPORT]) && | 444 | bw_ext_csd[EXT_CSD_PARTITION_SUPPORT]) && |
426 | (ext_csd[EXT_CSD_ERASED_MEM_CONT] == | 445 | (card->ext_csd.raw_erased_mem_count == |
427 | bw_ext_csd[EXT_CSD_ERASED_MEM_CONT]) && | 446 | bw_ext_csd[EXT_CSD_ERASED_MEM_CONT]) && |
428 | (ext_csd[EXT_CSD_REV] == | 447 | (card->ext_csd.rev == |
429 | bw_ext_csd[EXT_CSD_REV]) && | 448 | bw_ext_csd[EXT_CSD_REV]) && |
430 | (ext_csd[EXT_CSD_STRUCTURE] == | 449 | (card->ext_csd.raw_ext_csd_structure == |
431 | bw_ext_csd[EXT_CSD_STRUCTURE]) && | 450 | bw_ext_csd[EXT_CSD_STRUCTURE]) && |
432 | (ext_csd[EXT_CSD_CARD_TYPE] == | 451 | (card->ext_csd.raw_card_type == |
433 | bw_ext_csd[EXT_CSD_CARD_TYPE]) && | 452 | bw_ext_csd[EXT_CSD_CARD_TYPE]) && |
434 | (ext_csd[EXT_CSD_S_A_TIMEOUT] == | 453 | (card->ext_csd.raw_s_a_timeout == |
435 | bw_ext_csd[EXT_CSD_S_A_TIMEOUT]) && | 454 | bw_ext_csd[EXT_CSD_S_A_TIMEOUT]) && |
436 | (ext_csd[EXT_CSD_HC_WP_GRP_SIZE] == | 455 | (card->ext_csd.raw_hc_erase_gap_size == |
437 | bw_ext_csd[EXT_CSD_HC_WP_GRP_SIZE]) && | 456 | bw_ext_csd[EXT_CSD_HC_WP_GRP_SIZE]) && |
438 | (ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT] == | 457 | (card->ext_csd.raw_erase_timeout_mult == |
439 | bw_ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]) && | 458 | bw_ext_csd[EXT_CSD_ERASE_TIMEOUT_MULT]) && |
440 | (ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] == | 459 | (card->ext_csd.raw_hc_erase_grp_size == |
441 | bw_ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]) && | 460 | bw_ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE]) && |
442 | (ext_csd[EXT_CSD_SEC_TRIM_MULT] == | 461 | (card->ext_csd.raw_sec_trim_mult == |
443 | bw_ext_csd[EXT_CSD_SEC_TRIM_MULT]) && | 462 | bw_ext_csd[EXT_CSD_SEC_TRIM_MULT]) && |
444 | (ext_csd[EXT_CSD_SEC_ERASE_MULT] == | 463 | (card->ext_csd.raw_sec_erase_mult == |
445 | bw_ext_csd[EXT_CSD_SEC_ERASE_MULT]) && | 464 | bw_ext_csd[EXT_CSD_SEC_ERASE_MULT]) && |
446 | (ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT] == | 465 | (card->ext_csd.raw_sec_feature_support == |
447 | bw_ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]) && | 466 | bw_ext_csd[EXT_CSD_SEC_FEATURE_SUPPORT]) && |
448 | (ext_csd[EXT_CSD_TRIM_MULT] == | 467 | (card->ext_csd.raw_trim_mult == |
449 | bw_ext_csd[EXT_CSD_TRIM_MULT]) && | 468 | bw_ext_csd[EXT_CSD_TRIM_MULT]) && |
450 | memcmp(&ext_csd[EXT_CSD_SEC_CNT], | 469 | (card->ext_csd.raw_sectors[0] == |
451 | &bw_ext_csd[EXT_CSD_SEC_CNT], | 470 | bw_ext_csd[EXT_CSD_SEC_CNT + 0]) && |
452 | 4) != 0); | 471 | (card->ext_csd.raw_sectors[1] == |
472 | bw_ext_csd[EXT_CSD_SEC_CNT + 1]) && | ||
473 | (card->ext_csd.raw_sectors[2] == | ||
474 | bw_ext_csd[EXT_CSD_SEC_CNT + 2]) && | ||
475 | (card->ext_csd.raw_sectors[3] == | ||
476 | bw_ext_csd[EXT_CSD_SEC_CNT + 3])); | ||
453 | if (err) | 477 | if (err) |
454 | err = -EINVAL; | 478 | err = -EINVAL; |
455 | 479 | ||
@@ -770,7 +794,6 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, | |||
770 | */ | 794 | */ |
771 | if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST)) | 795 | if (!(host->caps & MMC_CAP_BUS_WIDTH_TEST)) |
772 | err = mmc_compare_ext_csds(card, | 796 | err = mmc_compare_ext_csds(card, |
773 | ext_csd, | ||
774 | bus_width); | 797 | bus_width); |
775 | else | 798 | else |
776 | err = mmc_bus_test(card, bus_width); | 799 | err = mmc_bus_test(card, bus_width); |
diff --git a/drivers/mmc/host/mmci.c b/drivers/mmc/host/mmci.c index 7721de942c69..50f4f77ed202 100644 --- a/drivers/mmc/host/mmci.c +++ b/drivers/mmc/host/mmci.c | |||
@@ -582,6 +582,8 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data, | |||
582 | data->error = -EILSEQ; | 582 | data->error = -EILSEQ; |
583 | } else if (status & MCI_DATATIMEOUT) { | 583 | } else if (status & MCI_DATATIMEOUT) { |
584 | data->error = -ETIMEDOUT; | 584 | data->error = -ETIMEDOUT; |
585 | } else if (status & MCI_STARTBITERR) { | ||
586 | data->error = -ECOMM; | ||
585 | } else if (status & MCI_TXUNDERRUN) { | 587 | } else if (status & MCI_TXUNDERRUN) { |
586 | data->error = -EIO; | 588 | data->error = -EIO; |
587 | } else if (status & MCI_RXOVERRUN) { | 589 | } else if (status & MCI_RXOVERRUN) { |
@@ -1061,7 +1063,15 @@ static int __devinit mmci_probe(struct amba_device *dev, | |||
1061 | } | 1063 | } |
1062 | 1064 | ||
1063 | mmc->ops = &mmci_ops; | 1065 | mmc->ops = &mmci_ops; |
1064 | mmc->f_min = (host->mclk + 511) / 512; | 1066 | /* |
1067 | * The ARM and ST versions of the block have slightly different | ||
1068 | * clock divider equations which means that the minimum divider | ||
1069 | * differs too. | ||
1070 | */ | ||
1071 | if (variant->st_clkdiv) | ||
1072 | mmc->f_min = DIV_ROUND_UP(host->mclk, 257); | ||
1073 | else | ||
1074 | mmc->f_min = DIV_ROUND_UP(host->mclk, 512); | ||
1065 | /* | 1075 | /* |
1066 | * If the platform data supplies a maximum operating | 1076 | * If the platform data supplies a maximum operating |
1067 | * frequency, this takes precedence. Else, we fall back | 1077 | * frequency, this takes precedence. Else, we fall back |
diff --git a/drivers/mmc/host/mmci.h b/drivers/mmc/host/mmci.h index bb32e21c09db..2164e8c6476c 100644 --- a/drivers/mmc/host/mmci.h +++ b/drivers/mmc/host/mmci.h | |||
@@ -86,6 +86,7 @@ | |||
86 | #define MCI_CMDRESPEND (1 << 6) | 86 | #define MCI_CMDRESPEND (1 << 6) |
87 | #define MCI_CMDSENT (1 << 7) | 87 | #define MCI_CMDSENT (1 << 7) |
88 | #define MCI_DATAEND (1 << 8) | 88 | #define MCI_DATAEND (1 << 8) |
89 | #define MCI_STARTBITERR (1 << 9) | ||
89 | #define MCI_DATABLOCKEND (1 << 10) | 90 | #define MCI_DATABLOCKEND (1 << 10) |
90 | #define MCI_CMDACTIVE (1 << 11) | 91 | #define MCI_CMDACTIVE (1 << 11) |
91 | #define MCI_TXACTIVE (1 << 12) | 92 | #define MCI_TXACTIVE (1 << 12) |
@@ -112,6 +113,7 @@ | |||
112 | #define MCI_CMDRESPENDCLR (1 << 6) | 113 | #define MCI_CMDRESPENDCLR (1 << 6) |
113 | #define MCI_CMDSENTCLR (1 << 7) | 114 | #define MCI_CMDSENTCLR (1 << 7) |
114 | #define MCI_DATAENDCLR (1 << 8) | 115 | #define MCI_DATAENDCLR (1 << 8) |
116 | #define MCI_STARTBITERRCLR (1 << 9) | ||
115 | #define MCI_DATABLOCKENDCLR (1 << 10) | 117 | #define MCI_DATABLOCKENDCLR (1 << 10) |
116 | /* Extended status bits for the ST Micro variants */ | 118 | /* Extended status bits for the ST Micro variants */ |
117 | #define MCI_ST_SDIOITC (1 << 22) | 119 | #define MCI_ST_SDIOITC (1 << 22) |
@@ -127,6 +129,7 @@ | |||
127 | #define MCI_CMDRESPENDMASK (1 << 6) | 129 | #define MCI_CMDRESPENDMASK (1 << 6) |
128 | #define MCI_CMDSENTMASK (1 << 7) | 130 | #define MCI_CMDSENTMASK (1 << 7) |
129 | #define MCI_DATAENDMASK (1 << 8) | 131 | #define MCI_DATAENDMASK (1 << 8) |
132 | #define MCI_STARTBITERRMASK (1 << 9) | ||
130 | #define MCI_DATABLOCKENDMASK (1 << 10) | 133 | #define MCI_DATABLOCKENDMASK (1 << 10) |
131 | #define MCI_CMDACTIVEMASK (1 << 11) | 134 | #define MCI_CMDACTIVEMASK (1 << 11) |
132 | #define MCI_TXACTIVEMASK (1 << 12) | 135 | #define MCI_TXACTIVEMASK (1 << 12) |
@@ -150,7 +153,7 @@ | |||
150 | #define MCI_IRQENABLE \ | 153 | #define MCI_IRQENABLE \ |
151 | (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \ | 154 | (MCI_CMDCRCFAILMASK|MCI_DATACRCFAILMASK|MCI_CMDTIMEOUTMASK| \ |
152 | MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \ | 155 | MCI_DATATIMEOUTMASK|MCI_TXUNDERRUNMASK|MCI_RXOVERRUNMASK| \ |
153 | MCI_CMDRESPENDMASK|MCI_CMDSENTMASK) | 156 | MCI_CMDRESPENDMASK|MCI_CMDSENTMASK|MCI_STARTBITERRMASK) |
154 | 157 | ||
155 | /* These interrupts are directed to IRQ1 when two IRQ lines are available */ | 158 | /* These interrupts are directed to IRQ1 when two IRQ lines are available */ |
156 | #define MCI_IRQ1MASK \ | 159 | #define MCI_IRQ1MASK \ |
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c index 98517a373473..e3bad8247fd1 100644 --- a/drivers/net/8139too.c +++ b/drivers/net/8139too.c | |||
@@ -992,6 +992,7 @@ static int __devinit rtl8139_init_one (struct pci_dev *pdev, | |||
992 | * features | 992 | * features |
993 | */ | 993 | */ |
994 | dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA; | 994 | dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_HIGHDMA; |
995 | dev->vlan_features = dev->features; | ||
995 | 996 | ||
996 | dev->irq = pdev->irq; | 997 | dev->irq = pdev->irq; |
997 | 998 | ||
diff --git a/drivers/net/bna/bnad.c b/drivers/net/bna/bnad.c index 7d25a97d33f6..44e219c910da 100644 --- a/drivers/net/bna/bnad.c +++ b/drivers/net/bna/bnad.c | |||
@@ -1111,7 +1111,7 @@ bnad_mbox_irq_alloc(struct bnad *bnad, | |||
1111 | struct bna_intr_info *intr_info) | 1111 | struct bna_intr_info *intr_info) |
1112 | { | 1112 | { |
1113 | int err = 0; | 1113 | int err = 0; |
1114 | unsigned long flags; | 1114 | unsigned long irq_flags = 0, flags; |
1115 | u32 irq; | 1115 | u32 irq; |
1116 | irq_handler_t irq_handler; | 1116 | irq_handler_t irq_handler; |
1117 | 1117 | ||
@@ -1125,18 +1125,17 @@ bnad_mbox_irq_alloc(struct bnad *bnad, | |||
1125 | if (bnad->cfg_flags & BNAD_CF_MSIX) { | 1125 | if (bnad->cfg_flags & BNAD_CF_MSIX) { |
1126 | irq_handler = (irq_handler_t)bnad_msix_mbox_handler; | 1126 | irq_handler = (irq_handler_t)bnad_msix_mbox_handler; |
1127 | irq = bnad->msix_table[bnad->msix_num - 1].vector; | 1127 | irq = bnad->msix_table[bnad->msix_num - 1].vector; |
1128 | flags = 0; | ||
1129 | intr_info->intr_type = BNA_INTR_T_MSIX; | 1128 | intr_info->intr_type = BNA_INTR_T_MSIX; |
1130 | intr_info->idl[0].vector = bnad->msix_num - 1; | 1129 | intr_info->idl[0].vector = bnad->msix_num - 1; |
1131 | } else { | 1130 | } else { |
1132 | irq_handler = (irq_handler_t)bnad_isr; | 1131 | irq_handler = (irq_handler_t)bnad_isr; |
1133 | irq = bnad->pcidev->irq; | 1132 | irq = bnad->pcidev->irq; |
1134 | flags = IRQF_SHARED; | 1133 | irq_flags = IRQF_SHARED; |
1135 | intr_info->intr_type = BNA_INTR_T_INTX; | 1134 | intr_info->intr_type = BNA_INTR_T_INTX; |
1136 | /* intr_info->idl.vector = 0 ? */ | 1135 | /* intr_info->idl.vector = 0 ? */ |
1137 | } | 1136 | } |
1138 | spin_unlock_irqrestore(&bnad->bna_lock, flags); | 1137 | spin_unlock_irqrestore(&bnad->bna_lock, flags); |
1139 | 1138 | flags = irq_flags; | |
1140 | sprintf(bnad->mbox_irq_name, "%s", BNAD_NAME); | 1139 | sprintf(bnad->mbox_irq_name, "%s", BNAD_NAME); |
1141 | 1140 | ||
1142 | /* | 1141 | /* |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index eafe44a528ac..63c22b0bb5ad 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1428,9 +1428,9 @@ out: | |||
1428 | return features; | 1428 | return features; |
1429 | } | 1429 | } |
1430 | 1430 | ||
1431 | #define BOND_VLAN_FEATURES (NETIF_F_ALL_TX_OFFLOADS | \ | 1431 | #define BOND_VLAN_FEATURES (NETIF_F_ALL_CSUM | NETIF_F_SG | \ |
1432 | NETIF_F_SOFT_FEATURES | \ | 1432 | NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \ |
1433 | NETIF_F_LRO) | 1433 | NETIF_F_HIGHDMA | NETIF_F_LRO) |
1434 | 1434 | ||
1435 | static void bond_compute_features(struct bonding *bond) | 1435 | static void bond_compute_features(struct bonding *bond) |
1436 | { | 1436 | { |
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 2dfcc8047847..dfa55f94ba7f 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
@@ -2289,6 +2289,23 @@ static int gfar_set_mac_address(struct net_device *dev) | |||
2289 | return 0; | 2289 | return 0; |
2290 | } | 2290 | } |
2291 | 2291 | ||
2292 | /* Check if rx parser should be activated */ | ||
2293 | void gfar_check_rx_parser_mode(struct gfar_private *priv) | ||
2294 | { | ||
2295 | struct gfar __iomem *regs; | ||
2296 | u32 tempval; | ||
2297 | |||
2298 | regs = priv->gfargrp[0].regs; | ||
2299 | |||
2300 | tempval = gfar_read(®s->rctrl); | ||
2301 | /* If parse is no longer required, then disable parser */ | ||
2302 | if (tempval & RCTRL_REQ_PARSER) | ||
2303 | tempval |= RCTRL_PRSDEP_INIT; | ||
2304 | else | ||
2305 | tempval &= ~RCTRL_PRSDEP_INIT; | ||
2306 | gfar_write(®s->rctrl, tempval); | ||
2307 | } | ||
2308 | |||
2292 | 2309 | ||
2293 | /* Enables and disables VLAN insertion/extraction */ | 2310 | /* Enables and disables VLAN insertion/extraction */ |
2294 | static void gfar_vlan_rx_register(struct net_device *dev, | 2311 | static void gfar_vlan_rx_register(struct net_device *dev, |
@@ -2325,12 +2342,9 @@ static void gfar_vlan_rx_register(struct net_device *dev, | |||
2325 | /* Disable VLAN tag extraction */ | 2342 | /* Disable VLAN tag extraction */ |
2326 | tempval = gfar_read(®s->rctrl); | 2343 | tempval = gfar_read(®s->rctrl); |
2327 | tempval &= ~RCTRL_VLEX; | 2344 | tempval &= ~RCTRL_VLEX; |
2328 | /* If parse is no longer required, then disable parser */ | ||
2329 | if (tempval & RCTRL_REQ_PARSER) | ||
2330 | tempval |= RCTRL_PRSDEP_INIT; | ||
2331 | else | ||
2332 | tempval &= ~RCTRL_PRSDEP_INIT; | ||
2333 | gfar_write(®s->rctrl, tempval); | 2345 | gfar_write(®s->rctrl, tempval); |
2346 | |||
2347 | gfar_check_rx_parser_mode(priv); | ||
2334 | } | 2348 | } |
2335 | 2349 | ||
2336 | gfar_change_mtu(dev, dev->mtu); | 2350 | gfar_change_mtu(dev, dev->mtu); |
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index ba36dc7a3435..440e69d8beff 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h | |||
@@ -274,7 +274,7 @@ extern const char gfar_driver_version[]; | |||
274 | #define RCTRL_PROM 0x00000008 | 274 | #define RCTRL_PROM 0x00000008 |
275 | #define RCTRL_EMEN 0x00000002 | 275 | #define RCTRL_EMEN 0x00000002 |
276 | #define RCTRL_REQ_PARSER (RCTRL_VLEX | RCTRL_IPCSEN | \ | 276 | #define RCTRL_REQ_PARSER (RCTRL_VLEX | RCTRL_IPCSEN | \ |
277 | RCTRL_TUCSEN) | 277 | RCTRL_TUCSEN | RCTRL_FILREN) |
278 | #define RCTRL_CHECKSUMMING (RCTRL_IPCSEN | RCTRL_TUCSEN | \ | 278 | #define RCTRL_CHECKSUMMING (RCTRL_IPCSEN | RCTRL_TUCSEN | \ |
279 | RCTRL_PRSDEP_INIT) | 279 | RCTRL_PRSDEP_INIT) |
280 | #define RCTRL_EXTHASH (RCTRL_GHTX) | 280 | #define RCTRL_EXTHASH (RCTRL_GHTX) |
@@ -1156,6 +1156,7 @@ extern void gfar_configure_coalescing(struct gfar_private *priv, | |||
1156 | unsigned long tx_mask, unsigned long rx_mask); | 1156 | unsigned long tx_mask, unsigned long rx_mask); |
1157 | void gfar_init_sysfs(struct net_device *dev); | 1157 | void gfar_init_sysfs(struct net_device *dev); |
1158 | int gfar_set_features(struct net_device *dev, u32 features); | 1158 | int gfar_set_features(struct net_device *dev, u32 features); |
1159 | extern void gfar_check_rx_parser_mode(struct gfar_private *priv); | ||
1159 | 1160 | ||
1160 | extern const struct ethtool_ops gfar_ethtool_ops; | 1161 | extern const struct ethtool_ops gfar_ethtool_ops; |
1161 | 1162 | ||
diff --git a/drivers/net/greth.c b/drivers/net/greth.c index f181304a7ab6..672f096fe090 100644 --- a/drivers/net/greth.c +++ b/drivers/net/greth.c | |||
@@ -1015,11 +1015,10 @@ static int greth_set_mac_add(struct net_device *dev, void *p) | |||
1015 | return -EINVAL; | 1015 | return -EINVAL; |
1016 | 1016 | ||
1017 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); | 1017 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); |
1018 | GRETH_REGSAVE(regs->esa_msb, dev->dev_addr[0] << 8 | dev->dev_addr[1]); | ||
1019 | GRETH_REGSAVE(regs->esa_lsb, dev->dev_addr[2] << 24 | dev->dev_addr[3] << 16 | | ||
1020 | dev->dev_addr[4] << 8 | dev->dev_addr[5]); | ||
1018 | 1021 | ||
1019 | GRETH_REGSAVE(regs->esa_msb, addr->sa_data[0] << 8 | addr->sa_data[1]); | ||
1020 | GRETH_REGSAVE(regs->esa_lsb, | ||
1021 | addr->sa_data[2] << 24 | addr-> | ||
1022 | sa_data[3] << 16 | addr->sa_data[4] << 8 | addr->sa_data[5]); | ||
1023 | return 0; | 1022 | return 0; |
1024 | } | 1023 | } |
1025 | 1024 | ||
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index 3e5d0b6b6516..0d283781bc5e 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c | |||
@@ -692,10 +692,10 @@ static void sixpack_close(struct tty_struct *tty) | |||
692 | { | 692 | { |
693 | struct sixpack *sp; | 693 | struct sixpack *sp; |
694 | 694 | ||
695 | write_lock(&disc_data_lock); | 695 | write_lock_bh(&disc_data_lock); |
696 | sp = tty->disc_data; | 696 | sp = tty->disc_data; |
697 | tty->disc_data = NULL; | 697 | tty->disc_data = NULL; |
698 | write_unlock(&disc_data_lock); | 698 | write_unlock_bh(&disc_data_lock); |
699 | if (!sp) | 699 | if (!sp) |
700 | return; | 700 | return; |
701 | 701 | ||
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 4c628393c8b1..bc02968cee16 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c | |||
@@ -813,10 +813,10 @@ static void mkiss_close(struct tty_struct *tty) | |||
813 | { | 813 | { |
814 | struct mkiss *ax; | 814 | struct mkiss *ax; |
815 | 815 | ||
816 | write_lock(&disc_data_lock); | 816 | write_lock_bh(&disc_data_lock); |
817 | ax = tty->disc_data; | 817 | ax = tty->disc_data; |
818 | tty->disc_data = NULL; | 818 | tty->disc_data = NULL; |
819 | write_unlock(&disc_data_lock); | 819 | write_unlock_bh(&disc_data_lock); |
820 | 820 | ||
821 | if (!ax) | 821 | if (!ax) |
822 | return; | 822 | return; |
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index b78be088c4ad..60f46bc2bf64 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c | |||
@@ -140,7 +140,7 @@ MODULE_LICENSE("GPL"); | |||
140 | module_param(mtu, int, 0); | 140 | module_param(mtu, int, 0); |
141 | module_param(debug, int, 0); | 141 | module_param(debug, int, 0); |
142 | module_param(rx_copybreak, int, 0); | 142 | module_param(rx_copybreak, int, 0); |
143 | module_param(dspcfg_workaround, int, 1); | 143 | module_param(dspcfg_workaround, int, 0); |
144 | module_param_array(options, int, NULL, 0); | 144 | module_param_array(options, int, NULL, 0); |
145 | module_param_array(full_duplex, int, NULL, 0); | 145 | module_param_array(full_duplex, int, NULL, 0); |
146 | MODULE_PARM_DESC(mtu, "DP8381x MTU (all boards)"); | 146 | MODULE_PARM_DESC(mtu, "DP8381x MTU (all boards)"); |
@@ -2028,8 +2028,8 @@ static void drain_rx(struct net_device *dev) | |||
2028 | np->rx_ring[i].cmd_status = 0; | 2028 | np->rx_ring[i].cmd_status = 0; |
2029 | np->rx_ring[i].addr = cpu_to_le32(0xBADF00D0); /* An invalid address. */ | 2029 | np->rx_ring[i].addr = cpu_to_le32(0xBADF00D0); /* An invalid address. */ |
2030 | if (np->rx_skbuff[i]) { | 2030 | if (np->rx_skbuff[i]) { |
2031 | pci_unmap_single(np->pci_dev, | 2031 | pci_unmap_single(np->pci_dev, np->rx_dma[i], |
2032 | np->rx_dma[i], buflen, | 2032 | buflen + NATSEMI_PADDING, |
2033 | PCI_DMA_FROMDEVICE); | 2033 | PCI_DMA_FROMDEVICE); |
2034 | dev_kfree_skb(np->rx_skbuff[i]); | 2034 | dev_kfree_skb(np->rx_skbuff[i]); |
2035 | } | 2035 | } |
@@ -2360,7 +2360,8 @@ static void netdev_rx(struct net_device *dev, int *work_done, int work_to_do) | |||
2360 | PCI_DMA_FROMDEVICE); | 2360 | PCI_DMA_FROMDEVICE); |
2361 | } else { | 2361 | } else { |
2362 | pci_unmap_single(np->pci_dev, np->rx_dma[entry], | 2362 | pci_unmap_single(np->pci_dev, np->rx_dma[entry], |
2363 | buflen, PCI_DMA_FROMDEVICE); | 2363 | buflen + NATSEMI_PADDING, |
2364 | PCI_DMA_FROMDEVICE); | ||
2364 | skb_put(skb = np->rx_skbuff[entry], pkt_len); | 2365 | skb_put(skb = np->rx_skbuff[entry], pkt_len); |
2365 | np->rx_skbuff[entry] = NULL; | 2366 | np->rx_skbuff[entry] = NULL; |
2366 | } | 2367 | } |
diff --git a/drivers/net/pppoe.c b/drivers/net/pppoe.c index 718879b35b7d..bc9a4bb31980 100644 --- a/drivers/net/pppoe.c +++ b/drivers/net/pppoe.c | |||
@@ -348,8 +348,9 @@ static int pppoe_device_event(struct notifier_block *this, | |||
348 | 348 | ||
349 | /* Only look at sockets that are using this specific device. */ | 349 | /* Only look at sockets that are using this specific device. */ |
350 | switch (event) { | 350 | switch (event) { |
351 | case NETDEV_CHANGEADDR: | ||
351 | case NETDEV_CHANGEMTU: | 352 | case NETDEV_CHANGEMTU: |
352 | /* A change in mtu is a bad thing, requiring | 353 | /* A change in mtu or address is a bad thing, requiring |
353 | * LCP re-negotiation. | 354 | * LCP re-negotiation. |
354 | */ | 355 | */ |
355 | 356 | ||
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h index d32850715f5c..ca306fd5f588 100644 --- a/drivers/net/qlge/qlge.h +++ b/drivers/net/qlge/qlge.h | |||
@@ -16,7 +16,7 @@ | |||
16 | */ | 16 | */ |
17 | #define DRV_NAME "qlge" | 17 | #define DRV_NAME "qlge" |
18 | #define DRV_STRING "QLogic 10 Gigabit PCI-E Ethernet Driver " | 18 | #define DRV_STRING "QLogic 10 Gigabit PCI-E Ethernet Driver " |
19 | #define DRV_VERSION "v1.00.00.27.00.00-01" | 19 | #define DRV_VERSION "v1.00.00.29.00.00-01" |
20 | 20 | ||
21 | #define WQ_ADDR_ALIGN 0x3 /* 4 byte alignment */ | 21 | #define WQ_ADDR_ALIGN 0x3 /* 4 byte alignment */ |
22 | 22 | ||
@@ -1996,6 +1996,7 @@ enum { | |||
1996 | QL_LB_LINK_UP = 10, | 1996 | QL_LB_LINK_UP = 10, |
1997 | QL_FRC_COREDUMP = 11, | 1997 | QL_FRC_COREDUMP = 11, |
1998 | QL_EEH_FATAL = 12, | 1998 | QL_EEH_FATAL = 12, |
1999 | QL_ASIC_RECOVERY = 14, /* We are in ascic recovery. */ | ||
1999 | }; | 2000 | }; |
2000 | 2001 | ||
2001 | /* link_status bit definitions */ | 2002 | /* link_status bit definitions */ |
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c index 930ae45457bb..6b4ff970972b 100644 --- a/drivers/net/qlge/qlge_main.c +++ b/drivers/net/qlge/qlge_main.c | |||
@@ -2152,6 +2152,10 @@ void ql_queue_asic_error(struct ql_adapter *qdev) | |||
2152 | * thread | 2152 | * thread |
2153 | */ | 2153 | */ |
2154 | clear_bit(QL_ADAPTER_UP, &qdev->flags); | 2154 | clear_bit(QL_ADAPTER_UP, &qdev->flags); |
2155 | /* Set asic recovery bit to indicate reset process that we are | ||
2156 | * in fatal error recovery process rather than normal close | ||
2157 | */ | ||
2158 | set_bit(QL_ASIC_RECOVERY, &qdev->flags); | ||
2155 | queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0); | 2159 | queue_delayed_work(qdev->workqueue, &qdev->asic_reset_work, 0); |
2156 | } | 2160 | } |
2157 | 2161 | ||
@@ -2166,23 +2170,20 @@ static void ql_process_chip_ae_intr(struct ql_adapter *qdev, | |||
2166 | return; | 2170 | return; |
2167 | 2171 | ||
2168 | case CAM_LOOKUP_ERR_EVENT: | 2172 | case CAM_LOOKUP_ERR_EVENT: |
2169 | netif_err(qdev, link, qdev->ndev, | 2173 | netdev_err(qdev->ndev, "Multiple CAM hits lookup occurred.\n"); |
2170 | "Multiple CAM hits lookup occurred.\n"); | 2174 | netdev_err(qdev->ndev, "This event shouldn't occur.\n"); |
2171 | netif_err(qdev, drv, qdev->ndev, | ||
2172 | "This event shouldn't occur.\n"); | ||
2173 | ql_queue_asic_error(qdev); | 2175 | ql_queue_asic_error(qdev); |
2174 | return; | 2176 | return; |
2175 | 2177 | ||
2176 | case SOFT_ECC_ERROR_EVENT: | 2178 | case SOFT_ECC_ERROR_EVENT: |
2177 | netif_err(qdev, rx_err, qdev->ndev, | 2179 | netdev_err(qdev->ndev, "Soft ECC error detected.\n"); |
2178 | "Soft ECC error detected.\n"); | ||
2179 | ql_queue_asic_error(qdev); | 2180 | ql_queue_asic_error(qdev); |
2180 | break; | 2181 | break; |
2181 | 2182 | ||
2182 | case PCI_ERR_ANON_BUF_RD: | 2183 | case PCI_ERR_ANON_BUF_RD: |
2183 | netif_err(qdev, rx_err, qdev->ndev, | 2184 | netdev_err(qdev->ndev, "PCI error occurred when reading " |
2184 | "PCI error occurred when reading anonymous buffers from rx_ring %d.\n", | 2185 | "anonymous buffers from rx_ring %d.\n", |
2185 | ib_ae_rsp->q_id); | 2186 | ib_ae_rsp->q_id); |
2186 | ql_queue_asic_error(qdev); | 2187 | ql_queue_asic_error(qdev); |
2187 | break; | 2188 | break; |
2188 | 2189 | ||
@@ -2437,11 +2438,10 @@ static irqreturn_t qlge_isr(int irq, void *dev_id) | |||
2437 | */ | 2438 | */ |
2438 | if (var & STS_FE) { | 2439 | if (var & STS_FE) { |
2439 | ql_queue_asic_error(qdev); | 2440 | ql_queue_asic_error(qdev); |
2440 | netif_err(qdev, intr, qdev->ndev, | 2441 | netdev_err(qdev->ndev, "Got fatal error, STS = %x.\n", var); |
2441 | "Got fatal error, STS = %x.\n", var); | ||
2442 | var = ql_read32(qdev, ERR_STS); | 2442 | var = ql_read32(qdev, ERR_STS); |
2443 | netif_err(qdev, intr, qdev->ndev, | 2443 | netdev_err(qdev->ndev, "Resetting chip. " |
2444 | "Resetting chip. Error Status Register = 0x%x\n", var); | 2444 | "Error Status Register = 0x%x\n", var); |
2445 | return IRQ_HANDLED; | 2445 | return IRQ_HANDLED; |
2446 | } | 2446 | } |
2447 | 2447 | ||
@@ -3818,11 +3818,17 @@ static int ql_adapter_reset(struct ql_adapter *qdev) | |||
3818 | end_jiffies = jiffies + | 3818 | end_jiffies = jiffies + |
3819 | max((unsigned long)1, usecs_to_jiffies(30)); | 3819 | max((unsigned long)1, usecs_to_jiffies(30)); |
3820 | 3820 | ||
3821 | /* Stop management traffic. */ | 3821 | /* Check if bit is set then skip the mailbox command and |
3822 | ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_STOP); | 3822 | * clear the bit, else we are in normal reset process. |
3823 | */ | ||
3824 | if (!test_bit(QL_ASIC_RECOVERY, &qdev->flags)) { | ||
3825 | /* Stop management traffic. */ | ||
3826 | ql_mb_set_mgmnt_traffic_ctl(qdev, MB_SET_MPI_TFK_STOP); | ||
3823 | 3827 | ||
3824 | /* Wait for the NIC and MGMNT FIFOs to empty. */ | 3828 | /* Wait for the NIC and MGMNT FIFOs to empty. */ |
3825 | ql_wait_fifo_empty(qdev); | 3829 | ql_wait_fifo_empty(qdev); |
3830 | } else | ||
3831 | clear_bit(QL_ASIC_RECOVERY, &qdev->flags); | ||
3826 | 3832 | ||
3827 | ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR); | 3833 | ql_write32(qdev, RST_FO, (RST_FO_FR << 16) | RST_FO_FR); |
3828 | 3834 | ||
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c index 200a363c3bf5..0ffec4608441 100644 --- a/drivers/net/r6040.c +++ b/drivers/net/r6040.c | |||
@@ -677,9 +677,11 @@ static irqreturn_t r6040_interrupt(int irq, void *dev_id) | |||
677 | if (status & RX_FIFO_FULL) | 677 | if (status & RX_FIFO_FULL) |
678 | dev->stats.rx_fifo_errors++; | 678 | dev->stats.rx_fifo_errors++; |
679 | 679 | ||
680 | /* Mask off RX interrupt */ | 680 | if (likely(napi_schedule_prep(&lp->napi))) { |
681 | misr &= ~RX_INTS; | 681 | /* Mask off RX interrupt */ |
682 | napi_schedule(&lp->napi); | 682 | misr &= ~RX_INTS; |
683 | __napi_schedule(&lp->napi); | ||
684 | } | ||
683 | } | 685 | } |
684 | 686 | ||
685 | /* TX interrupt request */ | 687 | /* TX interrupt request */ |
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index 8a72a979ee71..1f3f7b4dd638 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c | |||
@@ -140,6 +140,8 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = { | |||
140 | .tpauser = 1, | 140 | .tpauser = 1, |
141 | .hw_swap = 1, | 141 | .hw_swap = 1, |
142 | .no_ade = 1, | 142 | .no_ade = 1, |
143 | .rpadir = 1, | ||
144 | .rpadir_value = 2 << 16, | ||
143 | }; | 145 | }; |
144 | 146 | ||
145 | #define SH_GIGA_ETH_BASE 0xfee00000 | 147 | #define SH_GIGA_ETH_BASE 0xfee00000 |
@@ -1184,8 +1186,8 @@ static void sh_eth_adjust_link(struct net_device *ndev) | |||
1184 | mdp->cd->set_rate(ndev); | 1186 | mdp->cd->set_rate(ndev); |
1185 | } | 1187 | } |
1186 | if (mdp->link == PHY_DOWN) { | 1188 | if (mdp->link == PHY_DOWN) { |
1187 | sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_TXF) | 1189 | sh_eth_write(ndev, |
1188 | | ECMR_DM, ECMR); | 1190 | (sh_eth_read(ndev, ECMR) & ~ECMR_TXF), ECMR); |
1189 | new_state = 1; | 1191 | new_state = 1; |
1190 | mdp->link = phydev->link; | 1192 | mdp->link = phydev->link; |
1191 | } | 1193 | } |
diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 8ec1a9a0bb9a..2f110fb30daa 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c | |||
@@ -182,11 +182,11 @@ static int sl_alloc_bufs(struct slip *sl, int mtu) | |||
182 | #ifdef SL_INCLUDE_CSLIP | 182 | #ifdef SL_INCLUDE_CSLIP |
183 | cbuff = xchg(&sl->cbuff, cbuff); | 183 | cbuff = xchg(&sl->cbuff, cbuff); |
184 | slcomp = xchg(&sl->slcomp, slcomp); | 184 | slcomp = xchg(&sl->slcomp, slcomp); |
185 | #endif | ||
185 | #ifdef CONFIG_SLIP_MODE_SLIP6 | 186 | #ifdef CONFIG_SLIP_MODE_SLIP6 |
186 | sl->xdata = 0; | 187 | sl->xdata = 0; |
187 | sl->xbits = 0; | 188 | sl->xbits = 0; |
188 | #endif | 189 | #endif |
189 | #endif | ||
190 | spin_unlock_bh(&sl->lock); | 190 | spin_unlock_bh(&sl->lock); |
191 | err = 0; | 191 | err = 0; |
192 | 192 | ||
diff --git a/drivers/net/tulip/dmfe.c b/drivers/net/tulip/dmfe.c index 468512731966..9a21ca3873fc 100644 --- a/drivers/net/tulip/dmfe.c +++ b/drivers/net/tulip/dmfe.c | |||
@@ -879,7 +879,6 @@ static void dmfe_free_tx_pkt(struct DEVICE *dev, struct dmfe_board_info * db) | |||
879 | txptr = db->tx_remove_ptr; | 879 | txptr = db->tx_remove_ptr; |
880 | while(db->tx_packet_cnt) { | 880 | while(db->tx_packet_cnt) { |
881 | tdes0 = le32_to_cpu(txptr->tdes0); | 881 | tdes0 = le32_to_cpu(txptr->tdes0); |
882 | pr_debug("tdes0=%x\n", tdes0); | ||
883 | if (tdes0 & 0x80000000) | 882 | if (tdes0 & 0x80000000) |
884 | break; | 883 | break; |
885 | 884 | ||
@@ -889,7 +888,6 @@ static void dmfe_free_tx_pkt(struct DEVICE *dev, struct dmfe_board_info * db) | |||
889 | 888 | ||
890 | /* Transmit statistic counter */ | 889 | /* Transmit statistic counter */ |
891 | if ( tdes0 != 0x7fffffff ) { | 890 | if ( tdes0 != 0x7fffffff ) { |
892 | pr_debug("tdes0=%x\n", tdes0); | ||
893 | dev->stats.collisions += (tdes0 >> 3) & 0xf; | 891 | dev->stats.collisions += (tdes0 >> 3) & 0xf; |
894 | dev->stats.tx_bytes += le32_to_cpu(txptr->tdes1) & 0x7ff; | 892 | dev->stats.tx_bytes += le32_to_cpu(txptr->tdes1) & 0x7ff; |
895 | if (tdes0 & TDES0_ERR_MASK) { | 893 | if (tdes0 & TDES0_ERR_MASK) { |
@@ -986,7 +984,6 @@ static void dmfe_rx_packet(struct DEVICE *dev, struct dmfe_board_info * db) | |||
986 | /* error summary bit check */ | 984 | /* error summary bit check */ |
987 | if (rdes0 & 0x8000) { | 985 | if (rdes0 & 0x8000) { |
988 | /* This is a error packet */ | 986 | /* This is a error packet */ |
989 | pr_debug("rdes0: %x\n", rdes0); | ||
990 | dev->stats.rx_errors++; | 987 | dev->stats.rx_errors++; |
991 | if (rdes0 & 1) | 988 | if (rdes0 & 1) |
992 | dev->stats.rx_fifo_errors++; | 989 | dev->stats.rx_fifo_errors++; |
@@ -1638,7 +1635,6 @@ static u8 dmfe_sense_speed(struct dmfe_board_info * db) | |||
1638 | else /* DM9102/DM9102A */ | 1635 | else /* DM9102/DM9102A */ |
1639 | phy_mode = phy_read(db->ioaddr, | 1636 | phy_mode = phy_read(db->ioaddr, |
1640 | db->phy_addr, 17, db->chip_id) & 0xf000; | 1637 | db->phy_addr, 17, db->chip_id) & 0xf000; |
1641 | pr_debug("Phy_mode %x\n", phy_mode); | ||
1642 | switch (phy_mode) { | 1638 | switch (phy_mode) { |
1643 | case 0x1000: db->op_mode = DMFE_10MHF; break; | 1639 | case 0x1000: db->op_mode = DMFE_10MHF; break; |
1644 | case 0x2000: db->op_mode = DMFE_10MFD; break; | 1640 | case 0x2000: db->op_mode = DMFE_10MFD; break; |
diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c index 387ca43f26f4..304fe78ff60e 100644 --- a/drivers/net/usb/hso.c +++ b/drivers/net/usb/hso.c | |||
@@ -2421,10 +2421,8 @@ static void hso_free_net_device(struct hso_device *hso_dev) | |||
2421 | 2421 | ||
2422 | remove_net_device(hso_net->parent); | 2422 | remove_net_device(hso_net->parent); |
2423 | 2423 | ||
2424 | if (hso_net->net) { | 2424 | if (hso_net->net) |
2425 | unregister_netdev(hso_net->net); | 2425 | unregister_netdev(hso_net->net); |
2426 | free_netdev(hso_net->net); | ||
2427 | } | ||
2428 | 2426 | ||
2429 | /* start freeing */ | 2427 | /* start freeing */ |
2430 | for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { | 2428 | for (i = 0; i < MUX_BULK_RX_BUF_COUNT; i++) { |
@@ -2436,6 +2434,9 @@ static void hso_free_net_device(struct hso_device *hso_dev) | |||
2436 | kfree(hso_net->mux_bulk_tx_buf); | 2434 | kfree(hso_net->mux_bulk_tx_buf); |
2437 | hso_net->mux_bulk_tx_buf = NULL; | 2435 | hso_net->mux_bulk_tx_buf = NULL; |
2438 | 2436 | ||
2437 | if (hso_net->net) | ||
2438 | free_netdev(hso_net->net); | ||
2439 | |||
2439 | kfree(hso_dev); | 2440 | kfree(hso_dev); |
2440 | } | 2441 | } |
2441 | 2442 | ||
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index fa6e2ac7475a..67402350d0df 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c | |||
@@ -575,7 +575,7 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx, | |||
575 | struct vmxnet3_cmd_ring *ring = &rq->rx_ring[ring_idx]; | 575 | struct vmxnet3_cmd_ring *ring = &rq->rx_ring[ring_idx]; |
576 | u32 val; | 576 | u32 val; |
577 | 577 | ||
578 | while (num_allocated < num_to_alloc) { | 578 | while (num_allocated <= num_to_alloc) { |
579 | struct vmxnet3_rx_buf_info *rbi; | 579 | struct vmxnet3_rx_buf_info *rbi; |
580 | union Vmxnet3_GenericDesc *gd; | 580 | union Vmxnet3_GenericDesc *gd; |
581 | 581 | ||
@@ -621,9 +621,15 @@ vmxnet3_rq_alloc_rx_buf(struct vmxnet3_rx_queue *rq, u32 ring_idx, | |||
621 | 621 | ||
622 | BUG_ON(rbi->dma_addr == 0); | 622 | BUG_ON(rbi->dma_addr == 0); |
623 | gd->rxd.addr = cpu_to_le64(rbi->dma_addr); | 623 | gd->rxd.addr = cpu_to_le64(rbi->dma_addr); |
624 | gd->dword[2] = cpu_to_le32((ring->gen << VMXNET3_RXD_GEN_SHIFT) | 624 | gd->dword[2] = cpu_to_le32((!ring->gen << VMXNET3_RXD_GEN_SHIFT) |
625 | | val | rbi->len); | 625 | | val | rbi->len); |
626 | 626 | ||
627 | /* Fill the last buffer but dont mark it ready, or else the | ||
628 | * device will think that the queue is full */ | ||
629 | if (num_allocated == num_to_alloc) | ||
630 | break; | ||
631 | |||
632 | gd->dword[2] |= cpu_to_le32(ring->gen << VMXNET3_RXD_GEN_SHIFT); | ||
627 | num_allocated++; | 633 | num_allocated++; |
628 | vmxnet3_cmd_ring_adv_next2fill(ring); | 634 | vmxnet3_cmd_ring_adv_next2fill(ring); |
629 | } | 635 | } |
@@ -1140,6 +1146,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, | |||
1140 | VMXNET3_REG_RXPROD, VMXNET3_REG_RXPROD2 | 1146 | VMXNET3_REG_RXPROD, VMXNET3_REG_RXPROD2 |
1141 | }; | 1147 | }; |
1142 | u32 num_rxd = 0; | 1148 | u32 num_rxd = 0; |
1149 | bool skip_page_frags = false; | ||
1143 | struct Vmxnet3_RxCompDesc *rcd; | 1150 | struct Vmxnet3_RxCompDesc *rcd; |
1144 | struct vmxnet3_rx_ctx *ctx = &rq->rx_ctx; | 1151 | struct vmxnet3_rx_ctx *ctx = &rq->rx_ctx; |
1145 | #ifdef __BIG_ENDIAN_BITFIELD | 1152 | #ifdef __BIG_ENDIAN_BITFIELD |
@@ -1150,11 +1157,12 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, | |||
1150 | &rxComp); | 1157 | &rxComp); |
1151 | while (rcd->gen == rq->comp_ring.gen) { | 1158 | while (rcd->gen == rq->comp_ring.gen) { |
1152 | struct vmxnet3_rx_buf_info *rbi; | 1159 | struct vmxnet3_rx_buf_info *rbi; |
1153 | struct sk_buff *skb; | 1160 | struct sk_buff *skb, *new_skb = NULL; |
1161 | struct page *new_page = NULL; | ||
1154 | int num_to_alloc; | 1162 | int num_to_alloc; |
1155 | struct Vmxnet3_RxDesc *rxd; | 1163 | struct Vmxnet3_RxDesc *rxd; |
1156 | u32 idx, ring_idx; | 1164 | u32 idx, ring_idx; |
1157 | 1165 | struct vmxnet3_cmd_ring *ring = NULL; | |
1158 | if (num_rxd >= quota) { | 1166 | if (num_rxd >= quota) { |
1159 | /* we may stop even before we see the EOP desc of | 1167 | /* we may stop even before we see the EOP desc of |
1160 | * the current pkt | 1168 | * the current pkt |
@@ -1165,6 +1173,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, | |||
1165 | BUG_ON(rcd->rqID != rq->qid && rcd->rqID != rq->qid2); | 1173 | BUG_ON(rcd->rqID != rq->qid && rcd->rqID != rq->qid2); |
1166 | idx = rcd->rxdIdx; | 1174 | idx = rcd->rxdIdx; |
1167 | ring_idx = rcd->rqID < adapter->num_rx_queues ? 0 : 1; | 1175 | ring_idx = rcd->rqID < adapter->num_rx_queues ? 0 : 1; |
1176 | ring = rq->rx_ring + ring_idx; | ||
1168 | vmxnet3_getRxDesc(rxd, &rq->rx_ring[ring_idx].base[idx].rxd, | 1177 | vmxnet3_getRxDesc(rxd, &rq->rx_ring[ring_idx].base[idx].rxd, |
1169 | &rxCmdDesc); | 1178 | &rxCmdDesc); |
1170 | rbi = rq->buf_info[ring_idx] + idx; | 1179 | rbi = rq->buf_info[ring_idx] + idx; |
@@ -1193,37 +1202,80 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, | |||
1193 | goto rcd_done; | 1202 | goto rcd_done; |
1194 | } | 1203 | } |
1195 | 1204 | ||
1205 | skip_page_frags = false; | ||
1196 | ctx->skb = rbi->skb; | 1206 | ctx->skb = rbi->skb; |
1197 | rbi->skb = NULL; | 1207 | new_skb = dev_alloc_skb(rbi->len + NET_IP_ALIGN); |
1208 | if (new_skb == NULL) { | ||
1209 | /* Skb allocation failed, do not handover this | ||
1210 | * skb to stack. Reuse it. Drop the existing pkt | ||
1211 | */ | ||
1212 | rq->stats.rx_buf_alloc_failure++; | ||
1213 | ctx->skb = NULL; | ||
1214 | rq->stats.drop_total++; | ||
1215 | skip_page_frags = true; | ||
1216 | goto rcd_done; | ||
1217 | } | ||
1198 | 1218 | ||
1199 | pci_unmap_single(adapter->pdev, rbi->dma_addr, rbi->len, | 1219 | pci_unmap_single(adapter->pdev, rbi->dma_addr, rbi->len, |
1200 | PCI_DMA_FROMDEVICE); | 1220 | PCI_DMA_FROMDEVICE); |
1201 | 1221 | ||
1202 | skb_put(ctx->skb, rcd->len); | 1222 | skb_put(ctx->skb, rcd->len); |
1223 | |||
1224 | /* Immediate refill */ | ||
1225 | new_skb->dev = adapter->netdev; | ||
1226 | skb_reserve(new_skb, NET_IP_ALIGN); | ||
1227 | rbi->skb = new_skb; | ||
1228 | rbi->dma_addr = pci_map_single(adapter->pdev, | ||
1229 | rbi->skb->data, rbi->len, | ||
1230 | PCI_DMA_FROMDEVICE); | ||
1231 | rxd->addr = cpu_to_le64(rbi->dma_addr); | ||
1232 | rxd->len = rbi->len; | ||
1233 | |||
1203 | } else { | 1234 | } else { |
1204 | BUG_ON(ctx->skb == NULL); | 1235 | BUG_ON(ctx->skb == NULL && !skip_page_frags); |
1236 | |||
1205 | /* non SOP buffer must be type 1 in most cases */ | 1237 | /* non SOP buffer must be type 1 in most cases */ |
1206 | if (rbi->buf_type == VMXNET3_RX_BUF_PAGE) { | 1238 | BUG_ON(rbi->buf_type != VMXNET3_RX_BUF_PAGE); |
1207 | BUG_ON(rxd->btype != VMXNET3_RXD_BTYPE_BODY); | 1239 | BUG_ON(rxd->btype != VMXNET3_RXD_BTYPE_BODY); |
1208 | 1240 | ||
1209 | if (rcd->len) { | 1241 | /* If an sop buffer was dropped, skip all |
1210 | pci_unmap_page(adapter->pdev, | 1242 | * following non-sop fragments. They will be reused. |
1211 | rbi->dma_addr, rbi->len, | 1243 | */ |
1212 | PCI_DMA_FROMDEVICE); | 1244 | if (skip_page_frags) |
1245 | goto rcd_done; | ||
1213 | 1246 | ||
1214 | vmxnet3_append_frag(ctx->skb, rcd, rbi); | 1247 | new_page = alloc_page(GFP_ATOMIC); |
1215 | rbi->page = NULL; | 1248 | if (unlikely(new_page == NULL)) { |
1216 | } | 1249 | /* Replacement page frag could not be allocated. |
1217 | } else { | 1250 | * Reuse this page. Drop the pkt and free the |
1218 | /* | 1251 | * skb which contained this page as a frag. Skip |
1219 | * The only time a non-SOP buffer is type 0 is | 1252 | * processing all the following non-sop frags. |
1220 | * when it's EOP and error flag is raised, which | ||
1221 | * has already been handled. | ||
1222 | */ | 1253 | */ |
1223 | BUG_ON(true); | 1254 | rq->stats.rx_buf_alloc_failure++; |
1255 | dev_kfree_skb(ctx->skb); | ||
1256 | ctx->skb = NULL; | ||
1257 | skip_page_frags = true; | ||
1258 | goto rcd_done; | ||
1259 | } | ||
1260 | |||
1261 | if (rcd->len) { | ||
1262 | pci_unmap_page(adapter->pdev, | ||
1263 | rbi->dma_addr, rbi->len, | ||
1264 | PCI_DMA_FROMDEVICE); | ||
1265 | |||
1266 | vmxnet3_append_frag(ctx->skb, rcd, rbi); | ||
1224 | } | 1267 | } |
1268 | |||
1269 | /* Immediate refill */ | ||
1270 | rbi->page = new_page; | ||
1271 | rbi->dma_addr = pci_map_page(adapter->pdev, rbi->page, | ||
1272 | 0, PAGE_SIZE, | ||
1273 | PCI_DMA_FROMDEVICE); | ||
1274 | rxd->addr = cpu_to_le64(rbi->dma_addr); | ||
1275 | rxd->len = rbi->len; | ||
1225 | } | 1276 | } |
1226 | 1277 | ||
1278 | |||
1227 | skb = ctx->skb; | 1279 | skb = ctx->skb; |
1228 | if (rcd->eop) { | 1280 | if (rcd->eop) { |
1229 | skb->len += skb->data_len; | 1281 | skb->len += skb->data_len; |
@@ -1244,26 +1296,27 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq, | |||
1244 | } | 1296 | } |
1245 | 1297 | ||
1246 | rcd_done: | 1298 | rcd_done: |
1247 | /* device may skip some rx descs */ | 1299 | /* device may have skipped some rx descs */ |
1248 | rq->rx_ring[ring_idx].next2comp = idx; | 1300 | ring->next2comp = idx; |
1249 | VMXNET3_INC_RING_IDX_ONLY(rq->rx_ring[ring_idx].next2comp, | 1301 | num_to_alloc = vmxnet3_cmd_ring_desc_avail(ring); |
1250 | rq->rx_ring[ring_idx].size); | 1302 | ring = rq->rx_ring + ring_idx; |
1251 | 1303 | while (num_to_alloc) { | |
1252 | /* refill rx buffers frequently to avoid starving the h/w */ | 1304 | vmxnet3_getRxDesc(rxd, &ring->base[ring->next2fill].rxd, |
1253 | num_to_alloc = vmxnet3_cmd_ring_desc_avail(rq->rx_ring + | 1305 | &rxCmdDesc); |
1254 | ring_idx); | 1306 | BUG_ON(!rxd->addr); |
1255 | if (unlikely(num_to_alloc > VMXNET3_RX_ALLOC_THRESHOLD(rq, | 1307 | |
1256 | ring_idx, adapter))) { | 1308 | /* Recv desc is ready to be used by the device */ |
1257 | vmxnet3_rq_alloc_rx_buf(rq, ring_idx, num_to_alloc, | 1309 | rxd->gen = ring->gen; |
1258 | adapter); | 1310 | vmxnet3_cmd_ring_adv_next2fill(ring); |
1259 | 1311 | num_to_alloc--; | |
1260 | /* if needed, update the register */ | 1312 | } |
1261 | if (unlikely(rq->shared->updateRxProd)) { | 1313 | |
1262 | VMXNET3_WRITE_BAR0_REG(adapter, | 1314 | /* if needed, update the register */ |
1263 | rxprod_reg[ring_idx] + rq->qid * 8, | 1315 | if (unlikely(rq->shared->updateRxProd)) { |
1264 | rq->rx_ring[ring_idx].next2fill); | 1316 | VMXNET3_WRITE_BAR0_REG(adapter, |
1265 | rq->uncommitted[ring_idx] = 0; | 1317 | rxprod_reg[ring_idx] + rq->qid * 8, |
1266 | } | 1318 | ring->next2fill); |
1319 | rq->uncommitted[ring_idx] = 0; | ||
1267 | } | 1320 | } |
1268 | 1321 | ||
1269 | vmxnet3_comp_ring_adv_next2proc(&rq->comp_ring); | 1322 | vmxnet3_comp_ring_adv_next2proc(&rq->comp_ring); |
@@ -2894,6 +2947,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, | |||
2894 | else | 2947 | else |
2895 | #endif | 2948 | #endif |
2896 | num_rx_queues = 1; | 2949 | num_rx_queues = 1; |
2950 | num_rx_queues = rounddown_pow_of_two(num_rx_queues); | ||
2897 | 2951 | ||
2898 | if (enable_mq) | 2952 | if (enable_mq) |
2899 | num_tx_queues = min(VMXNET3_DEVICE_MAX_TX_QUEUES, | 2953 | num_tx_queues = min(VMXNET3_DEVICE_MAX_TX_QUEUES, |
@@ -2901,6 +2955,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, | |||
2901 | else | 2955 | else |
2902 | num_tx_queues = 1; | 2956 | num_tx_queues = 1; |
2903 | 2957 | ||
2958 | num_tx_queues = rounddown_pow_of_two(num_tx_queues); | ||
2904 | netdev = alloc_etherdev_mq(sizeof(struct vmxnet3_adapter), | 2959 | netdev = alloc_etherdev_mq(sizeof(struct vmxnet3_adapter), |
2905 | max(num_tx_queues, num_rx_queues)); | 2960 | max(num_tx_queues, num_rx_queues)); |
2906 | printk(KERN_INFO "# of Tx queues : %d, # of Rx queues : %d\n", | 2961 | printk(KERN_INFO "# of Tx queues : %d, # of Rx queues : %d\n", |
@@ -3085,6 +3140,7 @@ vmxnet3_remove_device(struct pci_dev *pdev) | |||
3085 | else | 3140 | else |
3086 | #endif | 3141 | #endif |
3087 | num_rx_queues = 1; | 3142 | num_rx_queues = 1; |
3143 | num_rx_queues = rounddown_pow_of_two(num_rx_queues); | ||
3088 | 3144 | ||
3089 | cancel_work_sync(&adapter->work); | 3145 | cancel_work_sync(&adapter->work); |
3090 | 3146 | ||
diff --git a/drivers/net/vmxnet3/vmxnet3_int.h b/drivers/net/vmxnet3/vmxnet3_int.h index f50d36fdf405..e08d75e3f170 100644 --- a/drivers/net/vmxnet3/vmxnet3_int.h +++ b/drivers/net/vmxnet3/vmxnet3_int.h | |||
@@ -55,6 +55,7 @@ | |||
55 | #include <linux/if_vlan.h> | 55 | #include <linux/if_vlan.h> |
56 | #include <linux/if_arp.h> | 56 | #include <linux/if_arp.h> |
57 | #include <linux/inetdevice.h> | 57 | #include <linux/inetdevice.h> |
58 | #include <linux/log2.h> | ||
58 | 59 | ||
59 | #include "vmxnet3_defs.h" | 60 | #include "vmxnet3_defs.h" |
60 | 61 | ||
@@ -68,10 +69,10 @@ | |||
68 | /* | 69 | /* |
69 | * Version numbers | 70 | * Version numbers |
70 | */ | 71 | */ |
71 | #define VMXNET3_DRIVER_VERSION_STRING "1.1.9.0-k" | 72 | #define VMXNET3_DRIVER_VERSION_STRING "1.1.18.0-k" |
72 | 73 | ||
73 | /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ | 74 | /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */ |
74 | #define VMXNET3_DRIVER_VERSION_NUM 0x01010900 | 75 | #define VMXNET3_DRIVER_VERSION_NUM 0x01011200 |
75 | 76 | ||
76 | #if defined(CONFIG_PCI_MSI) | 77 | #if defined(CONFIG_PCI_MSI) |
77 | /* RSS only makes sense if MSI-X is supported. */ | 78 | /* RSS only makes sense if MSI-X is supported. */ |
diff --git a/drivers/net/wireless/ath/ath5k/desc.c b/drivers/net/wireless/ath/ath5k/desc.c index 62172d585723..f82383b3ed30 100644 --- a/drivers/net/wireless/ath/ath5k/desc.c +++ b/drivers/net/wireless/ath/ath5k/desc.c | |||
@@ -107,10 +107,13 @@ ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, | |||
107 | case AR5K_PKT_TYPE_BEACON: | 107 | case AR5K_PKT_TYPE_BEACON: |
108 | case AR5K_PKT_TYPE_PROBE_RESP: | 108 | case AR5K_PKT_TYPE_PROBE_RESP: |
109 | frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY; | 109 | frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY; |
110 | break; | ||
110 | case AR5K_PKT_TYPE_PIFS: | 111 | case AR5K_PKT_TYPE_PIFS: |
111 | frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS; | 112 | frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS; |
113 | break; | ||
112 | default: | 114 | default: |
113 | frame_type = type; | 115 | frame_type = type; |
116 | break; | ||
114 | } | 117 | } |
115 | 118 | ||
116 | tx_ctl->tx_control_0 |= | 119 | tx_ctl->tx_control_0 |= |
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c index 1fef84f87c78..392771f93759 100644 --- a/drivers/net/wireless/ath/ath5k/eeprom.c +++ b/drivers/net/wireless/ath/ath5k/eeprom.c | |||
@@ -691,14 +691,12 @@ ath5k_eeprom_free_pcal_info(struct ath5k_hw *ah, int mode) | |||
691 | if (!chinfo[pier].pd_curves) | 691 | if (!chinfo[pier].pd_curves) |
692 | continue; | 692 | continue; |
693 | 693 | ||
694 | for (pdg = 0; pdg < ee->ee_pd_gains[mode]; pdg++) { | 694 | for (pdg = 0; pdg < AR5K_EEPROM_N_PD_CURVES; pdg++) { |
695 | struct ath5k_pdgain_info *pd = | 695 | struct ath5k_pdgain_info *pd = |
696 | &chinfo[pier].pd_curves[pdg]; | 696 | &chinfo[pier].pd_curves[pdg]; |
697 | 697 | ||
698 | if (pd != NULL) { | 698 | kfree(pd->pd_step); |
699 | kfree(pd->pd_step); | 699 | kfree(pd->pd_pwr); |
700 | kfree(pd->pd_pwr); | ||
701 | } | ||
702 | } | 700 | } |
703 | 701 | ||
704 | kfree(chinfo[pier].pd_curves); | 702 | kfree(chinfo[pier].pd_curves); |
diff --git a/drivers/net/wireless/ath/ath5k/pci.c b/drivers/net/wireless/ath/ath5k/pci.c index 296c316a8341..f2c0c236392f 100644 --- a/drivers/net/wireless/ath/ath5k/pci.c +++ b/drivers/net/wireless/ath/ath5k/pci.c | |||
@@ -297,7 +297,9 @@ ath5k_pci_remove(struct pci_dev *pdev) | |||
297 | #ifdef CONFIG_PM_SLEEP | 297 | #ifdef CONFIG_PM_SLEEP |
298 | static int ath5k_pci_suspend(struct device *dev) | 298 | static int ath5k_pci_suspend(struct device *dev) |
299 | { | 299 | { |
300 | struct ath5k_softc *sc = pci_get_drvdata(to_pci_dev(dev)); | 300 | struct pci_dev *pdev = to_pci_dev(dev); |
301 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | ||
302 | struct ath5k_softc *sc = hw->priv; | ||
301 | 303 | ||
302 | ath5k_led_off(sc); | 304 | ath5k_led_off(sc); |
303 | return 0; | 305 | return 0; |
@@ -306,7 +308,8 @@ static int ath5k_pci_suspend(struct device *dev) | |||
306 | static int ath5k_pci_resume(struct device *dev) | 308 | static int ath5k_pci_resume(struct device *dev) |
307 | { | 309 | { |
308 | struct pci_dev *pdev = to_pci_dev(dev); | 310 | struct pci_dev *pdev = to_pci_dev(dev); |
309 | struct ath5k_softc *sc = pci_get_drvdata(pdev); | 311 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); |
312 | struct ath5k_softc *sc = hw->priv; | ||
310 | 313 | ||
311 | /* | 314 | /* |
312 | * Suspend/Resume resets the PCI configuration space, so we have to | 315 | * Suspend/Resume resets the PCI configuration space, so we have to |
diff --git a/drivers/net/wireless/ath/ath5k/sysfs.c b/drivers/net/wireless/ath/ath5k/sysfs.c index 929c68cdf8ab..a073cdce1f15 100644 --- a/drivers/net/wireless/ath/ath5k/sysfs.c +++ b/drivers/net/wireless/ath/ath5k/sysfs.c | |||
@@ -10,7 +10,8 @@ static ssize_t ath5k_attr_show_##name(struct device *dev, \ | |||
10 | struct device_attribute *attr, \ | 10 | struct device_attribute *attr, \ |
11 | char *buf) \ | 11 | char *buf) \ |
12 | { \ | 12 | { \ |
13 | struct ath5k_softc *sc = dev_get_drvdata(dev); \ | 13 | struct ieee80211_hw *hw = dev_get_drvdata(dev); \ |
14 | struct ath5k_softc *sc = hw->priv; \ | ||
14 | return snprintf(buf, PAGE_SIZE, "%d\n", get); \ | 15 | return snprintf(buf, PAGE_SIZE, "%d\n", get); \ |
15 | } \ | 16 | } \ |
16 | \ | 17 | \ |
@@ -18,7 +19,8 @@ static ssize_t ath5k_attr_store_##name(struct device *dev, \ | |||
18 | struct device_attribute *attr, \ | 19 | struct device_attribute *attr, \ |
19 | const char *buf, size_t count) \ | 20 | const char *buf, size_t count) \ |
20 | { \ | 21 | { \ |
21 | struct ath5k_softc *sc = dev_get_drvdata(dev); \ | 22 | struct ieee80211_hw *hw = dev_get_drvdata(dev); \ |
23 | struct ath5k_softc *sc = hw->priv; \ | ||
22 | int val; \ | 24 | int val; \ |
23 | \ | 25 | \ |
24 | val = (int)simple_strtoul(buf, NULL, 10); \ | 26 | val = (int)simple_strtoul(buf, NULL, 10); \ |
@@ -33,7 +35,8 @@ static ssize_t ath5k_attr_show_##name(struct device *dev, \ | |||
33 | struct device_attribute *attr, \ | 35 | struct device_attribute *attr, \ |
34 | char *buf) \ | 36 | char *buf) \ |
35 | { \ | 37 | { \ |
36 | struct ath5k_softc *sc = dev_get_drvdata(dev); \ | 38 | struct ieee80211_hw *hw = dev_get_drvdata(dev); \ |
39 | struct ath5k_softc *sc = hw->priv; \ | ||
37 | return snprintf(buf, PAGE_SIZE, "%d\n", get); \ | 40 | return snprintf(buf, PAGE_SIZE, "%d\n", get); \ |
38 | } \ | 41 | } \ |
39 | static DEVICE_ATTR(name, S_IRUGO, ath5k_attr_show_##name, NULL) | 42 | static DEVICE_ATTR(name, S_IRUGO, ath5k_attr_show_##name, NULL) |
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index b8cbfc707213..3bad0b2cf9a3 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -278,6 +278,12 @@ static int ath_pci_suspend(struct device *device) | |||
278 | 278 | ||
279 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); | 279 | ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1); |
280 | 280 | ||
281 | /* The device has to be moved to FULLSLEEP forcibly. | ||
282 | * Otherwise the chip never moved to full sleep, | ||
283 | * when no interface is up. | ||
284 | */ | ||
285 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); | ||
286 | |||
281 | return 0; | 287 | return 0; |
282 | } | 288 | } |
283 | 289 | ||
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 3779b8977d47..33443bcaa8d9 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -671,7 +671,8 @@ static int ath_compute_num_delims(struct ath_softc *sc, struct ath_atx_tid *tid, | |||
671 | * TODO - this could be improved to be dependent on the rate. | 671 | * TODO - this could be improved to be dependent on the rate. |
672 | * The hardware can keep up at lower rates, but not higher rates | 672 | * The hardware can keep up at lower rates, but not higher rates |
673 | */ | 673 | */ |
674 | if (fi->keyix != ATH9K_TXKEYIX_INVALID) | 674 | if ((fi->keyix != ATH9K_TXKEYIX_INVALID) && |
675 | !(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)) | ||
675 | ndelim += ATH_AGGR_ENCRYPTDELIM; | 676 | ndelim += ATH_AGGR_ENCRYPTDELIM; |
676 | 677 | ||
677 | /* | 678 | /* |
diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index 2fb53d067512..333b69ef2ae2 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c | |||
@@ -112,6 +112,8 @@ static struct usb_device_id carl9170_usb_ids[] = { | |||
112 | { USB_DEVICE(0x04bb, 0x093f) }, | 112 | { USB_DEVICE(0x04bb, 0x093f) }, |
113 | /* NEC WL300NU-G */ | 113 | /* NEC WL300NU-G */ |
114 | { USB_DEVICE(0x0409, 0x0249) }, | 114 | { USB_DEVICE(0x0409, 0x0249) }, |
115 | /* NEC WL300NU-AG */ | ||
116 | { USB_DEVICE(0x0409, 0x02b4) }, | ||
115 | /* AVM FRITZ!WLAN USB Stick N */ | 117 | /* AVM FRITZ!WLAN USB Stick N */ |
116 | { USB_DEVICE(0x057c, 0x8401) }, | 118 | { USB_DEVICE(0x057c, 0x8401) }, |
117 | /* AVM FRITZ!WLAN USB Stick N 2.4 */ | 119 | /* AVM FRITZ!WLAN USB Stick N 2.4 */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index 61d4a11f566b..2a88e73bb39c 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <net/mac80211.h> | 36 | #include <net/mac80211.h> |
37 | #include <linux/etherdevice.h> | 37 | #include <linux/etherdevice.h> |
38 | #include <asm/unaligned.h> | 38 | #include <asm/unaligned.h> |
39 | #include <linux/stringify.h> | ||
39 | 40 | ||
40 | #include "iwl-eeprom.h" | 41 | #include "iwl-eeprom.h" |
41 | #include "iwl-dev.h" | 42 | #include "iwl-dev.h" |
@@ -55,10 +56,10 @@ | |||
55 | #define IWL100_UCODE_API_MIN 5 | 56 | #define IWL100_UCODE_API_MIN 5 |
56 | 57 | ||
57 | #define IWL1000_FW_PRE "iwlwifi-1000-" | 58 | #define IWL1000_FW_PRE "iwlwifi-1000-" |
58 | #define IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE #api ".ucode" | 59 | #define IWL1000_MODULE_FIRMWARE(api) IWL1000_FW_PRE __stringify(api) ".ucode" |
59 | 60 | ||
60 | #define IWL100_FW_PRE "iwlwifi-100-" | 61 | #define IWL100_FW_PRE "iwlwifi-100-" |
61 | #define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE #api ".ucode" | 62 | #define IWL100_MODULE_FIRMWARE(api) IWL100_FW_PRE __stringify(api) ".ucode" |
62 | 63 | ||
63 | 64 | ||
64 | /* | 65 | /* |
diff --git a/drivers/net/wireless/iwlwifi/iwl-2000.c b/drivers/net/wireless/iwlwifi/iwl-2000.c index 2282279cffc4..3df76f53a41b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-2000.c +++ b/drivers/net/wireless/iwlwifi/iwl-2000.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <net/mac80211.h> | 36 | #include <net/mac80211.h> |
37 | #include <linux/etherdevice.h> | 37 | #include <linux/etherdevice.h> |
38 | #include <asm/unaligned.h> | 38 | #include <asm/unaligned.h> |
39 | #include <linux/stringify.h> | ||
39 | 40 | ||
40 | #include "iwl-eeprom.h" | 41 | #include "iwl-eeprom.h" |
41 | #include "iwl-dev.h" | 42 | #include "iwl-dev.h" |
@@ -58,13 +59,13 @@ | |||
58 | #define IWL105_UCODE_API_MIN 5 | 59 | #define IWL105_UCODE_API_MIN 5 |
59 | 60 | ||
60 | #define IWL2030_FW_PRE "iwlwifi-2030-" | 61 | #define IWL2030_FW_PRE "iwlwifi-2030-" |
61 | #define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE #api ".ucode" | 62 | #define IWL2030_MODULE_FIRMWARE(api) IWL2030_FW_PRE __stringify(api) ".ucode" |
62 | 63 | ||
63 | #define IWL2000_FW_PRE "iwlwifi-2000-" | 64 | #define IWL2000_FW_PRE "iwlwifi-2000-" |
64 | #define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE #api ".ucode" | 65 | #define IWL2000_MODULE_FIRMWARE(api) IWL2000_FW_PRE __stringify(api) ".ucode" |
65 | 66 | ||
66 | #define IWL105_FW_PRE "iwlwifi-105-" | 67 | #define IWL105_FW_PRE "iwlwifi-105-" |
67 | #define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE #api ".ucode" | 68 | #define IWL105_MODULE_FIRMWARE(api) IWL105_FW_PRE __stringify(api) ".ucode" |
68 | 69 | ||
69 | static void iwl2000_set_ct_threshold(struct iwl_priv *priv) | 70 | static void iwl2000_set_ct_threshold(struct iwl_priv *priv) |
70 | { | 71 | { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index f99f9c193352..e816c27db794 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <net/mac80211.h> | 37 | #include <net/mac80211.h> |
38 | #include <linux/etherdevice.h> | 38 | #include <linux/etherdevice.h> |
39 | #include <asm/unaligned.h> | 39 | #include <asm/unaligned.h> |
40 | #include <linux/stringify.h> | ||
40 | 41 | ||
41 | #include "iwl-eeprom.h" | 42 | #include "iwl-eeprom.h" |
42 | #include "iwl-dev.h" | 43 | #include "iwl-dev.h" |
@@ -57,10 +58,10 @@ | |||
57 | #define IWL5150_UCODE_API_MIN 1 | 58 | #define IWL5150_UCODE_API_MIN 1 |
58 | 59 | ||
59 | #define IWL5000_FW_PRE "iwlwifi-5000-" | 60 | #define IWL5000_FW_PRE "iwlwifi-5000-" |
60 | #define IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE #api ".ucode" | 61 | #define IWL5000_MODULE_FIRMWARE(api) IWL5000_FW_PRE __stringify(api) ".ucode" |
61 | 62 | ||
62 | #define IWL5150_FW_PRE "iwlwifi-5150-" | 63 | #define IWL5150_FW_PRE "iwlwifi-5150-" |
63 | #define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE #api ".ucode" | 64 | #define IWL5150_MODULE_FIRMWARE(api) IWL5150_FW_PRE __stringify(api) ".ucode" |
64 | 65 | ||
65 | /* NIC configuration for 5000 series */ | 66 | /* NIC configuration for 5000 series */ |
66 | static void iwl5000_nic_config(struct iwl_priv *priv) | 67 | static void iwl5000_nic_config(struct iwl_priv *priv) |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index fbe565c816e3..5b150bc70b06 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <net/mac80211.h> | 36 | #include <net/mac80211.h> |
37 | #include <linux/etherdevice.h> | 37 | #include <linux/etherdevice.h> |
38 | #include <asm/unaligned.h> | 38 | #include <asm/unaligned.h> |
39 | #include <linux/stringify.h> | ||
39 | 40 | ||
40 | #include "iwl-eeprom.h" | 41 | #include "iwl-eeprom.h" |
41 | #include "iwl-dev.h" | 42 | #include "iwl-dev.h" |
@@ -58,16 +59,16 @@ | |||
58 | #define IWL6000G2_UCODE_API_MIN 4 | 59 | #define IWL6000G2_UCODE_API_MIN 4 |
59 | 60 | ||
60 | #define IWL6000_FW_PRE "iwlwifi-6000-" | 61 | #define IWL6000_FW_PRE "iwlwifi-6000-" |
61 | #define IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE #api ".ucode" | 62 | #define IWL6000_MODULE_FIRMWARE(api) IWL6000_FW_PRE __stringify(api) ".ucode" |
62 | 63 | ||
63 | #define IWL6050_FW_PRE "iwlwifi-6050-" | 64 | #define IWL6050_FW_PRE "iwlwifi-6050-" |
64 | #define IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE #api ".ucode" | 65 | #define IWL6050_MODULE_FIRMWARE(api) IWL6050_FW_PRE __stringify(api) ".ucode" |
65 | 66 | ||
66 | #define IWL6005_FW_PRE "iwlwifi-6000g2a-" | 67 | #define IWL6005_FW_PRE "iwlwifi-6000g2a-" |
67 | #define IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE #api ".ucode" | 68 | #define IWL6005_MODULE_FIRMWARE(api) IWL6005_FW_PRE __stringify(api) ".ucode" |
68 | 69 | ||
69 | #define IWL6030_FW_PRE "iwlwifi-6000g2b-" | 70 | #define IWL6030_FW_PRE "iwlwifi-6000g2b-" |
70 | #define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE #api ".ucode" | 71 | #define IWL6030_MODULE_FIRMWARE(api) IWL6030_FW_PRE __stringify(api) ".ucode" |
71 | 72 | ||
72 | static void iwl6000_set_ct_threshold(struct iwl_priv *priv) | 73 | static void iwl6000_set_ct_threshold(struct iwl_priv *priv) |
73 | { | 74 | { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index 213c80c6a668..45cc51c9c93e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -1763,6 +1763,7 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
1763 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); | 1763 | struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif); |
1764 | struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | 1764 | struct iwl_rxon_context *bss_ctx = &priv->contexts[IWL_RXON_CTX_BSS]; |
1765 | struct iwl_rxon_context *tmp; | 1765 | struct iwl_rxon_context *tmp; |
1766 | enum nl80211_iftype newviftype = newtype; | ||
1766 | u32 interface_modes; | 1767 | u32 interface_modes; |
1767 | int err; | 1768 | int err; |
1768 | 1769 | ||
@@ -1818,7 +1819,7 @@ int iwl_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
1818 | 1819 | ||
1819 | /* success */ | 1820 | /* success */ |
1820 | iwl_teardown_interface(priv, vif, true); | 1821 | iwl_teardown_interface(priv, vif, true); |
1821 | vif->type = newtype; | 1822 | vif->type = newviftype; |
1822 | vif->p2p = newp2p; | 1823 | vif->p2p = newp2p; |
1823 | err = iwl_setup_interface(priv, ctx); | 1824 | err = iwl_setup_interface(priv, ctx); |
1824 | WARN_ON(err); | 1825 | WARN_ON(err); |
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index 686e176b5ebd..137dba95b1ad 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -126,7 +126,7 @@ static inline u8 iwl_tfd_get_num_tbs(struct iwl_tfd *tfd) | |||
126 | } | 126 | } |
127 | 127 | ||
128 | static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta, | 128 | static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta, |
129 | struct iwl_tfd *tfd) | 129 | struct iwl_tfd *tfd, int dma_dir) |
130 | { | 130 | { |
131 | struct pci_dev *dev = priv->pci_dev; | 131 | struct pci_dev *dev = priv->pci_dev; |
132 | int i; | 132 | int i; |
@@ -151,7 +151,7 @@ static void iwlagn_unmap_tfd(struct iwl_priv *priv, struct iwl_cmd_meta *meta, | |||
151 | /* Unmap chunks, if any. */ | 151 | /* Unmap chunks, if any. */ |
152 | for (i = 1; i < num_tbs; i++) | 152 | for (i = 1; i < num_tbs; i++) |
153 | pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i), | 153 | pci_unmap_single(dev, iwl_tfd_tb_get_addr(tfd, i), |
154 | iwl_tfd_tb_get_len(tfd, i), PCI_DMA_TODEVICE); | 154 | iwl_tfd_tb_get_len(tfd, i), dma_dir); |
155 | } | 155 | } |
156 | 156 | ||
157 | /** | 157 | /** |
@@ -167,7 +167,8 @@ void iwlagn_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq) | |||
167 | struct iwl_tfd *tfd_tmp = txq->tfds; | 167 | struct iwl_tfd *tfd_tmp = txq->tfds; |
168 | int index = txq->q.read_ptr; | 168 | int index = txq->q.read_ptr; |
169 | 169 | ||
170 | iwlagn_unmap_tfd(priv, &txq->meta[index], &tfd_tmp[index]); | 170 | iwlagn_unmap_tfd(priv, &txq->meta[index], &tfd_tmp[index], |
171 | PCI_DMA_TODEVICE); | ||
171 | 172 | ||
172 | /* free SKB */ | 173 | /* free SKB */ |
173 | if (txq->txb) { | 174 | if (txq->txb) { |
@@ -310,9 +311,7 @@ void iwl_cmd_queue_unmap(struct iwl_priv *priv) | |||
310 | i = get_cmd_index(q, q->read_ptr); | 311 | i = get_cmd_index(q, q->read_ptr); |
311 | 312 | ||
312 | if (txq->meta[i].flags & CMD_MAPPED) { | 313 | if (txq->meta[i].flags & CMD_MAPPED) { |
313 | pci_unmap_single(priv->pci_dev, | 314 | iwlagn_unmap_tfd(priv, &txq->meta[i], &txq->tfds[i], |
314 | dma_unmap_addr(&txq->meta[i], mapping), | ||
315 | dma_unmap_len(&txq->meta[i], len), | ||
316 | PCI_DMA_BIDIRECTIONAL); | 315 | PCI_DMA_BIDIRECTIONAL); |
317 | txq->meta[i].flags = 0; | 316 | txq->meta[i].flags = 0; |
318 | } | 317 | } |
@@ -535,12 +534,7 @@ out_free_arrays: | |||
535 | void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, | 534 | void iwl_tx_queue_reset(struct iwl_priv *priv, struct iwl_tx_queue *txq, |
536 | int slots_num, u32 txq_id) | 535 | int slots_num, u32 txq_id) |
537 | { | 536 | { |
538 | int actual_slots = slots_num; | 537 | memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * slots_num); |
539 | |||
540 | if (txq_id == priv->cmd_queue) | ||
541 | actual_slots++; | ||
542 | |||
543 | memset(txq->meta, 0, sizeof(struct iwl_cmd_meta) * actual_slots); | ||
544 | 538 | ||
545 | txq->need_update = 0; | 539 | txq->need_update = 0; |
546 | 540 | ||
@@ -700,10 +694,11 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd) | |||
700 | if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) | 694 | if (!(cmd->dataflags[i] & IWL_HCMD_DFL_NOCOPY)) |
701 | continue; | 695 | continue; |
702 | phys_addr = pci_map_single(priv->pci_dev, (void *)cmd->data[i], | 696 | phys_addr = pci_map_single(priv->pci_dev, (void *)cmd->data[i], |
703 | cmd->len[i], PCI_DMA_TODEVICE); | 697 | cmd->len[i], PCI_DMA_BIDIRECTIONAL); |
704 | if (pci_dma_mapping_error(priv->pci_dev, phys_addr)) { | 698 | if (pci_dma_mapping_error(priv->pci_dev, phys_addr)) { |
705 | iwlagn_unmap_tfd(priv, out_meta, | 699 | iwlagn_unmap_tfd(priv, out_meta, |
706 | &txq->tfds[q->write_ptr]); | 700 | &txq->tfds[q->write_ptr], |
701 | PCI_DMA_BIDIRECTIONAL); | ||
707 | idx = -ENOMEM; | 702 | idx = -ENOMEM; |
708 | goto out; | 703 | goto out; |
709 | } | 704 | } |
@@ -807,7 +802,7 @@ void iwl_tx_cmd_complete(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | |||
807 | cmd = txq->cmd[cmd_index]; | 802 | cmd = txq->cmd[cmd_index]; |
808 | meta = &txq->meta[cmd_index]; | 803 | meta = &txq->meta[cmd_index]; |
809 | 804 | ||
810 | iwlagn_unmap_tfd(priv, meta, &txq->tfds[index]); | 805 | iwlagn_unmap_tfd(priv, meta, &txq->tfds[index], PCI_DMA_BIDIRECTIONAL); |
811 | 806 | ||
812 | /* Input error checking is done when commands are added to queue. */ | 807 | /* Input error checking is done when commands are added to queue. */ |
813 | if (meta->flags & CMD_WANT_SKB) { | 808 | if (meta->flags & CMD_WANT_SKB) { |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c index 092e342c19df..942f7a3969a7 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | |||
@@ -298,6 +298,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = { | |||
298 | {RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/ | 298 | {RTL_USB_DEVICE(0x06f8, 0xe033, rtl92cu_hal_cfg)}, /*Hercules - Edimax*/ |
299 | {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ | 299 | {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ |
300 | {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ | 300 | {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ |
301 | {RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/ | ||
301 | {RTL_USB_DEVICE(0x0Df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ | 302 | {RTL_USB_DEVICE(0x0Df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ |
302 | {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ | 303 | {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/ |
303 | /* HP - Lite-On ,8188CUS Slim Combo */ | 304 | /* HP - Lite-On ,8188CUS Slim Combo */ |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 2c5b9b991279..692671b11667 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -3483,6 +3483,8 @@ static int __init pci_setup(char *str) | |||
3483 | pci_no_msi(); | 3483 | pci_no_msi(); |
3484 | } else if (!strcmp(str, "noaer")) { | 3484 | } else if (!strcmp(str, "noaer")) { |
3485 | pci_no_aer(); | 3485 | pci_no_aer(); |
3486 | } else if (!strncmp(str, "realloc", 7)) { | ||
3487 | pci_realloc(); | ||
3486 | } else if (!strcmp(str, "nodomains")) { | 3488 | } else if (!strcmp(str, "nodomains")) { |
3487 | pci_no_domains(); | 3489 | pci_no_domains(); |
3488 | } else if (!strncmp(str, "cbiosize=", 9)) { | 3490 | } else if (!strncmp(str, "cbiosize=", 9)) { |
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 731e20265ace..3a39bf1f1e2c 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -146,6 +146,8 @@ static inline void pci_no_msi(void) { } | |||
146 | static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } | 146 | static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } |
147 | #endif | 147 | #endif |
148 | 148 | ||
149 | extern void pci_realloc(void); | ||
150 | |||
149 | static inline int pci_no_d1d2(struct pci_dev *dev) | 151 | static inline int pci_no_d1d2(struct pci_dev *dev) |
150 | { | 152 | { |
151 | unsigned int parent_dstates = 0; | 153 | unsigned int parent_dstates = 0; |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 1e9e5a5b8c81..9995842e45b5 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -47,6 +47,13 @@ struct resource_list_x { | |||
47 | (head)->next = NULL; \ | 47 | (head)->next = NULL; \ |
48 | } while (0) | 48 | } while (0) |
49 | 49 | ||
50 | int pci_realloc_enable = 0; | ||
51 | #define pci_realloc_enabled() pci_realloc_enable | ||
52 | void pci_realloc(void) | ||
53 | { | ||
54 | pci_realloc_enable = 1; | ||
55 | } | ||
56 | |||
50 | /** | 57 | /** |
51 | * add_to_list() - add a new resource tracker to the list | 58 | * add_to_list() - add a new resource tracker to the list |
52 | * @head: Head of the list | 59 | * @head: Head of the list |
@@ -1025,6 +1032,7 @@ static int __init pci_get_max_depth(void) | |||
1025 | return depth; | 1032 | return depth; |
1026 | } | 1033 | } |
1027 | 1034 | ||
1035 | |||
1028 | /* | 1036 | /* |
1029 | * first try will not touch pci bridge res | 1037 | * first try will not touch pci bridge res |
1030 | * second and later try will clear small leaf bridge res | 1038 | * second and later try will clear small leaf bridge res |
@@ -1068,6 +1076,13 @@ again: | |||
1068 | /* any device complain? */ | 1076 | /* any device complain? */ |
1069 | if (!head.next) | 1077 | if (!head.next) |
1070 | goto enable_and_dump; | 1078 | goto enable_and_dump; |
1079 | |||
1080 | /* don't realloc if asked to do so */ | ||
1081 | if (!pci_realloc_enabled()) { | ||
1082 | free_list(resource_list_x, &head); | ||
1083 | goto enable_and_dump; | ||
1084 | } | ||
1085 | |||
1071 | failed_type = 0; | 1086 | failed_type = 0; |
1072 | for (list = head.next; list;) { | 1087 | for (list = head.next; list;) { |
1073 | failed_type |= list->flags; | 1088 | failed_type |= list->flags; |
diff --git a/drivers/pcmcia/pxa2xx_vpac270.c b/drivers/pcmcia/pxa2xx_vpac270.c index 712baab3c83d..e956f659089a 100644 --- a/drivers/pcmcia/pxa2xx_vpac270.c +++ b/drivers/pcmcia/pxa2xx_vpac270.c | |||
@@ -76,10 +76,10 @@ static int vpac270_pcmcia_hw_init(struct soc_pcmcia_socket *skt) | |||
76 | static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) | 76 | static void vpac270_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) |
77 | { | 77 | { |
78 | if (skt->nr == 0) | 78 | if (skt->nr == 0) |
79 | gpio_request_array(vpac270_pcmcia_gpios, | 79 | gpio_free_array(vpac270_pcmcia_gpios, |
80 | ARRAY_SIZE(vpac270_pcmcia_gpios)); | 80 | ARRAY_SIZE(vpac270_pcmcia_gpios)); |
81 | else | 81 | else |
82 | gpio_request_array(vpac270_cf_gpios, | 82 | gpio_free_array(vpac270_cf_gpios, |
83 | ARRAY_SIZE(vpac270_cf_gpios)); | 83 | ARRAY_SIZE(vpac270_cf_gpios)); |
84 | } | 84 | } |
85 | 85 | ||
diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index 005417bd429e..e1c4938b301b 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c | |||
@@ -1156,9 +1156,9 @@ static acpi_status wmid3_set_device_status(u32 value, u16 device) | |||
1156 | struct wmid3_gds_input_param params = { | 1156 | struct wmid3_gds_input_param params = { |
1157 | .function_num = 0x1, | 1157 | .function_num = 0x1, |
1158 | .hotkey_number = 0x01, | 1158 | .hotkey_number = 0x01, |
1159 | .devices = ACER_WMID3_GDS_WIRELESS & | 1159 | .devices = ACER_WMID3_GDS_WIRELESS | |
1160 | ACER_WMID3_GDS_THREEG & | 1160 | ACER_WMID3_GDS_THREEG | |
1161 | ACER_WMID3_GDS_WIMAX & | 1161 | ACER_WMID3_GDS_WIMAX | |
1162 | ACER_WMID3_GDS_BLUETOOTH, | 1162 | ACER_WMID3_GDS_BLUETOOTH, |
1163 | }; | 1163 | }; |
1164 | struct acpi_buffer input = { | 1164 | struct acpi_buffer input = { |
@@ -1445,6 +1445,8 @@ static void acer_wmi_notify(u32 value, void *context) | |||
1445 | union acpi_object *obj; | 1445 | union acpi_object *obj; |
1446 | struct event_return_value return_value; | 1446 | struct event_return_value return_value; |
1447 | acpi_status status; | 1447 | acpi_status status; |
1448 | u16 device_state; | ||
1449 | const struct key_entry *key; | ||
1448 | 1450 | ||
1449 | status = wmi_get_event_data(value, &response); | 1451 | status = wmi_get_event_data(value, &response); |
1450 | if (status != AE_OK) { | 1452 | if (status != AE_OK) { |
@@ -1472,23 +1474,32 @@ static void acer_wmi_notify(u32 value, void *context) | |||
1472 | 1474 | ||
1473 | switch (return_value.function) { | 1475 | switch (return_value.function) { |
1474 | case WMID_HOTKEY_EVENT: | 1476 | case WMID_HOTKEY_EVENT: |
1475 | if (return_value.device_state) { | 1477 | device_state = return_value.device_state; |
1476 | u16 device_state = return_value.device_state; | 1478 | pr_debug("device state: 0x%x\n", device_state); |
1477 | pr_debug("device state: 0x%x\n", device_state); | 1479 | |
1478 | if (has_cap(ACER_CAP_WIRELESS)) | 1480 | key = sparse_keymap_entry_from_scancode(acer_wmi_input_dev, |
1479 | rfkill_set_sw_state(wireless_rfkill, | 1481 | return_value.key_num); |
1480 | !(device_state & ACER_WMID3_GDS_WIRELESS)); | 1482 | if (!key) { |
1481 | if (has_cap(ACER_CAP_BLUETOOTH)) | ||
1482 | rfkill_set_sw_state(bluetooth_rfkill, | ||
1483 | !(device_state & ACER_WMID3_GDS_BLUETOOTH)); | ||
1484 | if (has_cap(ACER_CAP_THREEG)) | ||
1485 | rfkill_set_sw_state(threeg_rfkill, | ||
1486 | !(device_state & ACER_WMID3_GDS_THREEG)); | ||
1487 | } | ||
1488 | if (!sparse_keymap_report_event(acer_wmi_input_dev, | ||
1489 | return_value.key_num, 1, true)) | ||
1490 | pr_warn("Unknown key number - 0x%x\n", | 1483 | pr_warn("Unknown key number - 0x%x\n", |
1491 | return_value.key_num); | 1484 | return_value.key_num); |
1485 | } else { | ||
1486 | switch (key->keycode) { | ||
1487 | case KEY_WLAN: | ||
1488 | case KEY_BLUETOOTH: | ||
1489 | if (has_cap(ACER_CAP_WIRELESS)) | ||
1490 | rfkill_set_sw_state(wireless_rfkill, | ||
1491 | !(device_state & ACER_WMID3_GDS_WIRELESS)); | ||
1492 | if (has_cap(ACER_CAP_THREEG)) | ||
1493 | rfkill_set_sw_state(threeg_rfkill, | ||
1494 | !(device_state & ACER_WMID3_GDS_THREEG)); | ||
1495 | if (has_cap(ACER_CAP_BLUETOOTH)) | ||
1496 | rfkill_set_sw_state(bluetooth_rfkill, | ||
1497 | !(device_state & ACER_WMID3_GDS_BLUETOOTH)); | ||
1498 | break; | ||
1499 | } | ||
1500 | sparse_keymap_report_entry(acer_wmi_input_dev, key, | ||
1501 | 1, true); | ||
1502 | } | ||
1492 | break; | 1503 | break; |
1493 | default: | 1504 | default: |
1494 | pr_warn("Unknown function number - %d - %d\n", | 1505 | pr_warn("Unknown function number - %d - %d\n", |
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index 00460cb9587b..3c7857c71a23 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c | |||
@@ -1025,6 +1025,7 @@ static int asus_wmi_backlight_init(struct asus_wmi *asus) | |||
1025 | return power; | 1025 | return power; |
1026 | 1026 | ||
1027 | memset(&props, 0, sizeof(struct backlight_properties)); | 1027 | memset(&props, 0, sizeof(struct backlight_properties)); |
1028 | props.type = BACKLIGHT_PLATFORM; | ||
1028 | props.max_brightness = max; | 1029 | props.max_brightness = max; |
1029 | bd = backlight_device_register(asus->driver->name, | 1030 | bd = backlight_device_register(asus->driver->name, |
1030 | &asus->platform_device->dev, asus, | 1031 | &asus->platform_device->dev, asus, |
diff --git a/drivers/platform/x86/compal-laptop.c b/drivers/platform/x86/compal-laptop.c index 3f204fde1b02..8877b836d27c 100644 --- a/drivers/platform/x86/compal-laptop.c +++ b/drivers/platform/x86/compal-laptop.c | |||
@@ -1030,8 +1030,10 @@ static int __devinit compal_probe(struct platform_device *pdev) | |||
1030 | initialize_fan_control_data(data); | 1030 | initialize_fan_control_data(data); |
1031 | 1031 | ||
1032 | err = sysfs_create_group(&pdev->dev.kobj, &compal_attribute_group); | 1032 | err = sysfs_create_group(&pdev->dev.kobj, &compal_attribute_group); |
1033 | if (err) | 1033 | if (err) { |
1034 | kfree(data); | ||
1034 | return err; | 1035 | return err; |
1036 | } | ||
1035 | 1037 | ||
1036 | data->hwmon_dev = hwmon_device_register(&pdev->dev); | 1038 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
1037 | if (IS_ERR(data->hwmon_dev)) { | 1039 | if (IS_ERR(data->hwmon_dev)) { |
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index d3841de6a8cf..e39ab1d3ed87 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c | |||
@@ -292,12 +292,9 @@ static int dell_rfkill_set(void *data, bool blocked) | |||
292 | dell_send_request(buffer, 17, 11); | 292 | dell_send_request(buffer, 17, 11); |
293 | 293 | ||
294 | /* If the hardware switch controls this radio, and the hardware | 294 | /* If the hardware switch controls this radio, and the hardware |
295 | switch is disabled, don't allow changing the software state. | 295 | switch is disabled, don't allow changing the software state */ |
296 | If the hardware switch is reported as not supported, always | ||
297 | fire the SMI to toggle the killswitch. */ | ||
298 | if ((hwswitch_state & BIT(hwswitch_bit)) && | 296 | if ((hwswitch_state & BIT(hwswitch_bit)) && |
299 | !(buffer->output[1] & BIT(16)) && | 297 | !(buffer->output[1] & BIT(16))) { |
300 | (buffer->output[1] & BIT(0))) { | ||
301 | ret = -EINVAL; | 298 | ret = -EINVAL; |
302 | goto out; | 299 | goto out; |
303 | } | 300 | } |
@@ -403,23 +400,6 @@ static const struct file_operations dell_debugfs_fops = { | |||
403 | 400 | ||
404 | static void dell_update_rfkill(struct work_struct *ignored) | 401 | static void dell_update_rfkill(struct work_struct *ignored) |
405 | { | 402 | { |
406 | int status; | ||
407 | |||
408 | get_buffer(); | ||
409 | dell_send_request(buffer, 17, 11); | ||
410 | status = buffer->output[1]; | ||
411 | release_buffer(); | ||
412 | |||
413 | /* if hardware rfkill is not supported, set it explicitly */ | ||
414 | if (!(status & BIT(0))) { | ||
415 | if (wifi_rfkill) | ||
416 | dell_rfkill_set((void *)1, !((status & BIT(17)) >> 17)); | ||
417 | if (bluetooth_rfkill) | ||
418 | dell_rfkill_set((void *)2, !((status & BIT(18)) >> 18)); | ||
419 | if (wwan_rfkill) | ||
420 | dell_rfkill_set((void *)3, !((status & BIT(19)) >> 19)); | ||
421 | } | ||
422 | |||
423 | if (wifi_rfkill) | 403 | if (wifi_rfkill) |
424 | dell_rfkill_query(wifi_rfkill, (void *)1); | 404 | dell_rfkill_query(wifi_rfkill, (void *)1); |
425 | if (bluetooth_rfkill) | 405 | if (bluetooth_rfkill) |
@@ -560,11 +540,11 @@ static int dell_get_intensity(struct backlight_device *bd) | |||
560 | else | 540 | else |
561 | dell_send_request(buffer, 0, 1); | 541 | dell_send_request(buffer, 0, 1); |
562 | 542 | ||
543 | ret = buffer->output[1]; | ||
544 | |||
563 | out: | 545 | out: |
564 | release_buffer(); | 546 | release_buffer(); |
565 | if (ret) | 547 | return ret; |
566 | return ret; | ||
567 | return buffer->output[1]; | ||
568 | } | 548 | } |
569 | 549 | ||
570 | static const struct backlight_ops dell_ops = { | 550 | static const struct backlight_ops dell_ops = { |
diff --git a/drivers/platform/x86/hp-wmi.c b/drivers/platform/x86/hp-wmi.c index f94017bcdd6e..e2faa3cbb792 100644 --- a/drivers/platform/x86/hp-wmi.c +++ b/drivers/platform/x86/hp-wmi.c | |||
@@ -207,6 +207,7 @@ static int hp_wmi_perform_query(int query, int write, void *buffer, | |||
207 | }; | 207 | }; |
208 | struct acpi_buffer input = { sizeof(struct bios_args), &args }; | 208 | struct acpi_buffer input = { sizeof(struct bios_args), &args }; |
209 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | 209 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; |
210 | u32 rc; | ||
210 | 211 | ||
211 | if (WARN_ON(insize > sizeof(args.data))) | 212 | if (WARN_ON(insize > sizeof(args.data))) |
212 | return -EINVAL; | 213 | return -EINVAL; |
@@ -224,13 +225,13 @@ static int hp_wmi_perform_query(int query, int write, void *buffer, | |||
224 | } | 225 | } |
225 | 226 | ||
226 | bios_return = (struct bios_return *)obj->buffer.pointer; | 227 | bios_return = (struct bios_return *)obj->buffer.pointer; |
228 | rc = bios_return->return_code; | ||
227 | 229 | ||
228 | if (bios_return->return_code) { | 230 | if (rc) { |
229 | if (bios_return->return_code != HPWMI_RET_UNKNOWN_CMDTYPE) | 231 | if (rc != HPWMI_RET_UNKNOWN_CMDTYPE) |
230 | pr_warn("query 0x%x returned error 0x%x\n", | 232 | pr_warn("query 0x%x returned error 0x%x\n", query, rc); |
231 | query, bios_return->return_code); | ||
232 | kfree(obj); | 233 | kfree(obj); |
233 | return bios_return->return_code; | 234 | return rc; |
234 | } | 235 | } |
235 | 236 | ||
236 | if (!outsize) { | 237 | if (!outsize) { |
diff --git a/drivers/platform/x86/intel_oaktrail.c b/drivers/platform/x86/intel_oaktrail.c index e936364a609d..7f88c7923fc6 100644 --- a/drivers/platform/x86/intel_oaktrail.c +++ b/drivers/platform/x86/intel_oaktrail.c | |||
@@ -250,6 +250,7 @@ static int oaktrail_backlight_init(void) | |||
250 | struct backlight_properties props; | 250 | struct backlight_properties props; |
251 | 251 | ||
252 | memset(&props, 0, sizeof(struct backlight_properties)); | 252 | memset(&props, 0, sizeof(struct backlight_properties)); |
253 | props.type = BACKLIGHT_PLATFORM; | ||
253 | props.max_brightness = OT_EC_BL_BRIGHTNESS_MAX; | 254 | props.max_brightness = OT_EC_BL_BRIGHTNESS_MAX; |
254 | bd = backlight_device_register(DRIVER_NAME, | 255 | bd = backlight_device_register(DRIVER_NAME, |
255 | &oaktrail_device->dev, NULL, | 256 | &oaktrail_device->dev, NULL, |
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 77f6e707a2a9..26c5b117df22 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -184,6 +184,10 @@ enum tpacpi_hkey_event_t { | |||
184 | 184 | ||
185 | /* Misc bay events */ | 185 | /* Misc bay events */ |
186 | TP_HKEY_EV_OPTDRV_EJ = 0x3006, /* opt. drive tray ejected */ | 186 | TP_HKEY_EV_OPTDRV_EJ = 0x3006, /* opt. drive tray ejected */ |
187 | TP_HKEY_EV_HOTPLUG_DOCK = 0x4010, /* docked into hotplug dock | ||
188 | or port replicator */ | ||
189 | TP_HKEY_EV_HOTPLUG_UNDOCK = 0x4011, /* undocked from hotplug | ||
190 | dock or port replicator */ | ||
187 | 191 | ||
188 | /* User-interface events */ | 192 | /* User-interface events */ |
189 | TP_HKEY_EV_LID_CLOSE = 0x5001, /* laptop lid closed */ | 193 | TP_HKEY_EV_LID_CLOSE = 0x5001, /* laptop lid closed */ |
@@ -194,6 +198,10 @@ enum tpacpi_hkey_event_t { | |||
194 | TP_HKEY_EV_PEN_REMOVED = 0x500c, /* tablet pen removed */ | 198 | TP_HKEY_EV_PEN_REMOVED = 0x500c, /* tablet pen removed */ |
195 | TP_HKEY_EV_BRGHT_CHANGED = 0x5010, /* backlight control event */ | 199 | TP_HKEY_EV_BRGHT_CHANGED = 0x5010, /* backlight control event */ |
196 | 200 | ||
201 | /* Key-related user-interface events */ | ||
202 | TP_HKEY_EV_KEY_NUMLOCK = 0x6000, /* NumLock key pressed */ | ||
203 | TP_HKEY_EV_KEY_FN = 0x6005, /* Fn key pressed? E420 */ | ||
204 | |||
197 | /* Thermal events */ | 205 | /* Thermal events */ |
198 | TP_HKEY_EV_ALARM_BAT_HOT = 0x6011, /* battery too hot */ | 206 | TP_HKEY_EV_ALARM_BAT_HOT = 0x6011, /* battery too hot */ |
199 | TP_HKEY_EV_ALARM_BAT_XHOT = 0x6012, /* battery critically hot */ | 207 | TP_HKEY_EV_ALARM_BAT_XHOT = 0x6012, /* battery critically hot */ |
@@ -201,6 +209,10 @@ enum tpacpi_hkey_event_t { | |||
201 | TP_HKEY_EV_ALARM_SENSOR_XHOT = 0x6022, /* sensor critically hot */ | 209 | TP_HKEY_EV_ALARM_SENSOR_XHOT = 0x6022, /* sensor critically hot */ |
202 | TP_HKEY_EV_THM_TABLE_CHANGED = 0x6030, /* thermal table changed */ | 210 | TP_HKEY_EV_THM_TABLE_CHANGED = 0x6030, /* thermal table changed */ |
203 | 211 | ||
212 | TP_HKEY_EV_UNK_6040 = 0x6040, /* Related to AC change? | ||
213 | some sort of APM hint, | ||
214 | W520 */ | ||
215 | |||
204 | /* Misc */ | 216 | /* Misc */ |
205 | TP_HKEY_EV_RFKILL_CHANGED = 0x7000, /* rfkill switch changed */ | 217 | TP_HKEY_EV_RFKILL_CHANGED = 0x7000, /* rfkill switch changed */ |
206 | }; | 218 | }; |
@@ -3513,6 +3525,34 @@ static bool hotkey_notify_wakeup(const u32 hkey, | |||
3513 | return true; | 3525 | return true; |
3514 | } | 3526 | } |
3515 | 3527 | ||
3528 | static bool hotkey_notify_dockevent(const u32 hkey, | ||
3529 | bool *send_acpi_ev, | ||
3530 | bool *ignore_acpi_ev) | ||
3531 | { | ||
3532 | /* 0x4000-0x4FFF: dock-related events */ | ||
3533 | *send_acpi_ev = true; | ||
3534 | *ignore_acpi_ev = false; | ||
3535 | |||
3536 | switch (hkey) { | ||
3537 | case TP_HKEY_EV_UNDOCK_ACK: | ||
3538 | /* ACPI undock operation completed after wakeup */ | ||
3539 | hotkey_autosleep_ack = 1; | ||
3540 | pr_info("undocked\n"); | ||
3541 | hotkey_wakeup_hotunplug_complete_notify_change(); | ||
3542 | return true; | ||
3543 | |||
3544 | case TP_HKEY_EV_HOTPLUG_DOCK: /* docked to port replicator */ | ||
3545 | pr_info("docked into hotplug port replicator\n"); | ||
3546 | return true; | ||
3547 | case TP_HKEY_EV_HOTPLUG_UNDOCK: /* undocked from port replicator */ | ||
3548 | pr_info("undocked from hotplug port replicator\n"); | ||
3549 | return true; | ||
3550 | |||
3551 | default: | ||
3552 | return false; | ||
3553 | } | ||
3554 | } | ||
3555 | |||
3516 | static bool hotkey_notify_usrevent(const u32 hkey, | 3556 | static bool hotkey_notify_usrevent(const u32 hkey, |
3517 | bool *send_acpi_ev, | 3557 | bool *send_acpi_ev, |
3518 | bool *ignore_acpi_ev) | 3558 | bool *ignore_acpi_ev) |
@@ -3547,13 +3587,13 @@ static bool hotkey_notify_usrevent(const u32 hkey, | |||
3547 | 3587 | ||
3548 | static void thermal_dump_all_sensors(void); | 3588 | static void thermal_dump_all_sensors(void); |
3549 | 3589 | ||
3550 | static bool hotkey_notify_thermal(const u32 hkey, | 3590 | static bool hotkey_notify_6xxx(const u32 hkey, |
3551 | bool *send_acpi_ev, | 3591 | bool *send_acpi_ev, |
3552 | bool *ignore_acpi_ev) | 3592 | bool *ignore_acpi_ev) |
3553 | { | 3593 | { |
3554 | bool known = true; | 3594 | bool known = true; |
3555 | 3595 | ||
3556 | /* 0x6000-0x6FFF: thermal alarms */ | 3596 | /* 0x6000-0x6FFF: thermal alarms/notices and keyboard events */ |
3557 | *send_acpi_ev = true; | 3597 | *send_acpi_ev = true; |
3558 | *ignore_acpi_ev = false; | 3598 | *ignore_acpi_ev = false; |
3559 | 3599 | ||
@@ -3582,8 +3622,17 @@ static bool hotkey_notify_thermal(const u32 hkey, | |||
3582 | "a sensor reports something is extremely hot!\n"); | 3622 | "a sensor reports something is extremely hot!\n"); |
3583 | /* recommended action: immediate sleep/hibernate */ | 3623 | /* recommended action: immediate sleep/hibernate */ |
3584 | break; | 3624 | break; |
3625 | |||
3626 | case TP_HKEY_EV_KEY_NUMLOCK: | ||
3627 | case TP_HKEY_EV_KEY_FN: | ||
3628 | /* key press events, we just ignore them as long as the EC | ||
3629 | * is still reporting them in the normal keyboard stream */ | ||
3630 | *send_acpi_ev = false; | ||
3631 | *ignore_acpi_ev = true; | ||
3632 | return true; | ||
3633 | |||
3585 | default: | 3634 | default: |
3586 | pr_alert("THERMAL ALERT: unknown thermal alarm received\n"); | 3635 | pr_warn("unknown possible thermal alarm or keyboard event received\n"); |
3587 | known = false; | 3636 | known = false; |
3588 | } | 3637 | } |
3589 | 3638 | ||
@@ -3652,15 +3701,9 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) | |||
3652 | } | 3701 | } |
3653 | break; | 3702 | break; |
3654 | case 4: | 3703 | case 4: |
3655 | /* 0x4000-0x4FFF: dock-related wakeups */ | 3704 | /* 0x4000-0x4FFF: dock-related events */ |
3656 | if (hkey == TP_HKEY_EV_UNDOCK_ACK) { | 3705 | known_ev = hotkey_notify_dockevent(hkey, &send_acpi_ev, |
3657 | hotkey_autosleep_ack = 1; | 3706 | &ignore_acpi_ev); |
3658 | pr_info("undocked\n"); | ||
3659 | hotkey_wakeup_hotunplug_complete_notify_change(); | ||
3660 | known_ev = true; | ||
3661 | } else { | ||
3662 | known_ev = false; | ||
3663 | } | ||
3664 | break; | 3707 | break; |
3665 | case 5: | 3708 | case 5: |
3666 | /* 0x5000-0x5FFF: human interface helpers */ | 3709 | /* 0x5000-0x5FFF: human interface helpers */ |
@@ -3668,8 +3711,9 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) | |||
3668 | &ignore_acpi_ev); | 3711 | &ignore_acpi_ev); |
3669 | break; | 3712 | break; |
3670 | case 6: | 3713 | case 6: |
3671 | /* 0x6000-0x6FFF: thermal alarms */ | 3714 | /* 0x6000-0x6FFF: thermal alarms/notices and |
3672 | known_ev = hotkey_notify_thermal(hkey, &send_acpi_ev, | 3715 | * keyboard events */ |
3716 | known_ev = hotkey_notify_6xxx(hkey, &send_acpi_ev, | ||
3673 | &ignore_acpi_ev); | 3717 | &ignore_acpi_ev); |
3674 | break; | 3718 | break; |
3675 | case 7: | 3719 | case 7: |
diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c index e5f7b8fe51f4..2bb8f451cc06 100644 --- a/drivers/regulator/db8500-prcmu.c +++ b/drivers/regulator/db8500-prcmu.c | |||
@@ -266,7 +266,7 @@ static struct regulator_ops db8500_regulator_switch_ops = { | |||
266 | * Regulator information | 266 | * Regulator information |
267 | */ | 267 | */ |
268 | static struct db8500_regulator_info | 268 | static struct db8500_regulator_info |
269 | db8500_regulator_info[DB8500_NUM_REGULATORS] = { | 269 | db8500_regulator_info[DB8500_NUM_REGULATORS] = { |
270 | [DB8500_REGULATOR_VAPE] = { | 270 | [DB8500_REGULATOR_VAPE] = { |
271 | .desc = { | 271 | .desc = { |
272 | .name = "db8500-vape", | 272 | .name = "db8500-vape", |
@@ -492,11 +492,9 @@ static int __devinit db8500_regulator_probe(struct platform_device *pdev) | |||
492 | info->desc.name, err); | 492 | info->desc.name, err); |
493 | 493 | ||
494 | /* if failing, unregister all earlier regulators */ | 494 | /* if failing, unregister all earlier regulators */ |
495 | i--; | 495 | while (--i >= 0) { |
496 | while (i >= 0) { | ||
497 | info = &db8500_regulator_info[i]; | 496 | info = &db8500_regulator_info[i]; |
498 | regulator_unregister(info->rdev); | 497 | regulator_unregister(info->rdev); |
499 | i--; | ||
500 | } | 498 | } |
501 | return err; | 499 | return err; |
502 | } | 500 | } |
@@ -536,13 +534,7 @@ static struct platform_driver db8500_regulator_driver = { | |||
536 | 534 | ||
537 | static int __init db8500_regulator_init(void) | 535 | static int __init db8500_regulator_init(void) |
538 | { | 536 | { |
539 | int ret; | 537 | return platform_driver_register(&db8500_regulator_driver); |
540 | |||
541 | ret = platform_driver_register(&db8500_regulator_driver); | ||
542 | if (ret < 0) | ||
543 | return -ENODEV; | ||
544 | |||
545 | return 0; | ||
546 | } | 538 | } |
547 | 539 | ||
548 | static void __exit db8500_regulator_exit(void) | 540 | static void __exit db8500_regulator_exit(void) |
diff --git a/drivers/regulator/max8952.c b/drivers/regulator/max8952.c index daff7fd0e95c..486ed8141fcd 100644 --- a/drivers/regulator/max8952.c +++ b/drivers/regulator/max8952.c | |||
@@ -139,7 +139,7 @@ static int max8952_set_voltage(struct regulator_dev *rdev, | |||
139 | s8 vid = -1, i; | 139 | s8 vid = -1, i; |
140 | 140 | ||
141 | if (!gpio_is_valid(max8952->pdata->gpio_vid0) || | 141 | if (!gpio_is_valid(max8952->pdata->gpio_vid0) || |
142 | !gpio_is_valid(max8952->pdata->gpio_vid0)) { | 142 | !gpio_is_valid(max8952->pdata->gpio_vid1)) { |
143 | /* DVS not supported */ | 143 | /* DVS not supported */ |
144 | return -EPERM; | 144 | return -EPERM; |
145 | } | 145 | } |
diff --git a/drivers/regulator/max8997.c b/drivers/regulator/max8997.c index 10d5a1d9768e..ad6628ca94f4 100644 --- a/drivers/regulator/max8997.c +++ b/drivers/regulator/max8997.c | |||
@@ -39,25 +39,28 @@ struct max8997_data { | |||
39 | struct regulator_dev **rdev; | 39 | struct regulator_dev **rdev; |
40 | int ramp_delay; /* in mV/us */ | 40 | int ramp_delay; /* in mV/us */ |
41 | 41 | ||
42 | bool buck1_gpiodvs; | ||
43 | bool buck2_gpiodvs; | ||
44 | bool buck5_gpiodvs; | ||
42 | u8 buck1_vol[8]; | 45 | u8 buck1_vol[8]; |
43 | u8 buck2_vol[8]; | 46 | u8 buck2_vol[8]; |
44 | u8 buck5_vol[8]; | 47 | u8 buck5_vol[8]; |
48 | int buck125_gpios[3]; | ||
45 | int buck125_gpioindex; | 49 | int buck125_gpioindex; |
50 | bool ignore_gpiodvs_side_effect; | ||
46 | 51 | ||
47 | u8 saved_states[MAX8997_REG_MAX]; | 52 | u8 saved_states[MAX8997_REG_MAX]; |
48 | }; | 53 | }; |
49 | 54 | ||
50 | static inline void max8997_set_gpio(struct max8997_data *max8997) | 55 | static inline void max8997_set_gpio(struct max8997_data *max8997) |
51 | { | 56 | { |
52 | struct max8997_platform_data *pdata = | ||
53 | dev_get_platdata(max8997->iodev->dev); | ||
54 | int set3 = (max8997->buck125_gpioindex) & 0x1; | 57 | int set3 = (max8997->buck125_gpioindex) & 0x1; |
55 | int set2 = ((max8997->buck125_gpioindex) >> 1) & 0x1; | 58 | int set2 = ((max8997->buck125_gpioindex) >> 1) & 0x1; |
56 | int set1 = ((max8997->buck125_gpioindex) >> 2) & 0x1; | 59 | int set1 = ((max8997->buck125_gpioindex) >> 2) & 0x1; |
57 | 60 | ||
58 | gpio_set_value(pdata->buck125_gpios[0], set1); | 61 | gpio_set_value(max8997->buck125_gpios[0], set1); |
59 | gpio_set_value(pdata->buck125_gpios[1], set2); | 62 | gpio_set_value(max8997->buck125_gpios[1], set2); |
60 | gpio_set_value(pdata->buck125_gpios[2], set3); | 63 | gpio_set_value(max8997->buck125_gpios[2], set3); |
61 | } | 64 | } |
62 | 65 | ||
63 | struct voltage_map_desc { | 66 | struct voltage_map_desc { |
@@ -380,8 +383,6 @@ static int max8997_get_voltage_register(struct regulator_dev *rdev, | |||
380 | static int max8997_get_voltage(struct regulator_dev *rdev) | 383 | static int max8997_get_voltage(struct regulator_dev *rdev) |
381 | { | 384 | { |
382 | struct max8997_data *max8997 = rdev_get_drvdata(rdev); | 385 | struct max8997_data *max8997 = rdev_get_drvdata(rdev); |
383 | struct max8997_platform_data *pdata = | ||
384 | dev_get_platdata(max8997->iodev->dev); | ||
385 | struct i2c_client *i2c = max8997->iodev->i2c; | 386 | struct i2c_client *i2c = max8997->iodev->i2c; |
386 | int reg, shift, mask, ret; | 387 | int reg, shift, mask, ret; |
387 | int rid = max8997_get_rid(rdev); | 388 | int rid = max8997_get_rid(rdev); |
@@ -391,9 +392,9 @@ static int max8997_get_voltage(struct regulator_dev *rdev) | |||
391 | if (ret) | 392 | if (ret) |
392 | return ret; | 393 | return ret; |
393 | 394 | ||
394 | if ((rid == MAX8997_BUCK1 && pdata->buck1_gpiodvs) || | 395 | if ((rid == MAX8997_BUCK1 && max8997->buck1_gpiodvs) || |
395 | (rid == MAX8997_BUCK2 && pdata->buck2_gpiodvs) || | 396 | (rid == MAX8997_BUCK2 && max8997->buck2_gpiodvs) || |
396 | (rid == MAX8997_BUCK5 && pdata->buck5_gpiodvs)) | 397 | (rid == MAX8997_BUCK5 && max8997->buck5_gpiodvs)) |
397 | reg += max8997->buck125_gpioindex; | 398 | reg += max8997->buck125_gpioindex; |
398 | 399 | ||
399 | ret = max8997_read_reg(i2c, reg, &val); | 400 | ret = max8997_read_reg(i2c, reg, &val); |
@@ -543,7 +544,8 @@ static int max8997_set_voltage_ldobuck(struct regulator_dev *rdev, | |||
543 | rid == MAX8997_BUCK4 || rid == MAX8997_BUCK5) { | 544 | rid == MAX8997_BUCK4 || rid == MAX8997_BUCK5) { |
544 | /* If the voltage is increasing */ | 545 | /* If the voltage is increasing */ |
545 | if (org < i) | 546 | if (org < i) |
546 | udelay(desc->step * (i - org) / max8997->ramp_delay); | 547 | udelay(DIV_ROUND_UP(desc->step * (i - org), |
548 | max8997->ramp_delay)); | ||
547 | } | 549 | } |
548 | 550 | ||
549 | return ret; | 551 | return ret; |
@@ -561,8 +563,6 @@ static int max8997_assess_side_effect(struct regulator_dev *rdev, | |||
561 | u8 new_val, int *best) | 563 | u8 new_val, int *best) |
562 | { | 564 | { |
563 | struct max8997_data *max8997 = rdev_get_drvdata(rdev); | 565 | struct max8997_data *max8997 = rdev_get_drvdata(rdev); |
564 | struct max8997_platform_data *pdata = | ||
565 | dev_get_platdata(max8997->iodev->dev); | ||
566 | int rid = max8997_get_rid(rdev); | 566 | int rid = max8997_get_rid(rdev); |
567 | u8 *buckx_val[3]; | 567 | u8 *buckx_val[3]; |
568 | bool buckx_gpiodvs[3]; | 568 | bool buckx_gpiodvs[3]; |
@@ -589,9 +589,9 @@ static int max8997_assess_side_effect(struct regulator_dev *rdev, | |||
589 | buckx_val[0] = max8997->buck1_vol; | 589 | buckx_val[0] = max8997->buck1_vol; |
590 | buckx_val[1] = max8997->buck2_vol; | 590 | buckx_val[1] = max8997->buck2_vol; |
591 | buckx_val[2] = max8997->buck5_vol; | 591 | buckx_val[2] = max8997->buck5_vol; |
592 | buckx_gpiodvs[0] = pdata->buck1_gpiodvs; | 592 | buckx_gpiodvs[0] = max8997->buck1_gpiodvs; |
593 | buckx_gpiodvs[1] = pdata->buck2_gpiodvs; | 593 | buckx_gpiodvs[1] = max8997->buck2_gpiodvs; |
594 | buckx_gpiodvs[2] = pdata->buck5_gpiodvs; | 594 | buckx_gpiodvs[2] = max8997->buck5_gpiodvs; |
595 | 595 | ||
596 | for (i = 0; i < 8; i++) { | 596 | for (i = 0; i < 8; i++) { |
597 | int others; | 597 | int others; |
@@ -640,8 +640,6 @@ static int max8997_set_voltage_buck(struct regulator_dev *rdev, | |||
640 | int min_uV, int max_uV, unsigned *selector) | 640 | int min_uV, int max_uV, unsigned *selector) |
641 | { | 641 | { |
642 | struct max8997_data *max8997 = rdev_get_drvdata(rdev); | 642 | struct max8997_data *max8997 = rdev_get_drvdata(rdev); |
643 | struct max8997_platform_data *pdata = | ||
644 | dev_get_platdata(max8997->iodev->dev); | ||
645 | int rid = max8997_get_rid(rdev); | 643 | int rid = max8997_get_rid(rdev); |
646 | const struct voltage_map_desc *desc; | 644 | const struct voltage_map_desc *desc; |
647 | int new_val, new_idx, damage, tmp_val, tmp_idx, tmp_dmg; | 645 | int new_val, new_idx, damage, tmp_val, tmp_idx, tmp_dmg; |
@@ -653,15 +651,15 @@ static int max8997_set_voltage_buck(struct regulator_dev *rdev, | |||
653 | 651 | ||
654 | switch (rid) { | 652 | switch (rid) { |
655 | case MAX8997_BUCK1: | 653 | case MAX8997_BUCK1: |
656 | if (pdata->buck1_gpiodvs) | 654 | if (max8997->buck1_gpiodvs) |
657 | gpio_dvs_mode = true; | 655 | gpio_dvs_mode = true; |
658 | break; | 656 | break; |
659 | case MAX8997_BUCK2: | 657 | case MAX8997_BUCK2: |
660 | if (pdata->buck2_gpiodvs) | 658 | if (max8997->buck2_gpiodvs) |
661 | gpio_dvs_mode = true; | 659 | gpio_dvs_mode = true; |
662 | break; | 660 | break; |
663 | case MAX8997_BUCK5: | 661 | case MAX8997_BUCK5: |
664 | if (pdata->buck5_gpiodvs) | 662 | if (max8997->buck5_gpiodvs) |
665 | gpio_dvs_mode = true; | 663 | gpio_dvs_mode = true; |
666 | break; | 664 | break; |
667 | } | 665 | } |
@@ -695,7 +693,7 @@ static int max8997_set_voltage_buck(struct regulator_dev *rdev, | |||
695 | new_idx = tmp_idx; | 693 | new_idx = tmp_idx; |
696 | new_val = tmp_val; | 694 | new_val = tmp_val; |
697 | 695 | ||
698 | if (pdata->ignore_gpiodvs_side_effect == false) | 696 | if (max8997->ignore_gpiodvs_side_effect == false) |
699 | return -EINVAL; | 697 | return -EINVAL; |
700 | 698 | ||
701 | dev_warn(&rdev->dev, "MAX8997 GPIO-DVS Side Effect Warning: GPIO SET:" | 699 | dev_warn(&rdev->dev, "MAX8997 GPIO-DVS Side Effect Warning: GPIO SET:" |
@@ -993,6 +991,11 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) | |||
993 | i2c = max8997->iodev->i2c; | 991 | i2c = max8997->iodev->i2c; |
994 | 992 | ||
995 | max8997->buck125_gpioindex = pdata->buck125_default_idx; | 993 | max8997->buck125_gpioindex = pdata->buck125_default_idx; |
994 | max8997->buck1_gpiodvs = pdata->buck1_gpiodvs; | ||
995 | max8997->buck2_gpiodvs = pdata->buck2_gpiodvs; | ||
996 | max8997->buck5_gpiodvs = pdata->buck5_gpiodvs; | ||
997 | memcpy(max8997->buck125_gpios, pdata->buck125_gpios, sizeof(int) * 3); | ||
998 | max8997->ignore_gpiodvs_side_effect = pdata->ignore_gpiodvs_side_effect; | ||
996 | 999 | ||
997 | for (i = 0; i < 8; i++) { | 1000 | for (i = 0; i < 8; i++) { |
998 | max8997->buck1_vol[i] = ret = | 1001 | max8997->buck1_vol[i] = ret = |
@@ -1124,6 +1127,10 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) | |||
1124 | 0x3f); | 1127 | 0x3f); |
1125 | } | 1128 | } |
1126 | 1129 | ||
1130 | /* Misc Settings */ | ||
1131 | max8997->ramp_delay = 10; /* set 10mV/us, which is the default */ | ||
1132 | max8997_write_reg(i2c, MAX8997_REG_BUCKRAMP, (0xf << 4) | 0x9); | ||
1133 | |||
1127 | for (i = 0; i < pdata->num_regulators; i++) { | 1134 | for (i = 0; i < pdata->num_regulators; i++) { |
1128 | const struct voltage_map_desc *desc; | 1135 | const struct voltage_map_desc *desc; |
1129 | int id = pdata->regulators[i].id; | 1136 | int id = pdata->regulators[i].id; |
@@ -1148,10 +1155,6 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) | |||
1148 | } | 1155 | } |
1149 | } | 1156 | } |
1150 | 1157 | ||
1151 | /* Misc Settings */ | ||
1152 | max8997->ramp_delay = 10; /* set 10mV/us, which is the default */ | ||
1153 | max8997_write_reg(i2c, MAX8997_REG_BUCKRAMP, (0xf << 4) | 0x9); | ||
1154 | |||
1155 | return 0; | 1158 | return 0; |
1156 | err: | 1159 | err: |
1157 | for (i = 0; i < max8997->num_regulators; i++) | 1160 | for (i = 0; i < max8997->num_regulators; i++) |
diff --git a/drivers/spi/spi_s3c64xx.c b/drivers/spi/spi_s3c64xx.c index 795828b90f45..8945e201e42e 100644 --- a/drivers/spi/spi_s3c64xx.c +++ b/drivers/spi/spi_s3c64xx.c | |||
@@ -116,9 +116,7 @@ | |||
116 | (((i)->fifo_lvl_mask + 1))) \ | 116 | (((i)->fifo_lvl_mask + 1))) \ |
117 | ? 1 : 0) | 117 | ? 1 : 0) |
118 | 118 | ||
119 | #define S3C64XX_SPI_ST_TX_DONE(v, i) ((((v) >> (i)->rx_lvl_offset) & \ | 119 | #define S3C64XX_SPI_ST_TX_DONE(v, i) (((v) & (1 << (i)->tx_st_done)) ? 1 : 0) |
120 | (((i)->fifo_lvl_mask + 1) << 1)) \ | ||
121 | ? 1 : 0) | ||
122 | #define TX_FIFO_LVL(v, i) (((v) >> 6) & (i)->fifo_lvl_mask) | 120 | #define TX_FIFO_LVL(v, i) (((v) >> 6) & (i)->fifo_lvl_mask) |
123 | #define RX_FIFO_LVL(v, i) (((v) >> (i)->rx_lvl_offset) & (i)->fifo_lvl_mask) | 121 | #define RX_FIFO_LVL(v, i) (((v) >> (i)->rx_lvl_offset) & (i)->fifo_lvl_mask) |
124 | 122 | ||
diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index 2a20dabec76d..d6620ad309ce 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c | |||
@@ -516,8 +516,17 @@ static void ssb_pcicore_pcie_setup_workarounds(struct ssb_pcicore *pc) | |||
516 | 516 | ||
517 | static void ssb_pcicore_init_clientmode(struct ssb_pcicore *pc) | 517 | static void ssb_pcicore_init_clientmode(struct ssb_pcicore *pc) |
518 | { | 518 | { |
519 | ssb_pcicore_fix_sprom_core_index(pc); | ||
520 | |||
519 | /* Disable PCI interrupts. */ | 521 | /* Disable PCI interrupts. */ |
520 | ssb_write32(pc->dev, SSB_INTVEC, 0); | 522 | ssb_write32(pc->dev, SSB_INTVEC, 0); |
523 | |||
524 | /* Additional PCIe always once-executed workarounds */ | ||
525 | if (pc->dev->id.coreid == SSB_DEV_PCIE) { | ||
526 | ssb_pcicore_serdes_workaround(pc); | ||
527 | /* TODO: ASPM */ | ||
528 | /* TODO: Clock Request Update */ | ||
529 | } | ||
521 | } | 530 | } |
522 | 531 | ||
523 | void ssb_pcicore_init(struct ssb_pcicore *pc) | 532 | void ssb_pcicore_init(struct ssb_pcicore *pc) |
@@ -529,8 +538,6 @@ void ssb_pcicore_init(struct ssb_pcicore *pc) | |||
529 | if (!ssb_device_is_enabled(dev)) | 538 | if (!ssb_device_is_enabled(dev)) |
530 | ssb_device_enable(dev, 0); | 539 | ssb_device_enable(dev, 0); |
531 | 540 | ||
532 | ssb_pcicore_fix_sprom_core_index(pc); | ||
533 | |||
534 | #ifdef CONFIG_SSB_PCICORE_HOSTMODE | 541 | #ifdef CONFIG_SSB_PCICORE_HOSTMODE |
535 | pc->hostmode = pcicore_is_in_hostmode(pc); | 542 | pc->hostmode = pcicore_is_in_hostmode(pc); |
536 | if (pc->hostmode) | 543 | if (pc->hostmode) |
@@ -538,13 +545,6 @@ void ssb_pcicore_init(struct ssb_pcicore *pc) | |||
538 | #endif /* CONFIG_SSB_PCICORE_HOSTMODE */ | 545 | #endif /* CONFIG_SSB_PCICORE_HOSTMODE */ |
539 | if (!pc->hostmode) | 546 | if (!pc->hostmode) |
540 | ssb_pcicore_init_clientmode(pc); | 547 | ssb_pcicore_init_clientmode(pc); |
541 | |||
542 | /* Additional PCIe always once-executed workarounds */ | ||
543 | if (dev->id.coreid == SSB_DEV_PCIE) { | ||
544 | ssb_pcicore_serdes_workaround(pc); | ||
545 | /* TODO: ASPM */ | ||
546 | /* TODO: Clock Request Update */ | ||
547 | } | ||
548 | } | 548 | } |
549 | 549 | ||
550 | static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address) | 550 | static u32 ssb_pcie_read(struct ssb_pcicore *pc, u32 address) |
diff --git a/drivers/staging/lirc/lirc_imon.c b/drivers/staging/lirc/lirc_imon.c index 4039eda2a15b..4a9e563f40fa 100644 --- a/drivers/staging/lirc/lirc_imon.c +++ b/drivers/staging/lirc/lirc_imon.c | |||
@@ -672,8 +672,6 @@ static void imon_incoming_packet(struct imon_context *context, | |||
672 | static void usb_rx_callback(struct urb *urb) | 672 | static void usb_rx_callback(struct urb *urb) |
673 | { | 673 | { |
674 | struct imon_context *context; | 674 | struct imon_context *context; |
675 | unsigned char *buf; | ||
676 | int len; | ||
677 | int intfnum = 0; | 675 | int intfnum = 0; |
678 | 676 | ||
679 | if (!urb) | 677 | if (!urb) |
@@ -683,9 +681,6 @@ static void usb_rx_callback(struct urb *urb) | |||
683 | if (!context) | 681 | if (!context) |
684 | return; | 682 | return; |
685 | 683 | ||
686 | buf = urb->transfer_buffer; | ||
687 | len = urb->actual_length; | ||
688 | |||
689 | switch (urb->status) { | 684 | switch (urb->status) { |
690 | case -ENOENT: /* usbcore unlink successful! */ | 685 | case -ENOENT: /* usbcore unlink successful! */ |
691 | return; | 686 | return; |
@@ -728,7 +723,6 @@ static int imon_probe(struct usb_interface *interface, | |||
728 | int ir_ep_found = 0; | 723 | int ir_ep_found = 0; |
729 | int alloc_status = 0; | 724 | int alloc_status = 0; |
730 | int vfd_proto_6p = 0; | 725 | int vfd_proto_6p = 0; |
731 | int code_length; | ||
732 | struct imon_context *context = NULL; | 726 | struct imon_context *context = NULL; |
733 | int i; | 727 | int i; |
734 | u16 vendor, product; | 728 | u16 vendor, product; |
@@ -749,8 +743,6 @@ static int imon_probe(struct usb_interface *interface, | |||
749 | else | 743 | else |
750 | context->display = 1; | 744 | context->display = 1; |
751 | 745 | ||
752 | code_length = BUF_CHUNK_SIZE * 8; | ||
753 | |||
754 | usbdev = usb_get_dev(interface_to_usbdev(interface)); | 746 | usbdev = usb_get_dev(interface_to_usbdev(interface)); |
755 | iface_desc = interface->cur_altsetting; | 747 | iface_desc = interface->cur_altsetting; |
756 | num_endpts = iface_desc->desc.bNumEndpoints; | 748 | num_endpts = iface_desc->desc.bNumEndpoints; |
@@ -856,7 +848,7 @@ static int imon_probe(struct usb_interface *interface, | |||
856 | 848 | ||
857 | strcpy(driver->name, MOD_NAME); | 849 | strcpy(driver->name, MOD_NAME); |
858 | driver->minor = -1; | 850 | driver->minor = -1; |
859 | driver->code_length = sizeof(int) * 8; | 851 | driver->code_length = BUF_CHUNK_SIZE * 8; |
860 | driver->sample_rate = 0; | 852 | driver->sample_rate = 0; |
861 | driver->features = LIRC_CAN_REC_MODE2; | 853 | driver->features = LIRC_CAN_REC_MODE2; |
862 | driver->data = context; | 854 | driver->data = context; |
diff --git a/drivers/staging/lirc/lirc_serial.c b/drivers/staging/lirc/lirc_serial.c index 4a3cca03224a..805df913bb6e 100644 --- a/drivers/staging/lirc/lirc_serial.c +++ b/drivers/staging/lirc/lirc_serial.c | |||
@@ -838,7 +838,23 @@ static int hardware_init_port(void) | |||
838 | 838 | ||
839 | static int init_port(void) | 839 | static int init_port(void) |
840 | { | 840 | { |
841 | int i, nlow, nhigh; | 841 | int i, nlow, nhigh, result; |
842 | |||
843 | result = request_irq(irq, irq_handler, | ||
844 | IRQF_DISABLED | (share_irq ? IRQF_SHARED : 0), | ||
845 | LIRC_DRIVER_NAME, (void *)&hardware); | ||
846 | |||
847 | switch (result) { | ||
848 | case -EBUSY: | ||
849 | printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq); | ||
850 | return -EBUSY; | ||
851 | case -EINVAL: | ||
852 | printk(KERN_ERR LIRC_DRIVER_NAME | ||
853 | ": Bad irq number or handler\n"); | ||
854 | return -EINVAL; | ||
855 | default: | ||
856 | break; | ||
857 | }; | ||
842 | 858 | ||
843 | /* Reserve io region. */ | 859 | /* Reserve io region. */ |
844 | /* | 860 | /* |
@@ -893,34 +909,17 @@ static int init_port(void) | |||
893 | printk(KERN_INFO LIRC_DRIVER_NAME ": Manually using active " | 909 | printk(KERN_INFO LIRC_DRIVER_NAME ": Manually using active " |
894 | "%s receiver\n", sense ? "low" : "high"); | 910 | "%s receiver\n", sense ? "low" : "high"); |
895 | 911 | ||
912 | dprintk("Interrupt %d, port %04x obtained\n", irq, io); | ||
896 | return 0; | 913 | return 0; |
897 | } | 914 | } |
898 | 915 | ||
899 | static int set_use_inc(void *data) | 916 | static int set_use_inc(void *data) |
900 | { | 917 | { |
901 | int result; | ||
902 | unsigned long flags; | 918 | unsigned long flags; |
903 | 919 | ||
904 | /* initialize timestamp */ | 920 | /* initialize timestamp */ |
905 | do_gettimeofday(&lasttv); | 921 | do_gettimeofday(&lasttv); |
906 | 922 | ||
907 | result = request_irq(irq, irq_handler, | ||
908 | IRQF_DISABLED | (share_irq ? IRQF_SHARED : 0), | ||
909 | LIRC_DRIVER_NAME, (void *)&hardware); | ||
910 | |||
911 | switch (result) { | ||
912 | case -EBUSY: | ||
913 | printk(KERN_ERR LIRC_DRIVER_NAME ": IRQ %d busy\n", irq); | ||
914 | return -EBUSY; | ||
915 | case -EINVAL: | ||
916 | printk(KERN_ERR LIRC_DRIVER_NAME | ||
917 | ": Bad irq number or handler\n"); | ||
918 | return -EINVAL; | ||
919 | default: | ||
920 | dprintk("Interrupt %d, port %04x obtained\n", irq, io); | ||
921 | break; | ||
922 | } | ||
923 | |||
924 | spin_lock_irqsave(&hardware[type].lock, flags); | 923 | spin_lock_irqsave(&hardware[type].lock, flags); |
925 | 924 | ||
926 | /* Set DLAB 0. */ | 925 | /* Set DLAB 0. */ |
@@ -945,10 +944,6 @@ static void set_use_dec(void *data) | |||
945 | soutp(UART_IER, sinp(UART_IER) & | 944 | soutp(UART_IER, sinp(UART_IER) & |
946 | (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); | 945 | (~(UART_IER_MSI|UART_IER_RLSI|UART_IER_THRI|UART_IER_RDI))); |
947 | spin_unlock_irqrestore(&hardware[type].lock, flags); | 946 | spin_unlock_irqrestore(&hardware[type].lock, flags); |
948 | |||
949 | free_irq(irq, (void *)&hardware); | ||
950 | |||
951 | dprintk("freed IRQ %d\n", irq); | ||
952 | } | 947 | } |
953 | 948 | ||
954 | static ssize_t lirc_write(struct file *file, const char *buf, | 949 | static ssize_t lirc_write(struct file *file, const char *buf, |
@@ -1256,6 +1251,9 @@ exit_serial_exit: | |||
1256 | static void __exit lirc_serial_exit_module(void) | 1251 | static void __exit lirc_serial_exit_module(void) |
1257 | { | 1252 | { |
1258 | lirc_serial_exit(); | 1253 | lirc_serial_exit(); |
1254 | |||
1255 | free_irq(irq, (void *)&hardware); | ||
1256 | |||
1259 | if (iommap != 0) | 1257 | if (iommap != 0) |
1260 | release_mem_region(iommap, 8 << ioshift); | 1258 | release_mem_region(iommap, 8 << ioshift); |
1261 | else | 1259 | else |
diff --git a/drivers/staging/lirc/lirc_sir.c b/drivers/staging/lirc/lirc_sir.c index a7b46f24f24e..0d3864594b12 100644 --- a/drivers/staging/lirc/lirc_sir.c +++ b/drivers/staging/lirc/lirc_sir.c | |||
@@ -739,23 +739,16 @@ static void send_space(unsigned long len) | |||
739 | static void send_pulse(unsigned long len) | 739 | static void send_pulse(unsigned long len) |
740 | { | 740 | { |
741 | long bytes_out = len / TIME_CONST; | 741 | long bytes_out = len / TIME_CONST; |
742 | long time_left; | ||
743 | 742 | ||
744 | time_left = (long)len - (long)bytes_out * (long)TIME_CONST; | 743 | if (bytes_out == 0) |
745 | if (bytes_out == 0) { | ||
746 | bytes_out++; | 744 | bytes_out++; |
747 | time_left = 0; | 745 | |
748 | } | ||
749 | while (bytes_out--) { | 746 | while (bytes_out--) { |
750 | outb(PULSE, io + UART_TX); | 747 | outb(PULSE, io + UART_TX); |
751 | /* FIXME treba seriozne cakanie z char/serial.c */ | 748 | /* FIXME treba seriozne cakanie z char/serial.c */ |
752 | while (!(inb(io + UART_LSR) & UART_LSR_THRE)) | 749 | while (!(inb(io + UART_LSR) & UART_LSR_THRE)) |
753 | ; | 750 | ; |
754 | } | 751 | } |
755 | #if 0 | ||
756 | if (time_left > 0) | ||
757 | safe_udelay(time_left); | ||
758 | #endif | ||
759 | } | 752 | } |
760 | #endif | 753 | #endif |
761 | 754 | ||
diff --git a/drivers/staging/lirc/lirc_zilog.c b/drivers/staging/lirc/lirc_zilog.c index dd6a57c3c3a3..4e051f6b52db 100644 --- a/drivers/staging/lirc/lirc_zilog.c +++ b/drivers/staging/lirc/lirc_zilog.c | |||
@@ -475,14 +475,14 @@ static int lirc_thread(void *arg) | |||
475 | dprintk("poll thread started\n"); | 475 | dprintk("poll thread started\n"); |
476 | 476 | ||
477 | while (!kthread_should_stop()) { | 477 | while (!kthread_should_stop()) { |
478 | set_current_state(TASK_INTERRUPTIBLE); | ||
479 | |||
478 | /* if device not opened, we can sleep half a second */ | 480 | /* if device not opened, we can sleep half a second */ |
479 | if (atomic_read(&ir->open_count) == 0) { | 481 | if (atomic_read(&ir->open_count) == 0) { |
480 | schedule_timeout(HZ/2); | 482 | schedule_timeout(HZ/2); |
481 | continue; | 483 | continue; |
482 | } | 484 | } |
483 | 485 | ||
484 | set_current_state(TASK_INTERRUPTIBLE); | ||
485 | |||
486 | /* | 486 | /* |
487 | * This is ~113*2 + 24 + jitter (2*repeat gap + code length). | 487 | * This is ~113*2 + 24 + jitter (2*repeat gap + code length). |
488 | * We use this interval as the chip resets every time you poll | 488 | * We use this interval as the chip resets every time you poll |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 64c7ab4702df..0b5ec234c787 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1147,6 +1147,14 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) | |||
1147 | * any drivers bound to them (a key side effect) | 1147 | * any drivers bound to them (a key side effect) |
1148 | */ | 1148 | */ |
1149 | if (dev->actconfig) { | 1149 | if (dev->actconfig) { |
1150 | /* | ||
1151 | * FIXME: In order to avoid self-deadlock involving the | ||
1152 | * bandwidth_mutex, we have to mark all the interfaces | ||
1153 | * before unregistering any of them. | ||
1154 | */ | ||
1155 | for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) | ||
1156 | dev->actconfig->interface[i]->unregistering = 1; | ||
1157 | |||
1150 | for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { | 1158 | for (i = 0; i < dev->actconfig->desc.bNumInterfaces; i++) { |
1151 | struct usb_interface *interface; | 1159 | struct usb_interface *interface; |
1152 | 1160 | ||
@@ -1156,7 +1164,6 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) | |||
1156 | continue; | 1164 | continue; |
1157 | dev_dbg(&dev->dev, "unregistering interface %s\n", | 1165 | dev_dbg(&dev->dev, "unregistering interface %s\n", |
1158 | dev_name(&interface->dev)); | 1166 | dev_name(&interface->dev)); |
1159 | interface->unregistering = 1; | ||
1160 | remove_intf_ep_devs(interface); | 1167 | remove_intf_ep_devs(interface); |
1161 | device_del(&interface->dev); | 1168 | device_del(&interface->dev); |
1162 | } | 1169 | } |
@@ -1286,6 +1293,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) | |||
1286 | interface); | 1293 | interface); |
1287 | return -EINVAL; | 1294 | return -EINVAL; |
1288 | } | 1295 | } |
1296 | if (iface->unregistering) | ||
1297 | return -ENODEV; | ||
1289 | 1298 | ||
1290 | alt = usb_altnum_to_altsetting(iface, alternate); | 1299 | alt = usb_altnum_to_altsetting(iface, alternate); |
1291 | if (!alt) { | 1300 | if (!alt) { |
diff --git a/drivers/usb/gadget/fsl_udc_core.c b/drivers/usb/gadget/fsl_udc_core.c index 2cd9a60c7f3a..4e4833168087 100644 --- a/drivers/usb/gadget/fsl_udc_core.c +++ b/drivers/usb/gadget/fsl_udc_core.c | |||
@@ -46,7 +46,6 @@ | |||
46 | #include <asm/system.h> | 46 | #include <asm/system.h> |
47 | #include <asm/unaligned.h> | 47 | #include <asm/unaligned.h> |
48 | #include <asm/dma.h> | 48 | #include <asm/dma.h> |
49 | #include <asm/cacheflush.h> | ||
50 | 49 | ||
51 | #include "fsl_usb2_udc.h" | 50 | #include "fsl_usb2_udc.h" |
52 | 51 | ||
@@ -118,6 +117,17 @@ static void (*_fsl_writel)(u32 v, unsigned __iomem *p); | |||
118 | #define fsl_readl(p) (*_fsl_readl)((p)) | 117 | #define fsl_readl(p) (*_fsl_readl)((p)) |
119 | #define fsl_writel(v, p) (*_fsl_writel)((v), (p)) | 118 | #define fsl_writel(v, p) (*_fsl_writel)((v), (p)) |
120 | 119 | ||
120 | static inline void fsl_set_accessors(struct fsl_usb2_platform_data *pdata) | ||
121 | { | ||
122 | if (pdata->big_endian_mmio) { | ||
123 | _fsl_readl = _fsl_readl_be; | ||
124 | _fsl_writel = _fsl_writel_be; | ||
125 | } else { | ||
126 | _fsl_readl = _fsl_readl_le; | ||
127 | _fsl_writel = _fsl_writel_le; | ||
128 | } | ||
129 | } | ||
130 | |||
121 | static inline u32 cpu_to_hc32(const u32 x) | 131 | static inline u32 cpu_to_hc32(const u32 x) |
122 | { | 132 | { |
123 | return udc_controller->pdata->big_endian_desc | 133 | return udc_controller->pdata->big_endian_desc |
@@ -132,6 +142,8 @@ static inline u32 hc32_to_cpu(const u32 x) | |||
132 | : le32_to_cpu((__force __le32)x); | 142 | : le32_to_cpu((__force __le32)x); |
133 | } | 143 | } |
134 | #else /* !CONFIG_PPC32 */ | 144 | #else /* !CONFIG_PPC32 */ |
145 | static inline void fsl_set_accessors(struct fsl_usb2_platform_data *pdata) {} | ||
146 | |||
135 | #define fsl_readl(addr) readl(addr) | 147 | #define fsl_readl(addr) readl(addr) |
136 | #define fsl_writel(val32, addr) writel(val32, addr) | 148 | #define fsl_writel(val32, addr) writel(val32, addr) |
137 | #define cpu_to_hc32(x) cpu_to_le32(x) | 149 | #define cpu_to_hc32(x) cpu_to_le32(x) |
@@ -1277,6 +1289,11 @@ static int ep0_prime_status(struct fsl_udc *udc, int direction) | |||
1277 | req->req.complete = NULL; | 1289 | req->req.complete = NULL; |
1278 | req->dtd_count = 0; | 1290 | req->dtd_count = 0; |
1279 | 1291 | ||
1292 | req->req.dma = dma_map_single(ep->udc->gadget.dev.parent, | ||
1293 | req->req.buf, req->req.length, | ||
1294 | ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
1295 | req->mapped = 1; | ||
1296 | |||
1280 | if (fsl_req_to_dtd(req) == 0) | 1297 | if (fsl_req_to_dtd(req) == 0) |
1281 | fsl_queue_td(ep, req); | 1298 | fsl_queue_td(ep, req); |
1282 | else | 1299 | else |
@@ -1348,9 +1365,6 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value, | |||
1348 | /* Fill in the reqest structure */ | 1365 | /* Fill in the reqest structure */ |
1349 | *((u16 *) req->req.buf) = cpu_to_le16(tmp); | 1366 | *((u16 *) req->req.buf) = cpu_to_le16(tmp); |
1350 | 1367 | ||
1351 | /* flush cache for the req buffer */ | ||
1352 | flush_dcache_range((u32)req->req.buf, (u32)req->req.buf + 8); | ||
1353 | |||
1354 | req->ep = ep; | 1368 | req->ep = ep; |
1355 | req->req.length = 2; | 1369 | req->req.length = 2; |
1356 | req->req.status = -EINPROGRESS; | 1370 | req->req.status = -EINPROGRESS; |
@@ -1358,6 +1372,11 @@ static void ch9getstatus(struct fsl_udc *udc, u8 request_type, u16 value, | |||
1358 | req->req.complete = NULL; | 1372 | req->req.complete = NULL; |
1359 | req->dtd_count = 0; | 1373 | req->dtd_count = 0; |
1360 | 1374 | ||
1375 | req->req.dma = dma_map_single(ep->udc->gadget.dev.parent, | ||
1376 | req->req.buf, req->req.length, | ||
1377 | ep_is_in(ep) ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
1378 | req->mapped = 1; | ||
1379 | |||
1361 | /* prime the data phase */ | 1380 | /* prime the data phase */ |
1362 | if ((fsl_req_to_dtd(req) == 0)) | 1381 | if ((fsl_req_to_dtd(req) == 0)) |
1363 | fsl_queue_td(ep, req); | 1382 | fsl_queue_td(ep, req); |
@@ -2354,7 +2373,6 @@ static int __init struct_udc_setup(struct fsl_udc *udc, | |||
2354 | struct fsl_req, req); | 2373 | struct fsl_req, req); |
2355 | /* allocate a small amount of memory to get valid address */ | 2374 | /* allocate a small amount of memory to get valid address */ |
2356 | udc->status_req->req.buf = kmalloc(8, GFP_KERNEL); | 2375 | udc->status_req->req.buf = kmalloc(8, GFP_KERNEL); |
2357 | udc->status_req->req.dma = virt_to_phys(udc->status_req->req.buf); | ||
2358 | 2376 | ||
2359 | udc->resume_state = USB_STATE_NOTATTACHED; | 2377 | udc->resume_state = USB_STATE_NOTATTACHED; |
2360 | udc->usb_state = USB_STATE_POWERED; | 2378 | udc->usb_state = USB_STATE_POWERED; |
@@ -2470,13 +2488,7 @@ static int __init fsl_udc_probe(struct platform_device *pdev) | |||
2470 | } | 2488 | } |
2471 | 2489 | ||
2472 | /* Set accessors only after pdata->init() ! */ | 2490 | /* Set accessors only after pdata->init() ! */ |
2473 | if (pdata->big_endian_mmio) { | 2491 | fsl_set_accessors(pdata); |
2474 | _fsl_readl = _fsl_readl_be; | ||
2475 | _fsl_writel = _fsl_writel_be; | ||
2476 | } else { | ||
2477 | _fsl_readl = _fsl_readl_le; | ||
2478 | _fsl_writel = _fsl_writel_le; | ||
2479 | } | ||
2480 | 2492 | ||
2481 | #ifndef CONFIG_ARCH_MXC | 2493 | #ifndef CONFIG_ARCH_MXC |
2482 | if (pdata->have_sysif_regs) | 2494 | if (pdata->have_sysif_regs) |
diff --git a/drivers/w1/masters/ds1wm.c b/drivers/w1/masters/ds1wm.c index ad57593d224a..a0c8965c1a79 100644 --- a/drivers/w1/masters/ds1wm.c +++ b/drivers/w1/masters/ds1wm.c | |||
@@ -109,6 +109,7 @@ struct ds1wm_data { | |||
109 | /* byte to write that makes all intr disabled, */ | 109 | /* byte to write that makes all intr disabled, */ |
110 | /* considering active_state (IAS) (optimization) */ | 110 | /* considering active_state (IAS) (optimization) */ |
111 | u8 int_en_reg_none; | 111 | u8 int_en_reg_none; |
112 | unsigned int reset_recover_delay; /* see ds1wm.h */ | ||
112 | }; | 113 | }; |
113 | 114 | ||
114 | static inline void ds1wm_write_register(struct ds1wm_data *ds1wm_data, u32 reg, | 115 | static inline void ds1wm_write_register(struct ds1wm_data *ds1wm_data, u32 reg, |
@@ -187,6 +188,9 @@ static int ds1wm_reset(struct ds1wm_data *ds1wm_data) | |||
187 | return 1; | 188 | return 1; |
188 | } | 189 | } |
189 | 190 | ||
191 | if (ds1wm_data->reset_recover_delay) | ||
192 | msleep(ds1wm_data->reset_recover_delay); | ||
193 | |||
190 | return 0; | 194 | return 0; |
191 | } | 195 | } |
192 | 196 | ||
@@ -490,6 +494,7 @@ static int ds1wm_probe(struct platform_device *pdev) | |||
490 | } | 494 | } |
491 | ds1wm_data->irq = res->start; | 495 | ds1wm_data->irq = res->start; |
492 | ds1wm_data->int_en_reg_none = (plat->active_high ? DS1WM_INTEN_IAS : 0); | 496 | ds1wm_data->int_en_reg_none = (plat->active_high ? DS1WM_INTEN_IAS : 0); |
497 | ds1wm_data->reset_recover_delay = plat->reset_recover_delay; | ||
493 | 498 | ||
494 | if (res->flags & IORESOURCE_IRQ_HIGHEDGE) | 499 | if (res->flags & IORESOURCE_IRQ_HIGHEDGE) |
495 | irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_RISING); | 500 | irq_set_irq_type(ds1wm_data->irq, IRQ_TYPE_EDGE_RISING); |
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 9536d386bb38..21d816e9dfa5 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig | |||
@@ -599,8 +599,7 @@ config IT87_WDT | |||
599 | 599 | ||
600 | config HP_WATCHDOG | 600 | config HP_WATCHDOG |
601 | tristate "HP ProLiant iLO2+ Hardware Watchdog Timer" | 601 | tristate "HP ProLiant iLO2+ Hardware Watchdog Timer" |
602 | depends on X86 | 602 | depends on X86 && PCI |
603 | default m | ||
604 | help | 603 | help |
605 | A software monitoring watchdog and NMI sourcing driver. This driver | 604 | A software monitoring watchdog and NMI sourcing driver. This driver |
606 | will detect lockups and provide a stack trace. This is a driver that | 605 | will detect lockups and provide a stack trace. This is a driver that |
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 63039ed9576f..2bc5dc644b4c 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -1864,6 +1864,7 @@ cleanup: | |||
1864 | kfree(psinfo); | 1864 | kfree(psinfo); |
1865 | kfree(notes); | 1865 | kfree(notes); |
1866 | kfree(fpu); | 1866 | kfree(fpu); |
1867 | kfree(shdr4extnum); | ||
1867 | #ifdef ELF_CORE_COPY_XFPREGS | 1868 | #ifdef ELF_CORE_COPY_XFPREGS |
1868 | kfree(xfpu); | 1869 | kfree(xfpu); |
1869 | #endif | 1870 | #endif |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index f30ac05dbda7..3b859a3e6a0e 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -1335,6 +1335,11 @@ struct btrfs_ioctl_defrag_range_args { | |||
1335 | */ | 1335 | */ |
1336 | #define BTRFS_STRING_ITEM_KEY 253 | 1336 | #define BTRFS_STRING_ITEM_KEY 253 |
1337 | 1337 | ||
1338 | /* | ||
1339 | * Flags for mount options. | ||
1340 | * | ||
1341 | * Note: don't forget to add new options to btrfs_show_options() | ||
1342 | */ | ||
1338 | #define BTRFS_MOUNT_NODATASUM (1 << 0) | 1343 | #define BTRFS_MOUNT_NODATASUM (1 << 0) |
1339 | #define BTRFS_MOUNT_NODATACOW (1 << 1) | 1344 | #define BTRFS_MOUNT_NODATACOW (1 << 1) |
1340 | #define BTRFS_MOUNT_NOBARRIER (1 << 2) | 1345 | #define BTRFS_MOUNT_NOBARRIER (1 << 2) |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index d340f63d8f07..3601f0aebddf 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -2678,12 +2678,14 @@ noinline int btrfs_update_inode(struct btrfs_trans_handle *trans, | |||
2678 | int ret; | 2678 | int ret; |
2679 | 2679 | ||
2680 | /* | 2680 | /* |
2681 | * If root is tree root, it means this inode is used to | 2681 | * If the inode is a free space inode, we can deadlock during commit |
2682 | * store free space information. And these inodes are updated | 2682 | * if we put it into the delayed code. |
2683 | * when committing the transaction, so they needn't delaye to | 2683 | * |
2684 | * be updated, or deadlock will occured. | 2684 | * The data relocation inode should also be directly updated |
2685 | * without delay | ||
2685 | */ | 2686 | */ |
2686 | if (!is_free_space_inode(root, inode)) { | 2687 | if (!is_free_space_inode(root, inode) |
2688 | && root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID) { | ||
2687 | ret = btrfs_delayed_update_inode(trans, root, inode); | 2689 | ret = btrfs_delayed_update_inode(trans, root, inode); |
2688 | if (!ret) | 2690 | if (!ret) |
2689 | btrfs_set_inode_last_trans(trans, inode); | 2691 | btrfs_set_inode_last_trans(trans, inode); |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 0bb4ebbb71b7..15634d4648d7 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -723,6 +723,12 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
723 | seq_puts(seq, ",clear_cache"); | 723 | seq_puts(seq, ",clear_cache"); |
724 | if (btrfs_test_opt(root, USER_SUBVOL_RM_ALLOWED)) | 724 | if (btrfs_test_opt(root, USER_SUBVOL_RM_ALLOWED)) |
725 | seq_puts(seq, ",user_subvol_rm_allowed"); | 725 | seq_puts(seq, ",user_subvol_rm_allowed"); |
726 | if (btrfs_test_opt(root, ENOSPC_DEBUG)) | ||
727 | seq_puts(seq, ",enospc_debug"); | ||
728 | if (btrfs_test_opt(root, AUTO_DEFRAG)) | ||
729 | seq_puts(seq, ",autodefrag"); | ||
730 | if (btrfs_test_opt(root, INODE_MAP_CACHE)) | ||
731 | seq_puts(seq, ",inode_cache"); | ||
726 | return 0; | 732 | return 0; |
727 | } | 733 | } |
728 | 734 | ||
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 1efa56e18f9b..19450bc53632 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -2098,7 +2098,8 @@ int btrfs_balance(struct btrfs_root *dev_root) | |||
2098 | chunk_root->root_key.objectid, | 2098 | chunk_root->root_key.objectid, |
2099 | found_key.objectid, | 2099 | found_key.objectid, |
2100 | found_key.offset); | 2100 | found_key.offset); |
2101 | BUG_ON(ret && ret != -ENOSPC); | 2101 | if (ret && ret != -ENOSPC) |
2102 | goto error; | ||
2102 | key.offset = found_key.offset - 1; | 2103 | key.offset = found_key.offset - 1; |
2103 | } | 2104 | } |
2104 | ret = 0; | 2105 | ret = 0; |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 9542f07d0b93..4698a5c553dc 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -290,7 +290,6 @@ static int striped_read(struct inode *inode, | |||
290 | struct ceph_inode_info *ci = ceph_inode(inode); | 290 | struct ceph_inode_info *ci = ceph_inode(inode); |
291 | u64 pos, this_len; | 291 | u64 pos, this_len; |
292 | int io_align, page_align; | 292 | int io_align, page_align; |
293 | int page_off = off & ~PAGE_CACHE_MASK; /* first byte's offset in page */ | ||
294 | int left, pages_left; | 293 | int left, pages_left; |
295 | int read; | 294 | int read; |
296 | struct page **page_pos; | 295 | struct page **page_pos; |
@@ -326,12 +325,11 @@ more: | |||
326 | ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : ""); | 325 | ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : ""); |
327 | 326 | ||
328 | if (ret > 0) { | 327 | if (ret > 0) { |
329 | int didpages = | 328 | int didpages = (page_align + ret) >> PAGE_CACHE_SHIFT; |
330 | ((pos & ~PAGE_CACHE_MASK) + ret) >> PAGE_CACHE_SHIFT; | ||
331 | 329 | ||
332 | if (read < pos - off) { | 330 | if (read < pos - off) { |
333 | dout(" zero gap %llu to %llu\n", off + read, pos); | 331 | dout(" zero gap %llu to %llu\n", off + read, pos); |
334 | ceph_zero_page_vector_range(page_off + read, | 332 | ceph_zero_page_vector_range(page_align + read, |
335 | pos - off - read, pages); | 333 | pos - off - read, pages); |
336 | } | 334 | } |
337 | pos += ret; | 335 | pos += ret; |
@@ -356,7 +354,7 @@ more: | |||
356 | left = inode->i_size - pos; | 354 | left = inode->i_size - pos; |
357 | 355 | ||
358 | dout("zero tail %d\n", left); | 356 | dout("zero tail %d\n", left); |
359 | ceph_zero_page_vector_range(page_off + read, left, | 357 | ceph_zero_page_vector_range(page_align + read, left, |
360 | pages); | 358 | pages); |
361 | read += left; | 359 | read += left; |
362 | } | 360 | } |
@@ -478,9 +476,6 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data, | |||
478 | else | 476 | else |
479 | pos = *offset; | 477 | pos = *offset; |
480 | 478 | ||
481 | io_align = pos & ~PAGE_MASK; | ||
482 | buf_align = (unsigned long)data & ~PAGE_MASK; | ||
483 | |||
484 | ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + left); | 479 | ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + left); |
485 | if (ret < 0) | 480 | if (ret < 0) |
486 | return ret; | 481 | return ret; |
@@ -504,6 +499,8 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data, | |||
504 | * boundary. this isn't atomic, unfortunately. :( | 499 | * boundary. this isn't atomic, unfortunately. :( |
505 | */ | 500 | */ |
506 | more: | 501 | more: |
502 | io_align = pos & ~PAGE_MASK; | ||
503 | buf_align = (unsigned long)data & ~PAGE_MASK; | ||
507 | len = left; | 504 | len = left; |
508 | if (file->f_flags & O_DIRECT) { | 505 | if (file->f_flags & O_DIRECT) { |
509 | /* write from beginning of first page, regardless of | 506 | /* write from beginning of first page, regardless of |
@@ -593,6 +590,7 @@ out: | |||
593 | pos += len; | 590 | pos += len; |
594 | written += len; | 591 | written += len; |
595 | left -= len; | 592 | left -= len; |
593 | data += written; | ||
596 | if (left) | 594 | if (left) |
597 | goto more; | 595 | goto more; |
598 | 596 | ||
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 79743d146be6..0c1d91756528 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -1438,12 +1438,15 @@ char *ceph_mdsc_build_path(struct dentry *dentry, int *plen, u64 *base, | |||
1438 | struct dentry *temp; | 1438 | struct dentry *temp; |
1439 | char *path; | 1439 | char *path; |
1440 | int len, pos; | 1440 | int len, pos; |
1441 | unsigned seq; | ||
1441 | 1442 | ||
1442 | if (dentry == NULL) | 1443 | if (dentry == NULL) |
1443 | return ERR_PTR(-EINVAL); | 1444 | return ERR_PTR(-EINVAL); |
1444 | 1445 | ||
1445 | retry: | 1446 | retry: |
1446 | len = 0; | 1447 | len = 0; |
1448 | seq = read_seqbegin(&rename_lock); | ||
1449 | rcu_read_lock(); | ||
1447 | for (temp = dentry; !IS_ROOT(temp);) { | 1450 | for (temp = dentry; !IS_ROOT(temp);) { |
1448 | struct inode *inode = temp->d_inode; | 1451 | struct inode *inode = temp->d_inode; |
1449 | if (inode && ceph_snap(inode) == CEPH_SNAPDIR) | 1452 | if (inode && ceph_snap(inode) == CEPH_SNAPDIR) |
@@ -1455,10 +1458,12 @@ retry: | |||
1455 | len += 1 + temp->d_name.len; | 1458 | len += 1 + temp->d_name.len; |
1456 | temp = temp->d_parent; | 1459 | temp = temp->d_parent; |
1457 | if (temp == NULL) { | 1460 | if (temp == NULL) { |
1461 | rcu_read_unlock(); | ||
1458 | pr_err("build_path corrupt dentry %p\n", dentry); | 1462 | pr_err("build_path corrupt dentry %p\n", dentry); |
1459 | return ERR_PTR(-EINVAL); | 1463 | return ERR_PTR(-EINVAL); |
1460 | } | 1464 | } |
1461 | } | 1465 | } |
1466 | rcu_read_unlock(); | ||
1462 | if (len) | 1467 | if (len) |
1463 | len--; /* no leading '/' */ | 1468 | len--; /* no leading '/' */ |
1464 | 1469 | ||
@@ -1467,9 +1472,12 @@ retry: | |||
1467 | return ERR_PTR(-ENOMEM); | 1472 | return ERR_PTR(-ENOMEM); |
1468 | pos = len; | 1473 | pos = len; |
1469 | path[pos] = 0; /* trailing null */ | 1474 | path[pos] = 0; /* trailing null */ |
1475 | rcu_read_lock(); | ||
1470 | for (temp = dentry; !IS_ROOT(temp) && pos != 0; ) { | 1476 | for (temp = dentry; !IS_ROOT(temp) && pos != 0; ) { |
1471 | struct inode *inode = temp->d_inode; | 1477 | struct inode *inode; |
1472 | 1478 | ||
1479 | spin_lock(&temp->d_lock); | ||
1480 | inode = temp->d_inode; | ||
1473 | if (inode && ceph_snap(inode) == CEPH_SNAPDIR) { | 1481 | if (inode && ceph_snap(inode) == CEPH_SNAPDIR) { |
1474 | dout("build_path path+%d: %p SNAPDIR\n", | 1482 | dout("build_path path+%d: %p SNAPDIR\n", |
1475 | pos, temp); | 1483 | pos, temp); |
@@ -1478,21 +1486,26 @@ retry: | |||
1478 | break; | 1486 | break; |
1479 | } else { | 1487 | } else { |
1480 | pos -= temp->d_name.len; | 1488 | pos -= temp->d_name.len; |
1481 | if (pos < 0) | 1489 | if (pos < 0) { |
1490 | spin_unlock(&temp->d_lock); | ||
1482 | break; | 1491 | break; |
1492 | } | ||
1483 | strncpy(path + pos, temp->d_name.name, | 1493 | strncpy(path + pos, temp->d_name.name, |
1484 | temp->d_name.len); | 1494 | temp->d_name.len); |
1485 | } | 1495 | } |
1496 | spin_unlock(&temp->d_lock); | ||
1486 | if (pos) | 1497 | if (pos) |
1487 | path[--pos] = '/'; | 1498 | path[--pos] = '/'; |
1488 | temp = temp->d_parent; | 1499 | temp = temp->d_parent; |
1489 | if (temp == NULL) { | 1500 | if (temp == NULL) { |
1501 | rcu_read_unlock(); | ||
1490 | pr_err("build_path corrupt dentry\n"); | 1502 | pr_err("build_path corrupt dentry\n"); |
1491 | kfree(path); | 1503 | kfree(path); |
1492 | return ERR_PTR(-EINVAL); | 1504 | return ERR_PTR(-EINVAL); |
1493 | } | 1505 | } |
1494 | } | 1506 | } |
1495 | if (pos != 0) { | 1507 | rcu_read_unlock(); |
1508 | if (pos != 0 || read_seqretry(&rename_lock, seq)) { | ||
1496 | pr_err("build_path did not end path lookup where " | 1509 | pr_err("build_path did not end path lookup where " |
1497 | "expected, namelen is %d, pos is %d\n", len, pos); | 1510 | "expected, namelen is %d, pos is %d\n", len, pos); |
1498 | /* presumably this is only possible if racing with a | 1511 | /* presumably this is only possible if racing with a |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 35f9154615fa..bc4b12ca537b 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
36 | #include <linux/kthread.h> | 36 | #include <linux/kthread.h> |
37 | #include <linux/freezer.h> | 37 | #include <linux/freezer.h> |
38 | #include <linux/namei.h> | ||
38 | #include <net/ipv6.h> | 39 | #include <net/ipv6.h> |
39 | #include "cifsfs.h" | 40 | #include "cifsfs.h" |
40 | #include "cifspdu.h" | 41 | #include "cifspdu.h" |
@@ -542,14 +543,12 @@ static const struct super_operations cifs_super_ops = { | |||
542 | static struct dentry * | 543 | static struct dentry * |
543 | cifs_get_root(struct smb_vol *vol, struct super_block *sb) | 544 | cifs_get_root(struct smb_vol *vol, struct super_block *sb) |
544 | { | 545 | { |
545 | int xid, rc; | 546 | struct dentry *dentry; |
546 | struct inode *inode; | ||
547 | struct qstr name; | ||
548 | struct dentry *dparent = NULL, *dchild = NULL, *alias; | ||
549 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); | 547 | struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
550 | unsigned int i, full_len, len; | 548 | char *full_path = NULL; |
551 | char *full_path = NULL, *pstart; | 549 | char *s, *p; |
552 | char sep; | 550 | char sep; |
551 | int xid; | ||
553 | 552 | ||
554 | full_path = cifs_build_path_to_root(vol, cifs_sb, | 553 | full_path = cifs_build_path_to_root(vol, cifs_sb, |
555 | cifs_sb_master_tcon(cifs_sb)); | 554 | cifs_sb_master_tcon(cifs_sb)); |
@@ -560,73 +559,32 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) | |||
560 | 559 | ||
561 | xid = GetXid(); | 560 | xid = GetXid(); |
562 | sep = CIFS_DIR_SEP(cifs_sb); | 561 | sep = CIFS_DIR_SEP(cifs_sb); |
563 | dparent = dget(sb->s_root); | 562 | dentry = dget(sb->s_root); |
564 | full_len = strlen(full_path); | 563 | p = s = full_path; |
565 | full_path[full_len] = sep; | 564 | |
566 | pstart = full_path + 1; | 565 | do { |
567 | 566 | struct inode *dir = dentry->d_inode; | |
568 | for (i = 1, len = 0; i <= full_len; i++) { | 567 | struct dentry *child; |
569 | if (full_path[i] != sep || !len) { | 568 | |
570 | len++; | 569 | /* skip separators */ |
571 | continue; | 570 | while (*s == sep) |
572 | } | 571 | s++; |
573 | 572 | if (!*s) | |
574 | full_path[i] = 0; | 573 | break; |
575 | cFYI(1, "get dentry for %s", pstart); | 574 | p = s++; |
576 | 575 | /* next separator */ | |
577 | name.name = pstart; | 576 | while (*s && *s != sep) |
578 | name.len = len; | 577 | s++; |
579 | name.hash = full_name_hash(pstart, len); | 578 | |
580 | dchild = d_lookup(dparent, &name); | 579 | mutex_lock(&dir->i_mutex); |
581 | if (dchild == NULL) { | 580 | child = lookup_one_len(p, dentry, s - p); |
582 | cFYI(1, "not exists"); | 581 | mutex_unlock(&dir->i_mutex); |
583 | dchild = d_alloc(dparent, &name); | 582 | dput(dentry); |
584 | if (dchild == NULL) { | 583 | dentry = child; |
585 | dput(dparent); | 584 | } while (!IS_ERR(dentry)); |
586 | dparent = ERR_PTR(-ENOMEM); | ||
587 | goto out; | ||
588 | } | ||
589 | } | ||
590 | |||
591 | cFYI(1, "get inode"); | ||
592 | if (dchild->d_inode == NULL) { | ||
593 | cFYI(1, "not exists"); | ||
594 | inode = NULL; | ||
595 | if (cifs_sb_master_tcon(CIFS_SB(sb))->unix_ext) | ||
596 | rc = cifs_get_inode_info_unix(&inode, full_path, | ||
597 | sb, xid); | ||
598 | else | ||
599 | rc = cifs_get_inode_info(&inode, full_path, | ||
600 | NULL, sb, xid, NULL); | ||
601 | if (rc) { | ||
602 | dput(dchild); | ||
603 | dput(dparent); | ||
604 | dparent = ERR_PTR(rc); | ||
605 | goto out; | ||
606 | } | ||
607 | alias = d_materialise_unique(dchild, inode); | ||
608 | if (alias != NULL) { | ||
609 | dput(dchild); | ||
610 | if (IS_ERR(alias)) { | ||
611 | dput(dparent); | ||
612 | dparent = ERR_PTR(-EINVAL); /* XXX */ | ||
613 | goto out; | ||
614 | } | ||
615 | dchild = alias; | ||
616 | } | ||
617 | } | ||
618 | cFYI(1, "parent %p, child %p", dparent, dchild); | ||
619 | |||
620 | dput(dparent); | ||
621 | dparent = dchild; | ||
622 | len = 0; | ||
623 | pstart = full_path + i + 1; | ||
624 | full_path[i] = sep; | ||
625 | } | ||
626 | out: | ||
627 | _FreeXid(xid); | 585 | _FreeXid(xid); |
628 | kfree(full_path); | 586 | kfree(full_path); |
629 | return dparent; | 587 | return dentry; |
630 | } | 588 | } |
631 | 589 | ||
632 | static int cifs_set_super(struct super_block *sb, void *data) | 590 | static int cifs_set_super(struct super_block *sb, void *data) |
@@ -649,9 +607,9 @@ cifs_do_mount(struct file_system_type *fs_type, | |||
649 | 607 | ||
650 | cFYI(1, "Devname: %s flags: %d ", dev_name, flags); | 608 | cFYI(1, "Devname: %s flags: %d ", dev_name, flags); |
651 | 609 | ||
652 | rc = cifs_setup_volume_info(&volume_info, (char *)data, dev_name); | 610 | volume_info = cifs_get_volume_info((char *)data, dev_name); |
653 | if (rc) | 611 | if (IS_ERR(volume_info)) |
654 | return ERR_PTR(rc); | 612 | return ERR_CAST(volume_info); |
655 | 613 | ||
656 | cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL); | 614 | cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL); |
657 | if (cifs_sb == NULL) { | 615 | if (cifs_sb == NULL) { |
@@ -713,7 +671,7 @@ cifs_do_mount(struct file_system_type *fs_type, | |||
713 | out_super: | 671 | out_super: |
714 | deactivate_locked_super(sb); | 672 | deactivate_locked_super(sb); |
715 | out: | 673 | out: |
716 | cifs_cleanup_volume_info(&volume_info); | 674 | cifs_cleanup_volume_info(volume_info); |
717 | return root; | 675 | return root; |
718 | 676 | ||
719 | out_mountdata: | 677 | out_mountdata: |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 0900e1658c96..036ca83e5f46 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -129,5 +129,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); | |||
129 | extern const struct export_operations cifs_export_ops; | 129 | extern const struct export_operations cifs_export_ops; |
130 | #endif /* CIFS_NFSD_EXPORT */ | 130 | #endif /* CIFS_NFSD_EXPORT */ |
131 | 131 | ||
132 | #define CIFS_VERSION "1.73" | 132 | #define CIFS_VERSION "1.74" |
133 | #endif /* _CIFSFS_H */ | 133 | #endif /* _CIFSFS_H */ |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 257f312ede42..8df28e925e5b 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -154,9 +154,9 @@ extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *, | |||
154 | extern void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, | 154 | extern void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, |
155 | struct cifs_sb_info *cifs_sb); | 155 | struct cifs_sb_info *cifs_sb); |
156 | extern int cifs_match_super(struct super_block *, void *); | 156 | extern int cifs_match_super(struct super_block *, void *); |
157 | extern void cifs_cleanup_volume_info(struct smb_vol **pvolume_info); | 157 | extern void cifs_cleanup_volume_info(struct smb_vol *pvolume_info); |
158 | extern int cifs_setup_volume_info(struct smb_vol **pvolume_info, | 158 | extern struct smb_vol *cifs_get_volume_info(char *mount_data, |
159 | char *mount_data, const char *devname); | 159 | const char *devname); |
160 | extern int cifs_mount(struct cifs_sb_info *, struct smb_vol *); | 160 | extern int cifs_mount(struct cifs_sb_info *, struct smb_vol *); |
161 | extern void cifs_umount(struct cifs_sb_info *); | 161 | extern void cifs_umount(struct cifs_sb_info *); |
162 | extern void cifs_dfs_release_automount_timer(void); | 162 | extern void cifs_dfs_release_automount_timer(void); |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index c8cb83ef6f6f..ccc1afa0bf3b 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -65,6 +65,8 @@ static int ip_connect(struct TCP_Server_Info *server); | |||
65 | static int generic_ip_connect(struct TCP_Server_Info *server); | 65 | static int generic_ip_connect(struct TCP_Server_Info *server); |
66 | static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink); | 66 | static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink); |
67 | static void cifs_prune_tlinks(struct work_struct *work); | 67 | static void cifs_prune_tlinks(struct work_struct *work); |
68 | static int cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data, | ||
69 | const char *devname); | ||
68 | 70 | ||
69 | /* | 71 | /* |
70 | * cifs tcp session reconnection | 72 | * cifs tcp session reconnection |
@@ -2240,8 +2242,8 @@ cifs_match_super(struct super_block *sb, void *data) | |||
2240 | 2242 | ||
2241 | rc = compare_mount_options(sb, mnt_data); | 2243 | rc = compare_mount_options(sb, mnt_data); |
2242 | out: | 2244 | out: |
2243 | cifs_put_tlink(tlink); | ||
2244 | spin_unlock(&cifs_tcp_ses_lock); | 2245 | spin_unlock(&cifs_tcp_ses_lock); |
2246 | cifs_put_tlink(tlink); | ||
2245 | return rc; | 2247 | return rc; |
2246 | } | 2248 | } |
2247 | 2249 | ||
@@ -2830,15 +2832,9 @@ is_path_accessible(int xid, struct cifs_tcon *tcon, | |||
2830 | return rc; | 2832 | return rc; |
2831 | } | 2833 | } |
2832 | 2834 | ||
2833 | void | 2835 | static void |
2834 | cifs_cleanup_volume_info(struct smb_vol **pvolume_info) | 2836 | cleanup_volume_info_contents(struct smb_vol *volume_info) |
2835 | { | 2837 | { |
2836 | struct smb_vol *volume_info; | ||
2837 | |||
2838 | if (!pvolume_info || !*pvolume_info) | ||
2839 | return; | ||
2840 | |||
2841 | volume_info = *pvolume_info; | ||
2842 | kfree(volume_info->username); | 2838 | kfree(volume_info->username); |
2843 | kzfree(volume_info->password); | 2839 | kzfree(volume_info->password); |
2844 | kfree(volume_info->UNC); | 2840 | kfree(volume_info->UNC); |
@@ -2846,28 +2842,44 @@ cifs_cleanup_volume_info(struct smb_vol **pvolume_info) | |||
2846 | kfree(volume_info->domainname); | 2842 | kfree(volume_info->domainname); |
2847 | kfree(volume_info->iocharset); | 2843 | kfree(volume_info->iocharset); |
2848 | kfree(volume_info->prepath); | 2844 | kfree(volume_info->prepath); |
2845 | } | ||
2846 | |||
2847 | void | ||
2848 | cifs_cleanup_volume_info(struct smb_vol *volume_info) | ||
2849 | { | ||
2850 | if (!volume_info) | ||
2851 | return; | ||
2852 | cleanup_volume_info_contents(volume_info); | ||
2849 | kfree(volume_info); | 2853 | kfree(volume_info); |
2850 | *pvolume_info = NULL; | ||
2851 | return; | ||
2852 | } | 2854 | } |
2853 | 2855 | ||
2856 | |||
2854 | #ifdef CONFIG_CIFS_DFS_UPCALL | 2857 | #ifdef CONFIG_CIFS_DFS_UPCALL |
2855 | /* build_path_to_root returns full path to root when | 2858 | /* build_path_to_root returns full path to root when |
2856 | * we do not have an exiting connection (tcon) */ | 2859 | * we do not have an exiting connection (tcon) */ |
2857 | static char * | 2860 | static char * |
2858 | build_unc_path_to_root(const struct smb_vol *volume_info, | 2861 | build_unc_path_to_root(const struct smb_vol *vol, |
2859 | const struct cifs_sb_info *cifs_sb) | 2862 | const struct cifs_sb_info *cifs_sb) |
2860 | { | 2863 | { |
2861 | char *full_path; | 2864 | char *full_path, *pos; |
2865 | unsigned int pplen = vol->prepath ? strlen(vol->prepath) : 0; | ||
2866 | unsigned int unc_len = strnlen(vol->UNC, MAX_TREE_SIZE + 1); | ||
2862 | 2867 | ||
2863 | int unc_len = strnlen(volume_info->UNC, MAX_TREE_SIZE + 1); | 2868 | full_path = kmalloc(unc_len + pplen + 1, GFP_KERNEL); |
2864 | full_path = kmalloc(unc_len + 1, GFP_KERNEL); | ||
2865 | if (full_path == NULL) | 2869 | if (full_path == NULL) |
2866 | return ERR_PTR(-ENOMEM); | 2870 | return ERR_PTR(-ENOMEM); |
2867 | 2871 | ||
2868 | strncpy(full_path, volume_info->UNC, unc_len); | 2872 | strncpy(full_path, vol->UNC, unc_len); |
2869 | full_path[unc_len] = 0; /* add trailing null */ | 2873 | pos = full_path + unc_len; |
2874 | |||
2875 | if (pplen) { | ||
2876 | strncpy(pos, vol->prepath, pplen); | ||
2877 | pos += pplen; | ||
2878 | } | ||
2879 | |||
2880 | *pos = '\0'; /* add trailing null */ | ||
2870 | convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb)); | 2881 | convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb)); |
2882 | cFYI(1, "%s: full_path=%s", __func__, full_path); | ||
2871 | return full_path; | 2883 | return full_path; |
2872 | } | 2884 | } |
2873 | 2885 | ||
@@ -2910,15 +2922,18 @@ expand_dfs_referral(int xid, struct cifs_ses *pSesInfo, | |||
2910 | &fake_devname); | 2922 | &fake_devname); |
2911 | 2923 | ||
2912 | free_dfs_info_array(referrals, num_referrals); | 2924 | free_dfs_info_array(referrals, num_referrals); |
2913 | kfree(fake_devname); | ||
2914 | |||
2915 | if (cifs_sb->mountdata != NULL) | ||
2916 | kfree(cifs_sb->mountdata); | ||
2917 | 2925 | ||
2918 | if (IS_ERR(mdata)) { | 2926 | if (IS_ERR(mdata)) { |
2919 | rc = PTR_ERR(mdata); | 2927 | rc = PTR_ERR(mdata); |
2920 | mdata = NULL; | 2928 | mdata = NULL; |
2929 | } else { | ||
2930 | cleanup_volume_info_contents(volume_info); | ||
2931 | memset(volume_info, '\0', sizeof(*volume_info)); | ||
2932 | rc = cifs_setup_volume_info(volume_info, mdata, | ||
2933 | fake_devname); | ||
2921 | } | 2934 | } |
2935 | kfree(fake_devname); | ||
2936 | kfree(cifs_sb->mountdata); | ||
2922 | cifs_sb->mountdata = mdata; | 2937 | cifs_sb->mountdata = mdata; |
2923 | } | 2938 | } |
2924 | kfree(full_path); | 2939 | kfree(full_path); |
@@ -2926,33 +2941,20 @@ expand_dfs_referral(int xid, struct cifs_ses *pSesInfo, | |||
2926 | } | 2941 | } |
2927 | #endif | 2942 | #endif |
2928 | 2943 | ||
2929 | int cifs_setup_volume_info(struct smb_vol **pvolume_info, char *mount_data, | 2944 | static int |
2930 | const char *devname) | 2945 | cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data, |
2946 | const char *devname) | ||
2931 | { | 2947 | { |
2932 | struct smb_vol *volume_info; | ||
2933 | int rc = 0; | 2948 | int rc = 0; |
2934 | 2949 | ||
2935 | *pvolume_info = NULL; | 2950 | if (cifs_parse_mount_options(mount_data, devname, volume_info)) |
2936 | 2951 | return -EINVAL; | |
2937 | volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL); | ||
2938 | if (!volume_info) { | ||
2939 | rc = -ENOMEM; | ||
2940 | goto out; | ||
2941 | } | ||
2942 | |||
2943 | if (cifs_parse_mount_options(mount_data, devname, | ||
2944 | volume_info)) { | ||
2945 | rc = -EINVAL; | ||
2946 | goto out; | ||
2947 | } | ||
2948 | 2952 | ||
2949 | if (volume_info->nullauth) { | 2953 | if (volume_info->nullauth) { |
2950 | cFYI(1, "null user"); | 2954 | cFYI(1, "null user"); |
2951 | volume_info->username = kzalloc(1, GFP_KERNEL); | 2955 | volume_info->username = kzalloc(1, GFP_KERNEL); |
2952 | if (volume_info->username == NULL) { | 2956 | if (volume_info->username == NULL) |
2953 | rc = -ENOMEM; | 2957 | return -ENOMEM; |
2954 | goto out; | ||
2955 | } | ||
2956 | } else if (volume_info->username) { | 2958 | } else if (volume_info->username) { |
2957 | /* BB fixme parse for domain name here */ | 2959 | /* BB fixme parse for domain name here */ |
2958 | cFYI(1, "Username: %s", volume_info->username); | 2960 | cFYI(1, "Username: %s", volume_info->username); |
@@ -2960,8 +2962,7 @@ int cifs_setup_volume_info(struct smb_vol **pvolume_info, char *mount_data, | |||
2960 | cifserror("No username specified"); | 2962 | cifserror("No username specified"); |
2961 | /* In userspace mount helper we can get user name from alternate | 2963 | /* In userspace mount helper we can get user name from alternate |
2962 | locations such as env variables and files on disk */ | 2964 | locations such as env variables and files on disk */ |
2963 | rc = -EINVAL; | 2965 | return -EINVAL; |
2964 | goto out; | ||
2965 | } | 2966 | } |
2966 | 2967 | ||
2967 | /* this is needed for ASCII cp to Unicode converts */ | 2968 | /* this is needed for ASCII cp to Unicode converts */ |
@@ -2973,18 +2974,32 @@ int cifs_setup_volume_info(struct smb_vol **pvolume_info, char *mount_data, | |||
2973 | if (volume_info->local_nls == NULL) { | 2974 | if (volume_info->local_nls == NULL) { |
2974 | cERROR(1, "CIFS mount error: iocharset %s not found", | 2975 | cERROR(1, "CIFS mount error: iocharset %s not found", |
2975 | volume_info->iocharset); | 2976 | volume_info->iocharset); |
2976 | rc = -ELIBACC; | 2977 | return -ELIBACC; |
2977 | goto out; | ||
2978 | } | 2978 | } |
2979 | } | 2979 | } |
2980 | 2980 | ||
2981 | *pvolume_info = volume_info; | ||
2982 | return rc; | ||
2983 | out: | ||
2984 | cifs_cleanup_volume_info(&volume_info); | ||
2985 | return rc; | 2981 | return rc; |
2986 | } | 2982 | } |
2987 | 2983 | ||
2984 | struct smb_vol * | ||
2985 | cifs_get_volume_info(char *mount_data, const char *devname) | ||
2986 | { | ||
2987 | int rc; | ||
2988 | struct smb_vol *volume_info; | ||
2989 | |||
2990 | volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL); | ||
2991 | if (!volume_info) | ||
2992 | return ERR_PTR(-ENOMEM); | ||
2993 | |||
2994 | rc = cifs_setup_volume_info(volume_info, mount_data, devname); | ||
2995 | if (rc) { | ||
2996 | cifs_cleanup_volume_info(volume_info); | ||
2997 | volume_info = ERR_PTR(rc); | ||
2998 | } | ||
2999 | |||
3000 | return volume_info; | ||
3001 | } | ||
3002 | |||
2988 | int | 3003 | int |
2989 | cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) | 3004 | cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) |
2990 | { | 3005 | { |
@@ -2997,6 +3012,7 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) | |||
2997 | struct tcon_link *tlink; | 3012 | struct tcon_link *tlink; |
2998 | #ifdef CONFIG_CIFS_DFS_UPCALL | 3013 | #ifdef CONFIG_CIFS_DFS_UPCALL |
2999 | int referral_walks_count = 0; | 3014 | int referral_walks_count = 0; |
3015 | #endif | ||
3000 | 3016 | ||
3001 | rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); | 3017 | rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); |
3002 | if (rc) | 3018 | if (rc) |
@@ -3004,6 +3020,7 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) | |||
3004 | 3020 | ||
3005 | cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages; | 3021 | cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages; |
3006 | 3022 | ||
3023 | #ifdef CONFIG_CIFS_DFS_UPCALL | ||
3007 | try_mount_again: | 3024 | try_mount_again: |
3008 | /* cleanup activities if we're chasing a referral */ | 3025 | /* cleanup activities if we're chasing a referral */ |
3009 | if (referral_walks_count) { | 3026 | if (referral_walks_count) { |
@@ -3012,7 +3029,6 @@ try_mount_again: | |||
3012 | else if (pSesInfo) | 3029 | else if (pSesInfo) |
3013 | cifs_put_smb_ses(pSesInfo); | 3030 | cifs_put_smb_ses(pSesInfo); |
3014 | 3031 | ||
3015 | cifs_cleanup_volume_info(&volume_info); | ||
3016 | FreeXid(xid); | 3032 | FreeXid(xid); |
3017 | } | 3033 | } |
3018 | #endif | 3034 | #endif |
@@ -3469,7 +3485,7 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid) | |||
3469 | goto out; | 3485 | goto out; |
3470 | } | 3486 | } |
3471 | 3487 | ||
3472 | snprintf(username, MAX_USERNAME_SIZE, "krb50x%x", fsuid); | 3488 | snprintf(username, sizeof(username), "krb50x%x", fsuid); |
3473 | vol_info->username = username; | 3489 | vol_info->username = username; |
3474 | vol_info->local_nls = cifs_sb->local_nls; | 3490 | vol_info->local_nls = cifs_sb->local_nls; |
3475 | vol_info->linux_uid = fsuid; | 3491 | vol_info->linux_uid = fsuid; |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 81914df47ef1..fa8c21d913bc 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -55,6 +55,7 @@ build_path_from_dentry(struct dentry *direntry) | |||
55 | char dirsep; | 55 | char dirsep; |
56 | struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); | 56 | struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb); |
57 | struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); | 57 | struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb); |
58 | unsigned seq; | ||
58 | 59 | ||
59 | if (direntry == NULL) | 60 | if (direntry == NULL) |
60 | return NULL; /* not much we can do if dentry is freed and | 61 | return NULL; /* not much we can do if dentry is freed and |
@@ -68,22 +69,29 @@ build_path_from_dentry(struct dentry *direntry) | |||
68 | dfsplen = 0; | 69 | dfsplen = 0; |
69 | cifs_bp_rename_retry: | 70 | cifs_bp_rename_retry: |
70 | namelen = dfsplen; | 71 | namelen = dfsplen; |
72 | seq = read_seqbegin(&rename_lock); | ||
73 | rcu_read_lock(); | ||
71 | for (temp = direntry; !IS_ROOT(temp);) { | 74 | for (temp = direntry; !IS_ROOT(temp);) { |
72 | namelen += (1 + temp->d_name.len); | 75 | namelen += (1 + temp->d_name.len); |
73 | temp = temp->d_parent; | 76 | temp = temp->d_parent; |
74 | if (temp == NULL) { | 77 | if (temp == NULL) { |
75 | cERROR(1, "corrupt dentry"); | 78 | cERROR(1, "corrupt dentry"); |
79 | rcu_read_unlock(); | ||
76 | return NULL; | 80 | return NULL; |
77 | } | 81 | } |
78 | } | 82 | } |
83 | rcu_read_unlock(); | ||
79 | 84 | ||
80 | full_path = kmalloc(namelen+1, GFP_KERNEL); | 85 | full_path = kmalloc(namelen+1, GFP_KERNEL); |
81 | if (full_path == NULL) | 86 | if (full_path == NULL) |
82 | return full_path; | 87 | return full_path; |
83 | full_path[namelen] = 0; /* trailing null */ | 88 | full_path[namelen] = 0; /* trailing null */ |
89 | rcu_read_lock(); | ||
84 | for (temp = direntry; !IS_ROOT(temp);) { | 90 | for (temp = direntry; !IS_ROOT(temp);) { |
91 | spin_lock(&temp->d_lock); | ||
85 | namelen -= 1 + temp->d_name.len; | 92 | namelen -= 1 + temp->d_name.len; |
86 | if (namelen < 0) { | 93 | if (namelen < 0) { |
94 | spin_unlock(&temp->d_lock); | ||
87 | break; | 95 | break; |
88 | } else { | 96 | } else { |
89 | full_path[namelen] = dirsep; | 97 | full_path[namelen] = dirsep; |
@@ -91,14 +99,17 @@ cifs_bp_rename_retry: | |||
91 | temp->d_name.len); | 99 | temp->d_name.len); |
92 | cFYI(0, "name: %s", full_path + namelen); | 100 | cFYI(0, "name: %s", full_path + namelen); |
93 | } | 101 | } |
102 | spin_unlock(&temp->d_lock); | ||
94 | temp = temp->d_parent; | 103 | temp = temp->d_parent; |
95 | if (temp == NULL) { | 104 | if (temp == NULL) { |
96 | cERROR(1, "corrupt dentry"); | 105 | cERROR(1, "corrupt dentry"); |
106 | rcu_read_unlock(); | ||
97 | kfree(full_path); | 107 | kfree(full_path); |
98 | return NULL; | 108 | return NULL; |
99 | } | 109 | } |
100 | } | 110 | } |
101 | if (namelen != dfsplen) { | 111 | rcu_read_unlock(); |
112 | if (namelen != dfsplen || read_seqretry(&rename_lock, seq)) { | ||
102 | cERROR(1, "did not end path lookup where expected namelen is %d", | 113 | cERROR(1, "did not end path lookup where expected namelen is %d", |
103 | namelen); | 114 | namelen); |
104 | /* presumably this is only possible if racing with a rename | 115 | /* presumably this is only possible if racing with a rename |
diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c index 816696621ec9..42e5363b4102 100644 --- a/fs/cifs/fscache.c +++ b/fs/cifs/fscache.c | |||
@@ -92,6 +92,7 @@ static void cifs_fscache_disable_inode_cookie(struct inode *inode) | |||
92 | 92 | ||
93 | if (cifsi->fscache) { | 93 | if (cifsi->fscache) { |
94 | cFYI(1, "%s: (0x%p)", __func__, cifsi->fscache); | 94 | cFYI(1, "%s: (0x%p)", __func__, cifsi->fscache); |
95 | fscache_uncache_all_inode_pages(cifsi->fscache, inode); | ||
95 | fscache_relinquish_cookie(cifsi->fscache, 1); | 96 | fscache_relinquish_cookie(cifsi->fscache, 1); |
96 | cifsi->fscache = NULL; | 97 | cifsi->fscache = NULL; |
97 | } | 98 | } |
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 3892ab817a36..d3e619692ee0 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c | |||
@@ -428,8 +428,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer, | |||
428 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { | 428 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { |
429 | flags |= NTLMSSP_NEGOTIATE_SIGN; | 429 | flags |= NTLMSSP_NEGOTIATE_SIGN; |
430 | if (!ses->server->session_estab) | 430 | if (!ses->server->session_estab) |
431 | flags |= NTLMSSP_NEGOTIATE_KEY_XCH | | 431 | flags |= NTLMSSP_NEGOTIATE_KEY_XCH; |
432 | NTLMSSP_NEGOTIATE_EXTENDED_SEC; | ||
433 | } | 432 | } |
434 | 433 | ||
435 | sec_blob->NegotiateFlags = cpu_to_le32(flags); | 434 | sec_blob->NegotiateFlags = cpu_to_le32(flags); |
@@ -465,10 +464,11 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer, | |||
465 | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | | 464 | NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE | |
466 | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC; | 465 | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC; |
467 | if (ses->server->sec_mode & | 466 | if (ses->server->sec_mode & |
468 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) | 467 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) { |
469 | flags |= NTLMSSP_NEGOTIATE_SIGN; | 468 | flags |= NTLMSSP_NEGOTIATE_SIGN; |
470 | if (ses->server->sec_mode & SECMODE_SIGN_REQUIRED) | 469 | if (!ses->server->session_estab) |
471 | flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; | 470 | flags |= NTLMSSP_NEGOTIATE_KEY_XCH; |
471 | } | ||
472 | 472 | ||
473 | tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE); | 473 | tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE); |
474 | sec_blob->NegotiateFlags = cpu_to_le32(flags); | 474 | sec_blob->NegotiateFlags = cpu_to_le32(flags); |
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c index e141939080f0..739fb59bcdc2 100644 --- a/fs/cramfs/inode.c +++ b/fs/cramfs/inode.c | |||
@@ -37,7 +37,7 @@ static DEFINE_MUTEX(read_mutex); | |||
37 | /* These macros may change in future, to provide better st_ino semantics. */ | 37 | /* These macros may change in future, to provide better st_ino semantics. */ |
38 | #define OFFSET(x) ((x)->i_ino) | 38 | #define OFFSET(x) ((x)->i_ino) |
39 | 39 | ||
40 | static unsigned long cramino(struct cramfs_inode *cino, unsigned int offset) | 40 | static unsigned long cramino(const struct cramfs_inode *cino, unsigned int offset) |
41 | { | 41 | { |
42 | if (!cino->offset) | 42 | if (!cino->offset) |
43 | return offset + 1; | 43 | return offset + 1; |
@@ -61,7 +61,7 @@ static unsigned long cramino(struct cramfs_inode *cino, unsigned int offset) | |||
61 | } | 61 | } |
62 | 62 | ||
63 | static struct inode *get_cramfs_inode(struct super_block *sb, | 63 | static struct inode *get_cramfs_inode(struct super_block *sb, |
64 | struct cramfs_inode *cramfs_inode, unsigned int offset) | 64 | const struct cramfs_inode *cramfs_inode, unsigned int offset) |
65 | { | 65 | { |
66 | struct inode *inode; | 66 | struct inode *inode; |
67 | static struct timespec zerotime; | 67 | static struct timespec zerotime; |
@@ -317,7 +317,7 @@ static int cramfs_fill_super(struct super_block *sb, void *data, int silent) | |||
317 | /* Set it all up.. */ | 317 | /* Set it all up.. */ |
318 | sb->s_op = &cramfs_ops; | 318 | sb->s_op = &cramfs_ops; |
319 | root = get_cramfs_inode(sb, &super.root, 0); | 319 | root = get_cramfs_inode(sb, &super.root, 0); |
320 | if (!root) | 320 | if (IS_ERR(root)) |
321 | goto out; | 321 | goto out; |
322 | sb->s_root = d_alloc_root(root); | 322 | sb->s_root = d_alloc_root(root); |
323 | if (!sb->s_root) { | 323 | if (!sb->s_root) { |
@@ -423,6 +423,7 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
423 | static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | 423 | static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) |
424 | { | 424 | { |
425 | unsigned int offset = 0; | 425 | unsigned int offset = 0; |
426 | struct inode *inode = NULL; | ||
426 | int sorted; | 427 | int sorted; |
427 | 428 | ||
428 | mutex_lock(&read_mutex); | 429 | mutex_lock(&read_mutex); |
@@ -449,8 +450,8 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, s | |||
449 | 450 | ||
450 | for (;;) { | 451 | for (;;) { |
451 | if (!namelen) { | 452 | if (!namelen) { |
452 | mutex_unlock(&read_mutex); | 453 | inode = ERR_PTR(-EIO); |
453 | return ERR_PTR(-EIO); | 454 | goto out; |
454 | } | 455 | } |
455 | if (name[namelen-1]) | 456 | if (name[namelen-1]) |
456 | break; | 457 | break; |
@@ -462,17 +463,18 @@ static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, s | |||
462 | if (retval > 0) | 463 | if (retval > 0) |
463 | continue; | 464 | continue; |
464 | if (!retval) { | 465 | if (!retval) { |
465 | struct cramfs_inode entry = *de; | 466 | inode = get_cramfs_inode(dir->i_sb, de, dir_off); |
466 | mutex_unlock(&read_mutex); | 467 | break; |
467 | d_add(dentry, get_cramfs_inode(dir->i_sb, &entry, dir_off)); | ||
468 | return NULL; | ||
469 | } | 468 | } |
470 | /* else (retval < 0) */ | 469 | /* else (retval < 0) */ |
471 | if (sorted) | 470 | if (sorted) |
472 | break; | 471 | break; |
473 | } | 472 | } |
473 | out: | ||
474 | mutex_unlock(&read_mutex); | 474 | mutex_unlock(&read_mutex); |
475 | d_add(dentry, NULL); | 475 | if (IS_ERR(inode)) |
476 | return ERR_CAST(inode); | ||
477 | d_add(dentry, inode); | ||
476 | return NULL; | 478 | return NULL; |
477 | } | 479 | } |
478 | 480 | ||
diff --git a/fs/dcache.c b/fs/dcache.c index 37f72ee5bf7c..6e4ea6d87774 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -2213,14 +2213,15 @@ static void dentry_unlock_parents_for_move(struct dentry *dentry, | |||
2213 | * The hash value has to match the hash queue that the dentry is on.. | 2213 | * The hash value has to match the hash queue that the dentry is on.. |
2214 | */ | 2214 | */ |
2215 | /* | 2215 | /* |
2216 | * d_move - move a dentry | 2216 | * __d_move - move a dentry |
2217 | * @dentry: entry to move | 2217 | * @dentry: entry to move |
2218 | * @target: new dentry | 2218 | * @target: new dentry |
2219 | * | 2219 | * |
2220 | * Update the dcache to reflect the move of a file name. Negative | 2220 | * Update the dcache to reflect the move of a file name. Negative |
2221 | * dcache entries should not be moved in this way. | 2221 | * dcache entries should not be moved in this way. Caller hold |
2222 | * rename_lock. | ||
2222 | */ | 2223 | */ |
2223 | void d_move(struct dentry * dentry, struct dentry * target) | 2224 | static void __d_move(struct dentry * dentry, struct dentry * target) |
2224 | { | 2225 | { |
2225 | if (!dentry->d_inode) | 2226 | if (!dentry->d_inode) |
2226 | printk(KERN_WARNING "VFS: moving negative dcache entry\n"); | 2227 | printk(KERN_WARNING "VFS: moving negative dcache entry\n"); |
@@ -2228,8 +2229,6 @@ void d_move(struct dentry * dentry, struct dentry * target) | |||
2228 | BUG_ON(d_ancestor(dentry, target)); | 2229 | BUG_ON(d_ancestor(dentry, target)); |
2229 | BUG_ON(d_ancestor(target, dentry)); | 2230 | BUG_ON(d_ancestor(target, dentry)); |
2230 | 2231 | ||
2231 | write_seqlock(&rename_lock); | ||
2232 | |||
2233 | dentry_lock_for_move(dentry, target); | 2232 | dentry_lock_for_move(dentry, target); |
2234 | 2233 | ||
2235 | write_seqcount_begin(&dentry->d_seq); | 2234 | write_seqcount_begin(&dentry->d_seq); |
@@ -2275,6 +2274,20 @@ void d_move(struct dentry * dentry, struct dentry * target) | |||
2275 | spin_unlock(&target->d_lock); | 2274 | spin_unlock(&target->d_lock); |
2276 | fsnotify_d_move(dentry); | 2275 | fsnotify_d_move(dentry); |
2277 | spin_unlock(&dentry->d_lock); | 2276 | spin_unlock(&dentry->d_lock); |
2277 | } | ||
2278 | |||
2279 | /* | ||
2280 | * d_move - move a dentry | ||
2281 | * @dentry: entry to move | ||
2282 | * @target: new dentry | ||
2283 | * | ||
2284 | * Update the dcache to reflect the move of a file name. Negative | ||
2285 | * dcache entries should not be moved in this way. | ||
2286 | */ | ||
2287 | void d_move(struct dentry *dentry, struct dentry *target) | ||
2288 | { | ||
2289 | write_seqlock(&rename_lock); | ||
2290 | __d_move(dentry, target); | ||
2278 | write_sequnlock(&rename_lock); | 2291 | write_sequnlock(&rename_lock); |
2279 | } | 2292 | } |
2280 | EXPORT_SYMBOL(d_move); | 2293 | EXPORT_SYMBOL(d_move); |
@@ -2302,7 +2315,7 @@ struct dentry *d_ancestor(struct dentry *p1, struct dentry *p2) | |||
2302 | * This helper attempts to cope with remotely renamed directories | 2315 | * This helper attempts to cope with remotely renamed directories |
2303 | * | 2316 | * |
2304 | * It assumes that the caller is already holding | 2317 | * It assumes that the caller is already holding |
2305 | * dentry->d_parent->d_inode->i_mutex and the inode->i_lock | 2318 | * dentry->d_parent->d_inode->i_mutex, inode->i_lock and rename_lock |
2306 | * | 2319 | * |
2307 | * Note: If ever the locking in lock_rename() changes, then please | 2320 | * Note: If ever the locking in lock_rename() changes, then please |
2308 | * remember to update this too... | 2321 | * remember to update this too... |
@@ -2317,11 +2330,6 @@ static struct dentry *__d_unalias(struct inode *inode, | |||
2317 | if (alias->d_parent == dentry->d_parent) | 2330 | if (alias->d_parent == dentry->d_parent) |
2318 | goto out_unalias; | 2331 | goto out_unalias; |
2319 | 2332 | ||
2320 | /* Check for loops */ | ||
2321 | ret = ERR_PTR(-ELOOP); | ||
2322 | if (d_ancestor(alias, dentry)) | ||
2323 | goto out_err; | ||
2324 | |||
2325 | /* See lock_rename() */ | 2333 | /* See lock_rename() */ |
2326 | ret = ERR_PTR(-EBUSY); | 2334 | ret = ERR_PTR(-EBUSY); |
2327 | if (!mutex_trylock(&dentry->d_sb->s_vfs_rename_mutex)) | 2335 | if (!mutex_trylock(&dentry->d_sb->s_vfs_rename_mutex)) |
@@ -2331,7 +2339,7 @@ static struct dentry *__d_unalias(struct inode *inode, | |||
2331 | goto out_err; | 2339 | goto out_err; |
2332 | m2 = &alias->d_parent->d_inode->i_mutex; | 2340 | m2 = &alias->d_parent->d_inode->i_mutex; |
2333 | out_unalias: | 2341 | out_unalias: |
2334 | d_move(alias, dentry); | 2342 | __d_move(alias, dentry); |
2335 | ret = alias; | 2343 | ret = alias; |
2336 | out_err: | 2344 | out_err: |
2337 | spin_unlock(&inode->i_lock); | 2345 | spin_unlock(&inode->i_lock); |
@@ -2416,15 +2424,24 @@ struct dentry *d_materialise_unique(struct dentry *dentry, struct inode *inode) | |||
2416 | alias = __d_find_alias(inode, 0); | 2424 | alias = __d_find_alias(inode, 0); |
2417 | if (alias) { | 2425 | if (alias) { |
2418 | actual = alias; | 2426 | actual = alias; |
2419 | /* Is this an anonymous mountpoint that we could splice | 2427 | write_seqlock(&rename_lock); |
2420 | * into our tree? */ | 2428 | |
2421 | if (IS_ROOT(alias)) { | 2429 | if (d_ancestor(alias, dentry)) { |
2430 | /* Check for loops */ | ||
2431 | actual = ERR_PTR(-ELOOP); | ||
2432 | } else if (IS_ROOT(alias)) { | ||
2433 | /* Is this an anonymous mountpoint that we | ||
2434 | * could splice into our tree? */ | ||
2422 | __d_materialise_dentry(dentry, alias); | 2435 | __d_materialise_dentry(dentry, alias); |
2436 | write_sequnlock(&rename_lock); | ||
2423 | __d_drop(alias); | 2437 | __d_drop(alias); |
2424 | goto found; | 2438 | goto found; |
2439 | } else { | ||
2440 | /* Nope, but we must(!) avoid directory | ||
2441 | * aliasing */ | ||
2442 | actual = __d_unalias(inode, dentry, alias); | ||
2425 | } | 2443 | } |
2426 | /* Nope, but we must(!) avoid directory aliasing */ | 2444 | write_sequnlock(&rename_lock); |
2427 | actual = __d_unalias(inode, dentry, alias); | ||
2428 | if (IS_ERR(actual)) | 2445 | if (IS_ERR(actual)) |
2429 | dput(alias); | 2446 | dput(alias); |
2430 | goto out_nolock; | 2447 | goto out_nolock; |
diff --git a/fs/exofs/super.c b/fs/exofs/super.c index 06065bd37fc3..c57beddcc217 100644 --- a/fs/exofs/super.c +++ b/fs/exofs/super.c | |||
@@ -913,7 +913,7 @@ struct dentry *exofs_get_parent(struct dentry *child) | |||
913 | unsigned long ino = exofs_parent_ino(child); | 913 | unsigned long ino = exofs_parent_ino(child); |
914 | 914 | ||
915 | if (!ino) | 915 | if (!ino) |
916 | return NULL; | 916 | return ERR_PTR(-ESTALE); |
917 | 917 | ||
918 | return d_obtain_alias(exofs_iget(child->d_inode->i_sb, ino)); | 918 | return d_obtain_alias(exofs_iget(child->d_inode->i_sb, ino)); |
919 | } | 919 | } |
diff --git a/fs/fscache/page.c b/fs/fscache/page.c index a2a5d19ece6a..2f343b4d7a7d 100644 --- a/fs/fscache/page.c +++ b/fs/fscache/page.c | |||
@@ -954,3 +954,47 @@ void fscache_mark_pages_cached(struct fscache_retrieval *op, | |||
954 | pagevec_reinit(pagevec); | 954 | pagevec_reinit(pagevec); |
955 | } | 955 | } |
956 | EXPORT_SYMBOL(fscache_mark_pages_cached); | 956 | EXPORT_SYMBOL(fscache_mark_pages_cached); |
957 | |||
958 | /* | ||
959 | * Uncache all the pages in an inode that are marked PG_fscache, assuming them | ||
960 | * to be associated with the given cookie. | ||
961 | */ | ||
962 | void __fscache_uncache_all_inode_pages(struct fscache_cookie *cookie, | ||
963 | struct inode *inode) | ||
964 | { | ||
965 | struct address_space *mapping = inode->i_mapping; | ||
966 | struct pagevec pvec; | ||
967 | pgoff_t next; | ||
968 | int i; | ||
969 | |||
970 | _enter("%p,%p", cookie, inode); | ||
971 | |||
972 | if (!mapping || mapping->nrpages == 0) { | ||
973 | _leave(" [no pages]"); | ||
974 | return; | ||
975 | } | ||
976 | |||
977 | pagevec_init(&pvec, 0); | ||
978 | next = 0; | ||
979 | while (next <= (loff_t)-1 && | ||
980 | pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE) | ||
981 | ) { | ||
982 | for (i = 0; i < pagevec_count(&pvec); i++) { | ||
983 | struct page *page = pvec.pages[i]; | ||
984 | pgoff_t page_index = page->index; | ||
985 | |||
986 | ASSERTCMP(page_index, >=, next); | ||
987 | next = page_index + 1; | ||
988 | |||
989 | if (PageFsCache(page)) { | ||
990 | __fscache_wait_on_page_write(cookie, page); | ||
991 | __fscache_uncache_page(cookie, page); | ||
992 | } | ||
993 | } | ||
994 | pagevec_release(&pvec); | ||
995 | cond_resched(); | ||
996 | } | ||
997 | |||
998 | _leave(""); | ||
999 | } | ||
1000 | EXPORT_SYMBOL(__fscache_uncache_all_inode_pages); | ||
diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index 802ac5eeba28..f9fbbe96c222 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c | |||
@@ -1069,6 +1069,7 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask) | |||
1069 | return 0; | 1069 | return 0; |
1070 | 1070 | ||
1071 | gfs2_log_lock(sdp); | 1071 | gfs2_log_lock(sdp); |
1072 | spin_lock(&sdp->sd_ail_lock); | ||
1072 | head = bh = page_buffers(page); | 1073 | head = bh = page_buffers(page); |
1073 | do { | 1074 | do { |
1074 | if (atomic_read(&bh->b_count)) | 1075 | if (atomic_read(&bh->b_count)) |
@@ -1080,6 +1081,7 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask) | |||
1080 | goto not_possible; | 1081 | goto not_possible; |
1081 | bh = bh->b_this_page; | 1082 | bh = bh->b_this_page; |
1082 | } while(bh != head); | 1083 | } while(bh != head); |
1084 | spin_unlock(&sdp->sd_ail_lock); | ||
1083 | gfs2_log_unlock(sdp); | 1085 | gfs2_log_unlock(sdp); |
1084 | 1086 | ||
1085 | head = bh = page_buffers(page); | 1087 | head = bh = page_buffers(page); |
@@ -1112,6 +1114,7 @@ not_possible: /* Should never happen */ | |||
1112 | WARN_ON(buffer_dirty(bh)); | 1114 | WARN_ON(buffer_dirty(bh)); |
1113 | WARN_ON(buffer_pinned(bh)); | 1115 | WARN_ON(buffer_pinned(bh)); |
1114 | cannot_release: | 1116 | cannot_release: |
1117 | spin_unlock(&sdp->sd_ail_lock); | ||
1115 | gfs2_log_unlock(sdp); | 1118 | gfs2_log_unlock(sdp); |
1116 | return 0; | 1119 | return 0; |
1117 | } | 1120 | } |
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 8ef70f464731..2cca29316bd6 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -47,10 +47,10 @@ static void __gfs2_ail_flush(struct gfs2_glock *gl) | |||
47 | bd_ail_gl_list); | 47 | bd_ail_gl_list); |
48 | bh = bd->bd_bh; | 48 | bh = bd->bd_bh; |
49 | gfs2_remove_from_ail(bd); | 49 | gfs2_remove_from_ail(bd); |
50 | spin_unlock(&sdp->sd_ail_lock); | ||
51 | |||
52 | bd->bd_bh = NULL; | 50 | bd->bd_bh = NULL; |
53 | bh->b_private = NULL; | 51 | bh->b_private = NULL; |
52 | spin_unlock(&sdp->sd_ail_lock); | ||
53 | |||
54 | bd->bd_blkno = bh->b_blocknr; | 54 | bd->bd_blkno = bh->b_blocknr; |
55 | gfs2_log_lock(sdp); | 55 | gfs2_log_lock(sdp); |
56 | gfs2_assert_withdraw(sdp, !buffer_busy(bh)); | 56 | gfs2_assert_withdraw(sdp, !buffer_busy(bh)); |
@@ -221,8 +221,10 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags) | |||
221 | } | 221 | } |
222 | } | 222 | } |
223 | 223 | ||
224 | if (ip == GFS2_I(gl->gl_sbd->sd_rindex)) | 224 | if (ip == GFS2_I(gl->gl_sbd->sd_rindex)) { |
225 | gfs2_log_flush(gl->gl_sbd, NULL); | ||
225 | gl->gl_sbd->sd_rindex_uptodate = 0; | 226 | gl->gl_sbd->sd_rindex_uptodate = 0; |
227 | } | ||
226 | if (ip && S_ISREG(ip->i_inode.i_mode)) | 228 | if (ip && S_ISREG(ip->i_inode.i_mode)) |
227 | truncate_inode_pages(ip->i_inode.i_mapping, 0); | 229 | truncate_inode_pages(ip->i_inode.i_mapping, 0); |
228 | } | 230 | } |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 0a064e91ac70..81206e70cbf6 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/buffer_head.h> | 17 | #include <linux/buffer_head.h> |
18 | #include <linux/rcupdate.h> | 18 | #include <linux/rcupdate.h> |
19 | #include <linux/rculist_bl.h> | 19 | #include <linux/rculist_bl.h> |
20 | #include <linux/completion.h> | ||
20 | 21 | ||
21 | #define DIO_WAIT 0x00000010 | 22 | #define DIO_WAIT 0x00000010 |
22 | #define DIO_METADATA 0x00000020 | 23 | #define DIO_METADATA 0x00000020 |
@@ -546,6 +547,7 @@ struct gfs2_sbd { | |||
546 | struct gfs2_glock *sd_trans_gl; | 547 | struct gfs2_glock *sd_trans_gl; |
547 | wait_queue_head_t sd_glock_wait; | 548 | wait_queue_head_t sd_glock_wait; |
548 | atomic_t sd_glock_disposal; | 549 | atomic_t sd_glock_disposal; |
550 | struct completion sd_locking_init; | ||
549 | 551 | ||
550 | /* Inode Stuff */ | 552 | /* Inode Stuff */ |
551 | 553 | ||
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 903115f2bb34..85c62923ee29 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -903,6 +903,7 @@ void gfs2_meta_syncfs(struct gfs2_sbd *sdp) | |||
903 | if (gfs2_ail1_empty(sdp)) | 903 | if (gfs2_ail1_empty(sdp)) |
904 | break; | 904 | break; |
905 | } | 905 | } |
906 | gfs2_log_flush(sdp, NULL); | ||
906 | } | 907 | } |
907 | 908 | ||
908 | static inline int gfs2_jrnl_flush_reqd(struct gfs2_sbd *sdp) | 909 | static inline int gfs2_jrnl_flush_reqd(struct gfs2_sbd *sdp) |
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 8ac9ae189b53..2a77071fb7b6 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -72,6 +72,7 @@ static struct gfs2_sbd *init_sbd(struct super_block *sb) | |||
72 | 72 | ||
73 | init_waitqueue_head(&sdp->sd_glock_wait); | 73 | init_waitqueue_head(&sdp->sd_glock_wait); |
74 | atomic_set(&sdp->sd_glock_disposal, 0); | 74 | atomic_set(&sdp->sd_glock_disposal, 0); |
75 | init_completion(&sdp->sd_locking_init); | ||
75 | spin_lock_init(&sdp->sd_statfs_spin); | 76 | spin_lock_init(&sdp->sd_statfs_spin); |
76 | 77 | ||
77 | spin_lock_init(&sdp->sd_rindex_spin); | 78 | spin_lock_init(&sdp->sd_rindex_spin); |
@@ -1017,11 +1018,13 @@ hostdata_error: | |||
1017 | fsname++; | 1018 | fsname++; |
1018 | if (lm->lm_mount == NULL) { | 1019 | if (lm->lm_mount == NULL) { |
1019 | fs_info(sdp, "Now mounting FS...\n"); | 1020 | fs_info(sdp, "Now mounting FS...\n"); |
1021 | complete(&sdp->sd_locking_init); | ||
1020 | return 0; | 1022 | return 0; |
1021 | } | 1023 | } |
1022 | ret = lm->lm_mount(sdp, fsname); | 1024 | ret = lm->lm_mount(sdp, fsname); |
1023 | if (ret == 0) | 1025 | if (ret == 0) |
1024 | fs_info(sdp, "Joined cluster. Now mounting FS...\n"); | 1026 | fs_info(sdp, "Joined cluster. Now mounting FS...\n"); |
1027 | complete(&sdp->sd_locking_init); | ||
1025 | return ret; | 1028 | return ret; |
1026 | } | 1029 | } |
1027 | 1030 | ||
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index ed540e7018be..fb0edf735483 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -757,13 +757,17 @@ static int gfs2_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
757 | struct timespec atime; | 757 | struct timespec atime; |
758 | struct gfs2_dinode *di; | 758 | struct gfs2_dinode *di; |
759 | int ret = -EAGAIN; | 759 | int ret = -EAGAIN; |
760 | int unlock_required = 0; | ||
760 | 761 | ||
761 | /* Skip timestamp update, if this is from a memalloc */ | 762 | /* Skip timestamp update, if this is from a memalloc */ |
762 | if (current->flags & PF_MEMALLOC) | 763 | if (current->flags & PF_MEMALLOC) |
763 | goto do_flush; | 764 | goto do_flush; |
764 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); | 765 | if (!gfs2_glock_is_locked_by_me(ip->i_gl)) { |
765 | if (ret) | 766 | ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); |
766 | goto do_flush; | 767 | if (ret) |
768 | goto do_flush; | ||
769 | unlock_required = 1; | ||
770 | } | ||
767 | ret = gfs2_trans_begin(sdp, RES_DINODE, 0); | 771 | ret = gfs2_trans_begin(sdp, RES_DINODE, 0); |
768 | if (ret) | 772 | if (ret) |
769 | goto do_unlock; | 773 | goto do_unlock; |
@@ -780,7 +784,8 @@ static int gfs2_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
780 | } | 784 | } |
781 | gfs2_trans_end(sdp); | 785 | gfs2_trans_end(sdp); |
782 | do_unlock: | 786 | do_unlock: |
783 | gfs2_glock_dq_uninit(&gh); | 787 | if (unlock_required) |
788 | gfs2_glock_dq_uninit(&gh); | ||
784 | do_flush: | 789 | do_flush: |
785 | if (wbc->sync_mode == WB_SYNC_ALL) | 790 | if (wbc->sync_mode == WB_SYNC_ALL) |
786 | gfs2_log_flush(GFS2_SB(inode), ip->i_gl); | 791 | gfs2_log_flush(GFS2_SB(inode), ip->i_gl); |
@@ -1427,7 +1432,20 @@ out: | |||
1427 | return error; | 1432 | return error; |
1428 | } | 1433 | } |
1429 | 1434 | ||
1430 | /* | 1435 | /** |
1436 | * gfs2_evict_inode - Remove an inode from cache | ||
1437 | * @inode: The inode to evict | ||
1438 | * | ||
1439 | * There are three cases to consider: | ||
1440 | * 1. i_nlink == 0, we are final opener (and must deallocate) | ||
1441 | * 2. i_nlink == 0, we are not the final opener (and cannot deallocate) | ||
1442 | * 3. i_nlink > 0 | ||
1443 | * | ||
1444 | * If the fs is read only, then we have to treat all cases as per #3 | ||
1445 | * since we are unable to do any deallocation. The inode will be | ||
1446 | * deallocated by the next read/write node to attempt an allocation | ||
1447 | * in the same resource group | ||
1448 | * | ||
1431 | * We have to (at the moment) hold the inodes main lock to cover | 1449 | * We have to (at the moment) hold the inodes main lock to cover |
1432 | * the gap between unlocking the shared lock on the iopen lock and | 1450 | * the gap between unlocking the shared lock on the iopen lock and |
1433 | * taking the exclusive lock. I'd rather do a shared -> exclusive | 1451 | * taking the exclusive lock. I'd rather do a shared -> exclusive |
@@ -1470,6 +1488,8 @@ static void gfs2_evict_inode(struct inode *inode) | |||
1470 | if (error) | 1488 | if (error) |
1471 | goto out_truncate; | 1489 | goto out_truncate; |
1472 | 1490 | ||
1491 | /* Case 1 starts here */ | ||
1492 | |||
1473 | if (S_ISDIR(inode->i_mode) && | 1493 | if (S_ISDIR(inode->i_mode) && |
1474 | (ip->i_diskflags & GFS2_DIF_EXHASH)) { | 1494 | (ip->i_diskflags & GFS2_DIF_EXHASH)) { |
1475 | error = gfs2_dir_exhash_dealloc(ip); | 1495 | error = gfs2_dir_exhash_dealloc(ip); |
@@ -1493,13 +1513,16 @@ static void gfs2_evict_inode(struct inode *inode) | |||
1493 | goto out_unlock; | 1513 | goto out_unlock; |
1494 | 1514 | ||
1495 | out_truncate: | 1515 | out_truncate: |
1516 | /* Case 2 starts here */ | ||
1496 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); | 1517 | error = gfs2_trans_begin(sdp, 0, sdp->sd_jdesc->jd_blocks); |
1497 | if (error) | 1518 | if (error) |
1498 | goto out_unlock; | 1519 | goto out_unlock; |
1499 | gfs2_final_release_pages(ip); | 1520 | /* Needs to be done before glock release & also in a transaction */ |
1521 | truncate_inode_pages(&inode->i_data, 0); | ||
1500 | gfs2_trans_end(sdp); | 1522 | gfs2_trans_end(sdp); |
1501 | 1523 | ||
1502 | out_unlock: | 1524 | out_unlock: |
1525 | /* Error path for case 1 */ | ||
1503 | if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) | 1526 | if (test_bit(HIF_HOLDER, &ip->i_iopen_gh.gh_iflags)) |
1504 | gfs2_glock_dq(&ip->i_iopen_gh); | 1527 | gfs2_glock_dq(&ip->i_iopen_gh); |
1505 | gfs2_holder_uninit(&ip->i_iopen_gh); | 1528 | gfs2_holder_uninit(&ip->i_iopen_gh); |
@@ -1507,6 +1530,7 @@ out_unlock: | |||
1507 | if (error && error != GLR_TRYFAILED && error != -EROFS) | 1530 | if (error && error != GLR_TRYFAILED && error != -EROFS) |
1508 | fs_warn(sdp, "gfs2_evict_inode: %d\n", error); | 1531 | fs_warn(sdp, "gfs2_evict_inode: %d\n", error); |
1509 | out: | 1532 | out: |
1533 | /* Case 3 starts here */ | ||
1510 | truncate_inode_pages(&inode->i_data, 0); | 1534 | truncate_inode_pages(&inode->i_data, 0); |
1511 | end_writeback(inode); | 1535 | end_writeback(inode); |
1512 | 1536 | ||
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index e20eab37bc80..443cabcfcd23 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c | |||
@@ -338,6 +338,9 @@ static ssize_t lkfirst_store(struct gfs2_sbd *sdp, const char *buf, size_t len) | |||
338 | rv = sscanf(buf, "%u", &first); | 338 | rv = sscanf(buf, "%u", &first); |
339 | if (rv != 1 || first > 1) | 339 | if (rv != 1 || first > 1) |
340 | return -EINVAL; | 340 | return -EINVAL; |
341 | rv = wait_for_completion_killable(&sdp->sd_locking_init); | ||
342 | if (rv) | ||
343 | return rv; | ||
341 | spin_lock(&sdp->sd_jindex_spin); | 344 | spin_lock(&sdp->sd_jindex_spin); |
342 | rv = -EBUSY; | 345 | rv = -EBUSY; |
343 | if (test_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0) | 346 | if (test_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0) |
@@ -414,7 +417,9 @@ static ssize_t jid_store(struct gfs2_sbd *sdp, const char *buf, size_t len) | |||
414 | rv = sscanf(buf, "%d", &jid); | 417 | rv = sscanf(buf, "%d", &jid); |
415 | if (rv != 1) | 418 | if (rv != 1) |
416 | return -EINVAL; | 419 | return -EINVAL; |
417 | 420 | rv = wait_for_completion_killable(&sdp->sd_locking_init); | |
421 | if (rv) | ||
422 | return rv; | ||
418 | spin_lock(&sdp->sd_jindex_spin); | 423 | spin_lock(&sdp->sd_jindex_spin); |
419 | rv = -EINVAL; | 424 | rv = -EINVAL; |
420 | if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL) | 425 | if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL) |
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index b49b55584c84..84a47b709f51 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
@@ -500,7 +500,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
500 | out_put_hidden_dir: | 500 | out_put_hidden_dir: |
501 | iput(sbi->hidden_dir); | 501 | iput(sbi->hidden_dir); |
502 | out_put_root: | 502 | out_put_root: |
503 | iput(sbi->alloc_file); | 503 | iput(root); |
504 | out_put_alloc_file: | 504 | out_put_alloc_file: |
505 | iput(sbi->alloc_file); | 505 | iput(sbi->alloc_file); |
506 | out_close_cat_tree: | 506 | out_close_cat_tree: |
diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c index 3031d81f5f0f..4ac88ff79aa6 100644 --- a/fs/hfsplus/wrapper.c +++ b/fs/hfsplus/wrapper.c | |||
@@ -36,6 +36,7 @@ int hfsplus_submit_bio(struct block_device *bdev, sector_t sector, | |||
36 | { | 36 | { |
37 | DECLARE_COMPLETION_ONSTACK(wait); | 37 | DECLARE_COMPLETION_ONSTACK(wait); |
38 | struct bio *bio; | 38 | struct bio *bio; |
39 | int ret = 0; | ||
39 | 40 | ||
40 | bio = bio_alloc(GFP_NOIO, 1); | 41 | bio = bio_alloc(GFP_NOIO, 1); |
41 | bio->bi_sector = sector; | 42 | bio->bi_sector = sector; |
@@ -54,8 +55,10 @@ int hfsplus_submit_bio(struct block_device *bdev, sector_t sector, | |||
54 | wait_for_completion(&wait); | 55 | wait_for_completion(&wait); |
55 | 56 | ||
56 | if (!bio_flagged(bio, BIO_UPTODATE)) | 57 | if (!bio_flagged(bio, BIO_UPTODATE)) |
57 | return -EIO; | 58 | ret = -EIO; |
58 | return 0; | 59 | |
60 | bio_put(bio); | ||
61 | return ret; | ||
59 | } | 62 | } |
60 | 63 | ||
61 | static int hfsplus_read_mdb(void *bufptr, struct hfsplus_wd *wd) | 64 | static int hfsplus_read_mdb(void *bufptr, struct hfsplus_wd *wd) |
diff --git a/fs/hppfs/hppfs.c b/fs/hppfs/hppfs.c index 87ed48e0343d..85c098a499f3 100644 --- a/fs/hppfs/hppfs.c +++ b/fs/hppfs/hppfs.c | |||
@@ -139,7 +139,8 @@ static int file_removed(struct dentry *dentry, const char *file) | |||
139 | static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, | 139 | static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, |
140 | struct nameidata *nd) | 140 | struct nameidata *nd) |
141 | { | 141 | { |
142 | struct dentry *proc_dentry, *new, *parent; | 142 | struct dentry *proc_dentry, *parent; |
143 | struct qstr *name = &dentry->d_name; | ||
143 | struct inode *inode; | 144 | struct inode *inode; |
144 | int err, deleted; | 145 | int err, deleted; |
145 | 146 | ||
@@ -149,23 +150,9 @@ static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, | |||
149 | else if (deleted) | 150 | else if (deleted) |
150 | return ERR_PTR(-ENOENT); | 151 | return ERR_PTR(-ENOENT); |
151 | 152 | ||
152 | err = -ENOMEM; | ||
153 | parent = HPPFS_I(ino)->proc_dentry; | 153 | parent = HPPFS_I(ino)->proc_dentry; |
154 | mutex_lock(&parent->d_inode->i_mutex); | 154 | mutex_lock(&parent->d_inode->i_mutex); |
155 | proc_dentry = d_lookup(parent, &dentry->d_name); | 155 | proc_dentry = lookup_one_len(name->name, parent, name->len); |
156 | if (proc_dentry == NULL) { | ||
157 | proc_dentry = d_alloc(parent, &dentry->d_name); | ||
158 | if (proc_dentry == NULL) { | ||
159 | mutex_unlock(&parent->d_inode->i_mutex); | ||
160 | goto out; | ||
161 | } | ||
162 | new = (*parent->d_inode->i_op->lookup)(parent->d_inode, | ||
163 | proc_dentry, NULL); | ||
164 | if (new) { | ||
165 | dput(proc_dentry); | ||
166 | proc_dentry = new; | ||
167 | } | ||
168 | } | ||
169 | mutex_unlock(&parent->d_inode->i_mutex); | 156 | mutex_unlock(&parent->d_inode->i_mutex); |
170 | 157 | ||
171 | if (IS_ERR(proc_dentry)) | 158 | if (IS_ERR(proc_dentry)) |
@@ -174,13 +161,11 @@ static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, | |||
174 | err = -ENOMEM; | 161 | err = -ENOMEM; |
175 | inode = get_inode(ino->i_sb, proc_dentry); | 162 | inode = get_inode(ino->i_sb, proc_dentry); |
176 | if (!inode) | 163 | if (!inode) |
177 | goto out_dput; | 164 | goto out; |
178 | 165 | ||
179 | d_add(dentry, inode); | 166 | d_add(dentry, inode); |
180 | return NULL; | 167 | return NULL; |
181 | 168 | ||
182 | out_dput: | ||
183 | dput(proc_dentry); | ||
184 | out: | 169 | out: |
185 | return ERR_PTR(err); | 170 | return ERR_PTR(err); |
186 | } | 171 | } |
@@ -690,8 +675,10 @@ static struct inode *get_inode(struct super_block *sb, struct dentry *dentry) | |||
690 | struct inode *proc_ino = dentry->d_inode; | 675 | struct inode *proc_ino = dentry->d_inode; |
691 | struct inode *inode = new_inode(sb); | 676 | struct inode *inode = new_inode(sb); |
692 | 677 | ||
693 | if (!inode) | 678 | if (!inode) { |
679 | dput(dentry); | ||
694 | return ERR_PTR(-ENOMEM); | 680 | return ERR_PTR(-ENOMEM); |
681 | } | ||
695 | 682 | ||
696 | if (S_ISDIR(dentry->d_inode->i_mode)) { | 683 | if (S_ISDIR(dentry->d_inode->i_mode)) { |
697 | inode->i_op = &hppfs_dir_iops; | 684 | inode->i_op = &hppfs_dir_iops; |
@@ -704,7 +691,7 @@ static struct inode *get_inode(struct super_block *sb, struct dentry *dentry) | |||
704 | inode->i_fop = &hppfs_file_fops; | 691 | inode->i_fop = &hppfs_file_fops; |
705 | } | 692 | } |
706 | 693 | ||
707 | HPPFS_I(inode)->proc_dentry = dget(dentry); | 694 | HPPFS_I(inode)->proc_dentry = dentry; |
708 | 695 | ||
709 | inode->i_uid = proc_ino->i_uid; | 696 | inode->i_uid = proc_ino->i_uid; |
710 | inode->i_gid = proc_ino->i_gid; | 697 | inode->i_gid = proc_ino->i_gid; |
@@ -737,7 +724,7 @@ static int hppfs_fill_super(struct super_block *sb, void *d, int silent) | |||
737 | sb->s_fs_info = proc_mnt; | 724 | sb->s_fs_info = proc_mnt; |
738 | 725 | ||
739 | err = -ENOMEM; | 726 | err = -ENOMEM; |
740 | root_inode = get_inode(sb, proc_mnt->mnt_sb->s_root); | 727 | root_inode = get_inode(sb, dget(proc_mnt->mnt_sb->s_root)); |
741 | if (!root_inode) | 728 | if (!root_inode) |
742 | goto out_mntput; | 729 | goto out_mntput; |
743 | 730 | ||
diff --git a/fs/libfs.c b/fs/libfs.c index c88eab55aec9..275ca4749a2e 100644 --- a/fs/libfs.c +++ b/fs/libfs.c | |||
@@ -822,7 +822,7 @@ ssize_t simple_attr_write(struct file *file, const char __user *buf, | |||
822 | goto out; | 822 | goto out; |
823 | 823 | ||
824 | attr->set_buf[size] = '\0'; | 824 | attr->set_buf[size] = '\0'; |
825 | val = simple_strtol(attr->set_buf, NULL, 0); | 825 | val = simple_strtoll(attr->set_buf, NULL, 0); |
826 | ret = attr->set(attr->data, val); | 826 | ret = attr->set(attr->data, val); |
827 | if (ret == 0) | 827 | if (ret == 0) |
828 | ret = len; /* on success, claim we got the whole input */ | 828 | ret = len; /* on success, claim we got the whole input */ |
diff --git a/fs/locks.c b/fs/locks.c index 0a4f50dfadfb..b286539d547a 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -160,10 +160,28 @@ EXPORT_SYMBOL_GPL(unlock_flocks); | |||
160 | 160 | ||
161 | static struct kmem_cache *filelock_cache __read_mostly; | 161 | static struct kmem_cache *filelock_cache __read_mostly; |
162 | 162 | ||
163 | static void locks_init_lock_always(struct file_lock *fl) | ||
164 | { | ||
165 | fl->fl_next = NULL; | ||
166 | fl->fl_fasync = NULL; | ||
167 | fl->fl_owner = NULL; | ||
168 | fl->fl_pid = 0; | ||
169 | fl->fl_nspid = NULL; | ||
170 | fl->fl_file = NULL; | ||
171 | fl->fl_flags = 0; | ||
172 | fl->fl_type = 0; | ||
173 | fl->fl_start = fl->fl_end = 0; | ||
174 | } | ||
175 | |||
163 | /* Allocate an empty lock structure. */ | 176 | /* Allocate an empty lock structure. */ |
164 | struct file_lock *locks_alloc_lock(void) | 177 | struct file_lock *locks_alloc_lock(void) |
165 | { | 178 | { |
166 | return kmem_cache_alloc(filelock_cache, GFP_KERNEL); | 179 | struct file_lock *fl = kmem_cache_alloc(filelock_cache, GFP_KERNEL); |
180 | |||
181 | if (fl) | ||
182 | locks_init_lock_always(fl); | ||
183 | |||
184 | return fl; | ||
167 | } | 185 | } |
168 | EXPORT_SYMBOL_GPL(locks_alloc_lock); | 186 | EXPORT_SYMBOL_GPL(locks_alloc_lock); |
169 | 187 | ||
@@ -200,17 +218,9 @@ void locks_init_lock(struct file_lock *fl) | |||
200 | INIT_LIST_HEAD(&fl->fl_link); | 218 | INIT_LIST_HEAD(&fl->fl_link); |
201 | INIT_LIST_HEAD(&fl->fl_block); | 219 | INIT_LIST_HEAD(&fl->fl_block); |
202 | init_waitqueue_head(&fl->fl_wait); | 220 | init_waitqueue_head(&fl->fl_wait); |
203 | fl->fl_next = NULL; | ||
204 | fl->fl_fasync = NULL; | ||
205 | fl->fl_owner = NULL; | ||
206 | fl->fl_pid = 0; | ||
207 | fl->fl_nspid = NULL; | ||
208 | fl->fl_file = NULL; | ||
209 | fl->fl_flags = 0; | ||
210 | fl->fl_type = 0; | ||
211 | fl->fl_start = fl->fl_end = 0; | ||
212 | fl->fl_ops = NULL; | 221 | fl->fl_ops = NULL; |
213 | fl->fl_lmops = NULL; | 222 | fl->fl_lmops = NULL; |
223 | locks_init_lock_always(fl); | ||
214 | } | 224 | } |
215 | 225 | ||
216 | EXPORT_SYMBOL(locks_init_lock); | 226 | EXPORT_SYMBOL(locks_init_lock); |
diff --git a/fs/namei.c b/fs/namei.c index 0223c41fb114..14ab8d3f2f0c 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -433,6 +433,8 @@ static int unlazy_walk(struct nameidata *nd, struct dentry *dentry) | |||
433 | goto err_parent; | 433 | goto err_parent; |
434 | BUG_ON(nd->inode != parent->d_inode); | 434 | BUG_ON(nd->inode != parent->d_inode); |
435 | } else { | 435 | } else { |
436 | if (dentry->d_parent != parent) | ||
437 | goto err_parent; | ||
436 | spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); | 438 | spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); |
437 | if (!__d_rcu_to_refcount(dentry, nd->seq)) | 439 | if (!__d_rcu_to_refcount(dentry, nd->seq)) |
438 | goto err_child; | 440 | goto err_child; |
@@ -940,7 +942,6 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, | |||
940 | * Don't forget we might have a non-mountpoint managed dentry | 942 | * Don't forget we might have a non-mountpoint managed dentry |
941 | * that wants to block transit. | 943 | * that wants to block transit. |
942 | */ | 944 | */ |
943 | *inode = path->dentry->d_inode; | ||
944 | if (unlikely(managed_dentry_might_block(path->dentry))) | 945 | if (unlikely(managed_dentry_might_block(path->dentry))) |
945 | return false; | 946 | return false; |
946 | 947 | ||
@@ -953,6 +954,12 @@ static bool __follow_mount_rcu(struct nameidata *nd, struct path *path, | |||
953 | path->mnt = mounted; | 954 | path->mnt = mounted; |
954 | path->dentry = mounted->mnt_root; | 955 | path->dentry = mounted->mnt_root; |
955 | nd->seq = read_seqcount_begin(&path->dentry->d_seq); | 956 | nd->seq = read_seqcount_begin(&path->dentry->d_seq); |
957 | /* | ||
958 | * Update the inode too. We don't need to re-check the | ||
959 | * dentry sequence number here after this d_inode read, | ||
960 | * because a mount-point is always pinned. | ||
961 | */ | ||
962 | *inode = path->dentry->d_inode; | ||
956 | } | 963 | } |
957 | return true; | 964 | return true; |
958 | } | 965 | } |
diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c index ce153a6b3aec..419119c371bf 100644 --- a/fs/nfs/fscache.c +++ b/fs/nfs/fscache.c | |||
@@ -259,12 +259,10 @@ static void nfs_fscache_disable_inode_cookie(struct inode *inode) | |||
259 | dfprintk(FSCACHE, | 259 | dfprintk(FSCACHE, |
260 | "NFS: nfsi 0x%p turning cache off\n", NFS_I(inode)); | 260 | "NFS: nfsi 0x%p turning cache off\n", NFS_I(inode)); |
261 | 261 | ||
262 | /* Need to invalidate any mapped pages that were read in before | 262 | /* Need to uncache any pages attached to this inode that |
263 | * turning off the cache. | 263 | * fscache knows about before turning off the cache. |
264 | */ | 264 | */ |
265 | if (inode->i_mapping && inode->i_mapping->nrpages) | 265 | fscache_uncache_all_inode_pages(NFS_I(inode)->fscache, inode); |
266 | invalidate_inode_pages2(inode->i_mapping); | ||
267 | |||
268 | nfs_fscache_zap_inode_cookie(inode); | 266 | nfs_fscache_zap_inode_cookie(inode); |
269 | } | 267 | } |
270 | } | 268 | } |
diff --git a/fs/nfs/nfs4filelayout.c b/fs/nfs/nfs4filelayout.c index 0bafcc91c27f..f9d03abcd04c 100644 --- a/fs/nfs/nfs4filelayout.c +++ b/fs/nfs/nfs4filelayout.c | |||
@@ -398,7 +398,6 @@ filelayout_write_pagelist(struct nfs_write_data *data, int sync) | |||
398 | * this offset and save the original offset. | 398 | * this offset and save the original offset. |
399 | */ | 399 | */ |
400 | data->args.offset = filelayout_get_dserver_offset(lseg, offset); | 400 | data->args.offset = filelayout_get_dserver_offset(lseg, offset); |
401 | data->mds_offset = offset; | ||
402 | 401 | ||
403 | /* Perform an asynchronous write */ | 402 | /* Perform an asynchronous write */ |
404 | status = nfs_initiate_write(data, ds->ds_clp->cl_rpcclient, | 403 | status = nfs_initiate_write(data, ds->ds_clp->cl_rpcclient, |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 6870bc61ceec..e6e8f3b9a1de 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -91,7 +91,7 @@ static int nfs4_stat_to_errno(int); | |||
91 | #define encode_getfh_maxsz (op_encode_hdr_maxsz) | 91 | #define encode_getfh_maxsz (op_encode_hdr_maxsz) |
92 | #define decode_getfh_maxsz (op_decode_hdr_maxsz + 1 + \ | 92 | #define decode_getfh_maxsz (op_decode_hdr_maxsz + 1 + \ |
93 | ((3+NFS4_FHSIZE) >> 2)) | 93 | ((3+NFS4_FHSIZE) >> 2)) |
94 | #define nfs4_fattr_bitmap_maxsz 3 | 94 | #define nfs4_fattr_bitmap_maxsz 4 |
95 | #define encode_getattr_maxsz (op_encode_hdr_maxsz + nfs4_fattr_bitmap_maxsz) | 95 | #define encode_getattr_maxsz (op_encode_hdr_maxsz + nfs4_fattr_bitmap_maxsz) |
96 | #define nfs4_name_maxsz (1 + ((3 + NFS4_MAXNAMLEN) >> 2)) | 96 | #define nfs4_name_maxsz (1 + ((3 + NFS4_MAXNAMLEN) >> 2)) |
97 | #define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2)) | 97 | #define nfs4_path_maxsz (1 + ((3 + NFS4_MAXPATHLEN) >> 2)) |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index e268e3b23497..727168059684 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -864,6 +864,8 @@ static int nfs_write_rpcsetup(struct nfs_page *req, | |||
864 | 864 | ||
865 | data->args.fh = NFS_FH(inode); | 865 | data->args.fh = NFS_FH(inode); |
866 | data->args.offset = req_offset(req) + offset; | 866 | data->args.offset = req_offset(req) + offset; |
867 | /* pnfs_set_layoutcommit needs this */ | ||
868 | data->mds_offset = data->args.offset; | ||
867 | data->args.pgbase = req->wb_pgbase + offset; | 869 | data->args.pgbase = req->wb_pgbase + offset; |
868 | data->args.pages = data->pagevec; | 870 | data->args.pages = data->pagevec; |
869 | data->args.count = count; | 871 | data->args.count = count; |
diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index 29309e25417f..b57aab9a1184 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c | |||
@@ -56,16 +56,12 @@ static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry, stru | |||
56 | 56 | ||
57 | lock_ufs(dir->i_sb); | 57 | lock_ufs(dir->i_sb); |
58 | ino = ufs_inode_by_name(dir, &dentry->d_name); | 58 | ino = ufs_inode_by_name(dir, &dentry->d_name); |
59 | if (ino) { | 59 | if (ino) |
60 | inode = ufs_iget(dir->i_sb, ino); | 60 | inode = ufs_iget(dir->i_sb, ino); |
61 | if (IS_ERR(inode)) { | ||
62 | unlock_ufs(dir->i_sb); | ||
63 | return ERR_CAST(inode); | ||
64 | } | ||
65 | } | ||
66 | unlock_ufs(dir->i_sb); | 61 | unlock_ufs(dir->i_sb); |
67 | d_add(dentry, inode); | 62 | if (IS_ERR(inode)) |
68 | return NULL; | 63 | return ERR_CAST(inode); |
64 | return d_splice_alias(inode, dentry); | ||
69 | } | 65 | } |
70 | 66 | ||
71 | /* | 67 | /* |
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 09983a3344a5..b1e88d56069c 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c | |||
@@ -681,15 +681,15 @@ xfs_inode_item_unlock( | |||
681 | * where the cluster buffer may be unpinned before the inode is inserted into | 681 | * where the cluster buffer may be unpinned before the inode is inserted into |
682 | * the AIL during transaction committed processing. If the buffer is unpinned | 682 | * the AIL during transaction committed processing. If the buffer is unpinned |
683 | * before the inode item has been committed and inserted, then it is possible | 683 | * before the inode item has been committed and inserted, then it is possible |
684 | * for the buffer to be written and IO completions before the inode is inserted | 684 | * for the buffer to be written and IO completes before the inode is inserted |
685 | * into the AIL. In that case, we'd be inserting a clean, stale inode into the | 685 | * into the AIL. In that case, we'd be inserting a clean, stale inode into the |
686 | * AIL which will never get removed. It will, however, get reclaimed which | 686 | * AIL which will never get removed. It will, however, get reclaimed which |
687 | * triggers an assert in xfs_inode_free() complaining about freein an inode | 687 | * triggers an assert in xfs_inode_free() complaining about freein an inode |
688 | * still in the AIL. | 688 | * still in the AIL. |
689 | * | 689 | * |
690 | * To avoid this, return a lower LSN than the one passed in so that the | 690 | * To avoid this, just unpin the inode directly and return a LSN of -1 so the |
691 | * transaction committed code will not move the inode forward in the AIL but | 691 | * transaction committed code knows that it does not need to do any further |
692 | * will still unpin it properly. | 692 | * processing on the item. |
693 | */ | 693 | */ |
694 | STATIC xfs_lsn_t | 694 | STATIC xfs_lsn_t |
695 | xfs_inode_item_committed( | 695 | xfs_inode_item_committed( |
@@ -699,8 +699,10 @@ xfs_inode_item_committed( | |||
699 | struct xfs_inode_log_item *iip = INODE_ITEM(lip); | 699 | struct xfs_inode_log_item *iip = INODE_ITEM(lip); |
700 | struct xfs_inode *ip = iip->ili_inode; | 700 | struct xfs_inode *ip = iip->ili_inode; |
701 | 701 | ||
702 | if (xfs_iflags_test(ip, XFS_ISTALE)) | 702 | if (xfs_iflags_test(ip, XFS_ISTALE)) { |
703 | return lsn - 1; | 703 | xfs_inode_item_unpin(lip, 0); |
704 | return -1; | ||
705 | } | ||
704 | return lsn; | 706 | return lsn; |
705 | } | 707 | } |
706 | 708 | ||
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 7c7bc2b786bd..c83f63b33aae 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
@@ -1361,7 +1361,7 @@ xfs_trans_item_committed( | |||
1361 | lip->li_flags |= XFS_LI_ABORTED; | 1361 | lip->li_flags |= XFS_LI_ABORTED; |
1362 | item_lsn = IOP_COMMITTED(lip, commit_lsn); | 1362 | item_lsn = IOP_COMMITTED(lip, commit_lsn); |
1363 | 1363 | ||
1364 | /* If the committed routine returns -1, item has been freed. */ | 1364 | /* item_lsn of -1 means the item needs no further processing */ |
1365 | if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) | 1365 | if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) |
1366 | return; | 1366 | return; |
1367 | 1367 | ||
@@ -1474,7 +1474,7 @@ xfs_trans_committed_bulk( | |||
1474 | lip->li_flags |= XFS_LI_ABORTED; | 1474 | lip->li_flags |= XFS_LI_ABORTED; |
1475 | item_lsn = IOP_COMMITTED(lip, commit_lsn); | 1475 | item_lsn = IOP_COMMITTED(lip, commit_lsn); |
1476 | 1476 | ||
1477 | /* item_lsn of -1 means the item was freed */ | 1477 | /* item_lsn of -1 means the item needs no further processing */ |
1478 | if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) | 1478 | if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) |
1479 | continue; | 1479 | continue; |
1480 | 1480 | ||
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 3a10ef5914eb..6cd5b6403a7b 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -210,7 +210,7 @@ struct acpi_device_power_state { | |||
210 | struct acpi_device_power { | 210 | struct acpi_device_power { |
211 | int state; /* Current state */ | 211 | int state; /* Current state */ |
212 | struct acpi_device_power_flags flags; | 212 | struct acpi_device_power_flags flags; |
213 | struct acpi_device_power_state states[4]; /* Power states (D0-D3) */ | 213 | struct acpi_device_power_state states[ACPI_D_STATE_COUNT]; /* Power states (D0-D3Cold) */ |
214 | }; | 214 | }; |
215 | 215 | ||
216 | /* Performance Management */ | 216 | /* Performance Management */ |
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h index a756bc8d866d..4543b6f75867 100644 --- a/include/acpi/acpiosxf.h +++ b/include/acpi/acpiosxf.h | |||
@@ -98,8 +98,11 @@ acpi_os_table_override(struct acpi_table_header *existing_table, | |||
98 | /* | 98 | /* |
99 | * Spinlock primitives | 99 | * Spinlock primitives |
100 | */ | 100 | */ |
101 | |||
102 | #ifndef acpi_os_create_lock | ||
101 | acpi_status | 103 | acpi_status |
102 | acpi_os_create_lock(acpi_spinlock *out_handle); | 104 | acpi_os_create_lock(acpi_spinlock *out_handle); |
105 | #endif | ||
103 | 106 | ||
104 | void acpi_os_delete_lock(acpi_spinlock handle); | 107 | void acpi_os_delete_lock(acpi_spinlock handle); |
105 | 108 | ||
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h index 5d2a5e9544d9..2ce1be9f6291 100644 --- a/include/acpi/platform/aclinux.h +++ b/include/acpi/platform/aclinux.h | |||
@@ -159,6 +159,24 @@ static inline void *acpi_os_acquire_object(acpi_cache_t * cache) | |||
159 | } while (0) | 159 | } while (0) |
160 | #endif | 160 | #endif |
161 | 161 | ||
162 | /* | ||
163 | * When lockdep is enabled, the spin_lock_init() macro stringifies it's | ||
164 | * argument and uses that as a name for the lock in debugging. | ||
165 | * By executing spin_lock_init() in a macro the key changes from "lock" for | ||
166 | * all locks to the name of the argument of acpi_os_create_lock(), which | ||
167 | * prevents lockdep from reporting false positives for ACPICA locks. | ||
168 | */ | ||
169 | #define acpi_os_create_lock(__handle) \ | ||
170 | ({ \ | ||
171 | spinlock_t *lock = ACPI_ALLOCATE(sizeof(*lock)); \ | ||
172 | \ | ||
173 | if (lock) { \ | ||
174 | *(__handle) = lock; \ | ||
175 | spin_lock_init(*(__handle)); \ | ||
176 | } \ | ||
177 | lock ? AE_OK : AE_NO_MEMORY; \ | ||
178 | }) | ||
179 | |||
162 | #endif /* __KERNEL__ */ | 180 | #endif /* __KERNEL__ */ |
163 | 181 | ||
164 | #endif /* __ACLINUX_H__ */ | 182 | #endif /* __ACLINUX_H__ */ |
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index e08f344c6cff..3d53efd25ab9 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h | |||
@@ -182,6 +182,7 @@ | |||
182 | {0x1002, 0x6750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ | 182 | {0x1002, 0x6750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ |
183 | {0x1002, 0x6758, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ | 183 | {0x1002, 0x6758, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ |
184 | {0x1002, 0x6759, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ | 184 | {0x1002, 0x6759, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ |
185 | {0x1002, 0x675F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TURKS|RADEON_NEW_MEMMAP}, \ | ||
185 | {0x1002, 0x6760, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 186 | {0x1002, 0x6760, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
186 | {0x1002, 0x6761, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 187 | {0x1002, 0x6761, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
187 | {0x1002, 0x6762, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ | 188 | {0x1002, 0x6762, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ |
@@ -192,6 +193,7 @@ | |||
192 | {0x1002, 0x6767, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ | 193 | {0x1002, 0x6767, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ |
193 | {0x1002, 0x6768, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ | 194 | {0x1002, 0x6768, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ |
194 | {0x1002, 0x6770, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ | 195 | {0x1002, 0x6770, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ |
196 | {0x1002, 0x6778, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ | ||
195 | {0x1002, 0x6779, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ | 197 | {0x1002, 0x6779, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CAICOS|RADEON_NEW_MEMMAP}, \ |
196 | {0x1002, 0x6880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 198 | {0x1002, 0x6880, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
197 | {0x1002, 0x6888, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ | 199 | {0x1002, 0x6888, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_CYPRESS|RADEON_NEW_MEMMAP}, \ |
diff --git a/include/linux/drbd_limits.h b/include/linux/drbd_limits.h index 246f576c981d..447c36752385 100644 --- a/include/linux/drbd_limits.h +++ b/include/linux/drbd_limits.h | |||
@@ -117,10 +117,10 @@ | |||
117 | /* drbdsetup XY resize -d Z | 117 | /* drbdsetup XY resize -d Z |
118 | * you are free to reduce the device size to nothing, if you want to. | 118 | * you are free to reduce the device size to nothing, if you want to. |
119 | * the upper limit with 64bit kernel, enough ram and flexible meta data | 119 | * the upper limit with 64bit kernel, enough ram and flexible meta data |
120 | * is 16 TB, currently. */ | 120 | * is 1 PiB, currently. */ |
121 | /* DRBD_MAX_SECTORS */ | 121 | /* DRBD_MAX_SECTORS */ |
122 | #define DRBD_DISK_SIZE_SECT_MIN 0 | 122 | #define DRBD_DISK_SIZE_SECT_MIN 0 |
123 | #define DRBD_DISK_SIZE_SECT_MAX (16 * (2LLU << 30)) | 123 | #define DRBD_DISK_SIZE_SECT_MAX (1 * (2LLU << 40)) |
124 | #define DRBD_DISK_SIZE_SECT_DEF 0 /* = disabled = no user size... */ | 124 | #define DRBD_DISK_SIZE_SECT_DEF 0 /* = disabled = no user size... */ |
125 | 125 | ||
126 | #define DRBD_ON_IO_ERROR_DEF EP_PASS_ON | 126 | #define DRBD_ON_IO_ERROR_DEF EP_PASS_ON |
diff --git a/include/linux/fscache.h b/include/linux/fscache.h index 7c4d72f5581f..9ec20dec3353 100644 --- a/include/linux/fscache.h +++ b/include/linux/fscache.h | |||
@@ -204,6 +204,8 @@ extern bool __fscache_check_page_write(struct fscache_cookie *, struct page *); | |||
204 | extern void __fscache_wait_on_page_write(struct fscache_cookie *, struct page *); | 204 | extern void __fscache_wait_on_page_write(struct fscache_cookie *, struct page *); |
205 | extern bool __fscache_maybe_release_page(struct fscache_cookie *, struct page *, | 205 | extern bool __fscache_maybe_release_page(struct fscache_cookie *, struct page *, |
206 | gfp_t); | 206 | gfp_t); |
207 | extern void __fscache_uncache_all_inode_pages(struct fscache_cookie *, | ||
208 | struct inode *); | ||
207 | 209 | ||
208 | /** | 210 | /** |
209 | * fscache_register_netfs - Register a filesystem as desiring caching services | 211 | * fscache_register_netfs - Register a filesystem as desiring caching services |
@@ -643,4 +645,23 @@ bool fscache_maybe_release_page(struct fscache_cookie *cookie, | |||
643 | return false; | 645 | return false; |
644 | } | 646 | } |
645 | 647 | ||
648 | /** | ||
649 | * fscache_uncache_all_inode_pages - Uncache all an inode's pages | ||
650 | * @cookie: The cookie representing the inode's cache object. | ||
651 | * @inode: The inode to uncache pages from. | ||
652 | * | ||
653 | * Uncache all the pages in an inode that are marked PG_fscache, assuming them | ||
654 | * to be associated with the given cookie. | ||
655 | * | ||
656 | * This function may sleep. It will wait for pages that are being written out | ||
657 | * and will wait whilst the PG_fscache mark is removed by the cache. | ||
658 | */ | ||
659 | static inline | ||
660 | void fscache_uncache_all_inode_pages(struct fscache_cookie *cookie, | ||
661 | struct inode *inode) | ||
662 | { | ||
663 | if (fscache_cookie_valid(cookie)) | ||
664 | __fscache_uncache_all_inode_pages(cookie, inode); | ||
665 | } | ||
666 | |||
646 | #endif /* _LINUX_FSCACHE_H */ | 667 | #endif /* _LINUX_FSCACHE_H */ |
diff --git a/include/linux/irq.h b/include/linux/irq.h index 8b4538446636..baa397eb9c33 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -676,7 +676,8 @@ void irq_gc_mask_disable_reg(struct irq_data *d); | |||
676 | void irq_gc_mask_set_bit(struct irq_data *d); | 676 | void irq_gc_mask_set_bit(struct irq_data *d); |
677 | void irq_gc_mask_clr_bit(struct irq_data *d); | 677 | void irq_gc_mask_clr_bit(struct irq_data *d); |
678 | void irq_gc_unmask_enable_reg(struct irq_data *d); | 678 | void irq_gc_unmask_enable_reg(struct irq_data *d); |
679 | void irq_gc_ack(struct irq_data *d); | 679 | void irq_gc_ack_set_bit(struct irq_data *d); |
680 | void irq_gc_ack_clr_bit(struct irq_data *d); | ||
680 | void irq_gc_mask_disable_reg_and_ack(struct irq_data *d); | 681 | void irq_gc_mask_disable_reg_and_ack(struct irq_data *d); |
681 | void irq_gc_eoi(struct irq_data *d); | 682 | void irq_gc_eoi(struct irq_data *d); |
682 | int irq_gc_set_wake(struct irq_data *d, unsigned int on); | 683 | int irq_gc_set_wake(struct irq_data *d, unsigned int on); |
diff --git a/include/linux/memory.h b/include/linux/memory.h index e1e3b2b84f85..935699b30b7c 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h | |||
@@ -20,6 +20,8 @@ | |||
20 | #include <linux/compiler.h> | 20 | #include <linux/compiler.h> |
21 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
22 | 22 | ||
23 | #define MIN_MEMORY_BLOCK_SIZE (1 << SECTION_SIZE_BITS) | ||
24 | |||
23 | struct memory_block { | 25 | struct memory_block { |
24 | unsigned long start_section_nr; | 26 | unsigned long start_section_nr; |
25 | unsigned long end_section_nr; | 27 | unsigned long end_section_nr; |
diff --git a/include/linux/mfd/ds1wm.h b/include/linux/mfd/ds1wm.h index be469a357cbb..38a372a0e285 100644 --- a/include/linux/mfd/ds1wm.h +++ b/include/linux/mfd/ds1wm.h | |||
@@ -3,4 +3,11 @@ | |||
3 | struct ds1wm_driver_data { | 3 | struct ds1wm_driver_data { |
4 | int active_high; | 4 | int active_high; |
5 | int clock_rate; | 5 | int clock_rate; |
6 | /* in milliseconds, the amount of time to */ | ||
7 | /* sleep following a reset pulse. Zero */ | ||
8 | /* should work if your bus devices recover*/ | ||
9 | /* time respects the 1-wire spec since the*/ | ||
10 | /* ds1wm implements the precise timings of*/ | ||
11 | /* a reset pulse/presence detect sequence.*/ | ||
12 | unsigned int reset_recover_delay; | ||
6 | }; | 13 | }; |
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index c6927a4d157f..6ad43554ac05 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h | |||
@@ -64,6 +64,19 @@ struct mmc_ext_csd { | |||
64 | unsigned long long enhanced_area_offset; /* Units: Byte */ | 64 | unsigned long long enhanced_area_offset; /* Units: Byte */ |
65 | unsigned int enhanced_area_size; /* Units: KB */ | 65 | unsigned int enhanced_area_size; /* Units: KB */ |
66 | unsigned int boot_size; /* in bytes */ | 66 | unsigned int boot_size; /* in bytes */ |
67 | u8 raw_partition_support; /* 160 */ | ||
68 | u8 raw_erased_mem_count; /* 181 */ | ||
69 | u8 raw_ext_csd_structure; /* 194 */ | ||
70 | u8 raw_card_type; /* 196 */ | ||
71 | u8 raw_s_a_timeout; /* 217 */ | ||
72 | u8 raw_hc_erase_gap_size; /* 221 */ | ||
73 | u8 raw_erase_timeout_mult; /* 223 */ | ||
74 | u8 raw_hc_erase_grp_size; /* 224 */ | ||
75 | u8 raw_sec_trim_mult; /* 229 */ | ||
76 | u8 raw_sec_erase_mult; /* 230 */ | ||
77 | u8 raw_sec_feature_support;/* 231 */ | ||
78 | u8 raw_trim_mult; /* 232 */ | ||
79 | u8 raw_sectors[4]; /* 212 - 4 bytes */ | ||
67 | }; | 80 | }; |
68 | 81 | ||
69 | struct sd_scr { | 82 | struct sd_scr { |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 54b8b4d7b68f..9e19477991ad 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -1097,12 +1097,6 @@ struct net_device { | |||
1097 | #define NETIF_F_ALL_FCOE (NETIF_F_FCOE_CRC | NETIF_F_FCOE_MTU | \ | 1097 | #define NETIF_F_ALL_FCOE (NETIF_F_FCOE_CRC | NETIF_F_FCOE_MTU | \ |
1098 | NETIF_F_FSO) | 1098 | NETIF_F_FSO) |
1099 | 1099 | ||
1100 | #define NETIF_F_ALL_TX_OFFLOADS (NETIF_F_ALL_CSUM | NETIF_F_SG | \ | ||
1101 | NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | \ | ||
1102 | NETIF_F_HIGHDMA | \ | ||
1103 | NETIF_F_SCTP_CSUM | \ | ||
1104 | NETIF_F_ALL_FCOE) | ||
1105 | |||
1106 | /* | 1100 | /* |
1107 | * If one device supports one of these features, then enable them | 1101 | * If one device supports one of these features, then enable them |
1108 | * for all in netdev_increment_features. | 1102 | * for all in netdev_increment_features. |
diff --git a/include/linux/sched.h b/include/linux/sched.h index a837b20ba190..14a6c7b545de 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -808,7 +808,7 @@ enum cpu_idle_type { | |||
808 | * when BITS_PER_LONG <= 32 are pretty high and the returns do not justify the | 808 | * when BITS_PER_LONG <= 32 are pretty high and the returns do not justify the |
809 | * increased costs. | 809 | * increased costs. |
810 | */ | 810 | */ |
811 | #if BITS_PER_LONG > 32 | 811 | #if 0 /* BITS_PER_LONG > 32 -- currently broken: it increases power usage under light load */ |
812 | # define SCHED_LOAD_RESOLUTION 10 | 812 | # define SCHED_LOAD_RESOLUTION 10 |
813 | # define scale_load(w) ((w) << SCHED_LOAD_RESOLUTION) | 813 | # define scale_load(w) ((w) << SCHED_LOAD_RESOLUTION) |
814 | # define scale_load_down(w) ((w) >> SCHED_LOAD_RESOLUTION) | 814 | # define scale_load_down(w) ((w) >> SCHED_LOAD_RESOLUTION) |
@@ -844,6 +844,7 @@ enum cpu_idle_type { | |||
844 | #define SD_SERIALIZE 0x0400 /* Only a single load balancing instance */ | 844 | #define SD_SERIALIZE 0x0400 /* Only a single load balancing instance */ |
845 | #define SD_ASYM_PACKING 0x0800 /* Place busy groups earlier in the domain */ | 845 | #define SD_ASYM_PACKING 0x0800 /* Place busy groups earlier in the domain */ |
846 | #define SD_PREFER_SIBLING 0x1000 /* Prefer to place tasks in a sibling domain */ | 846 | #define SD_PREFER_SIBLING 0x1000 /* Prefer to place tasks in a sibling domain */ |
847 | #define SD_OVERLAP 0x2000 /* sched_domains of this level overlap */ | ||
847 | 848 | ||
848 | enum powersavings_balance_level { | 849 | enum powersavings_balance_level { |
849 | POWERSAVINGS_BALANCE_NONE = 0, /* No power saving load balance */ | 850 | POWERSAVINGS_BALANCE_NONE = 0, /* No power saving load balance */ |
@@ -893,16 +894,21 @@ static inline int sd_power_saving_flags(void) | |||
893 | return 0; | 894 | return 0; |
894 | } | 895 | } |
895 | 896 | ||
896 | struct sched_group { | 897 | struct sched_group_power { |
897 | struct sched_group *next; /* Must be a circular list */ | ||
898 | atomic_t ref; | 898 | atomic_t ref; |
899 | |||
900 | /* | 899 | /* |
901 | * CPU power of this group, SCHED_LOAD_SCALE being max power for a | 900 | * CPU power of this group, SCHED_LOAD_SCALE being max power for a |
902 | * single CPU. | 901 | * single CPU. |
903 | */ | 902 | */ |
904 | unsigned int cpu_power, cpu_power_orig; | 903 | unsigned int power, power_orig; |
904 | }; | ||
905 | |||
906 | struct sched_group { | ||
907 | struct sched_group *next; /* Must be a circular list */ | ||
908 | atomic_t ref; | ||
909 | |||
905 | unsigned int group_weight; | 910 | unsigned int group_weight; |
911 | struct sched_group_power *sgp; | ||
906 | 912 | ||
907 | /* | 913 | /* |
908 | * The CPUs this group covers. | 914 | * The CPUs this group covers. |
@@ -1254,6 +1260,9 @@ struct task_struct { | |||
1254 | #ifdef CONFIG_PREEMPT_RCU | 1260 | #ifdef CONFIG_PREEMPT_RCU |
1255 | int rcu_read_lock_nesting; | 1261 | int rcu_read_lock_nesting; |
1256 | char rcu_read_unlock_special; | 1262 | char rcu_read_unlock_special; |
1263 | #if defined(CONFIG_RCU_BOOST) && defined(CONFIG_TREE_PREEMPT_RCU) | ||
1264 | int rcu_boosted; | ||
1265 | #endif /* #if defined(CONFIG_RCU_BOOST) && defined(CONFIG_TREE_PREEMPT_RCU) */ | ||
1257 | struct list_head rcu_node_entry; | 1266 | struct list_head rcu_node_entry; |
1258 | #endif /* #ifdef CONFIG_PREEMPT_RCU */ | 1267 | #endif /* #ifdef CONFIG_PREEMPT_RCU */ |
1259 | #ifdef CONFIG_TREE_PREEMPT_RCU | 1268 | #ifdef CONFIG_TREE_PREEMPT_RCU |
diff --git a/include/linux/sdla.h b/include/linux/sdla.h index 564acd3a71c1..9995c7fc3f60 100644 --- a/include/linux/sdla.h +++ b/include/linux/sdla.h | |||
@@ -112,11 +112,7 @@ struct sdla_dlci_conf { | |||
112 | short Tb_max; | 112 | short Tb_max; |
113 | }; | 113 | }; |
114 | 114 | ||
115 | #ifndef __KERNEL__ | 115 | #ifdef __KERNEL__ |
116 | |||
117 | void sdla(void *cfg_info, char *dev, struct frad_conf *conf, int quiet); | ||
118 | |||
119 | #else | ||
120 | 116 | ||
121 | /* important Z80 window addresses */ | 117 | /* important Z80 window addresses */ |
122 | #define SDLA_CONTROL_WND 0xE000 | 118 | #define SDLA_CONTROL_WND 0xE000 |
diff --git a/include/media/lirc_dev.h b/include/media/lirc_dev.h index 630e702c9511..168dd0b1bae2 100644 --- a/include/media/lirc_dev.h +++ b/include/media/lirc_dev.h | |||
@@ -9,7 +9,7 @@ | |||
9 | #ifndef _LINUX_LIRC_DEV_H | 9 | #ifndef _LINUX_LIRC_DEV_H |
10 | #define _LINUX_LIRC_DEV_H | 10 | #define _LINUX_LIRC_DEV_H |
11 | 11 | ||
12 | #define MAX_IRCTL_DEVICES 4 | 12 | #define MAX_IRCTL_DEVICES 8 |
13 | #define BUFLEN 16 | 13 | #define BUFLEN 16 |
14 | 14 | ||
15 | #define mod(n, div) ((n) % (div)) | 15 | #define mod(n, div) ((n) % (div)) |
diff --git a/include/media/m5mols.h b/include/media/m5mols.h index 2d7e7ca2313d..aac2c0e06d5e 100644 --- a/include/media/m5mols.h +++ b/include/media/m5mols.h | |||
@@ -2,10 +2,10 @@ | |||
2 | * Driver header for M-5MOLS 8M Pixel camera sensor with ISP | 2 | * Driver header for M-5MOLS 8M Pixel camera sensor with ISP |
3 | * | 3 | * |
4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. | 4 | * Copyright (C) 2011 Samsung Electronics Co., Ltd. |
5 | * Author: HeungJun Kim, riverful.kim@samsung.com | 5 | * Author: HeungJun Kim <riverful.kim@samsung.com> |
6 | * | 6 | * |
7 | * Copyright (C) 2009 Samsung Electronics Co., Ltd. | 7 | * Copyright (C) 2009 Samsung Electronics Co., Ltd. |
8 | * Author: Dongsoo Nathaniel Kim, dongsoo45.kim@samsung.com | 8 | * Author: Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com> |
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 as published by | 11 | * it under the terms of the GNU General Public License as published by |
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h index 1562c4ff3a65..2884e3e69cb1 100644 --- a/include/media/v4l2-subdev.h +++ b/include/media/v4l2-subdev.h | |||
@@ -173,16 +173,20 @@ struct v4l2_subdev_core_ops { | |||
173 | struct v4l2_event_subscription *sub); | 173 | struct v4l2_event_subscription *sub); |
174 | }; | 174 | }; |
175 | 175 | ||
176 | /* s_mode: switch the tuner to a specific tuner mode. Replacement of s_radio. | 176 | /* s_radio: v4l device was opened in radio mode. |
177 | 177 | ||
178 | s_radio: v4l device was opened in Radio mode, to be replaced by s_mode. | 178 | g_frequency: freq->type must be filled in. Normally done by video_ioctl2 |
179 | or the bridge driver. | ||
180 | |||
181 | g_tuner: | ||
182 | s_tuner: vt->type must be filled in. Normally done by video_ioctl2 or the | ||
183 | bridge driver. | ||
179 | 184 | ||
180 | s_type_addr: sets tuner type and its I2C addr. | 185 | s_type_addr: sets tuner type and its I2C addr. |
181 | 186 | ||
182 | s_config: sets tda9887 specific stuff, like port1, port2 and qss | 187 | s_config: sets tda9887 specific stuff, like port1, port2 and qss |
183 | */ | 188 | */ |
184 | struct v4l2_subdev_tuner_ops { | 189 | struct v4l2_subdev_tuner_ops { |
185 | int (*s_mode)(struct v4l2_subdev *sd, enum v4l2_tuner_type); | ||
186 | int (*s_radio)(struct v4l2_subdev *sd); | 190 | int (*s_radio)(struct v4l2_subdev *sd); |
187 | int (*s_frequency)(struct v4l2_subdev *sd, struct v4l2_frequency *freq); | 191 | int (*s_frequency)(struct v4l2_subdev *sd, struct v4l2_frequency *freq); |
188 | int (*g_frequency)(struct v4l2_subdev *sd, struct v4l2_frequency *freq); | 192 | int (*g_frequency)(struct v4l2_subdev *sd, struct v4l2_frequency *freq); |
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index 0589f554788a..396e8fc8910e 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h | |||
@@ -2688,7 +2688,7 @@ void cfg80211_send_unprot_disassoc(struct net_device *dev, const u8 *buf, | |||
2688 | * @dev: network device | 2688 | * @dev: network device |
2689 | * @addr: The source MAC address of the frame | 2689 | * @addr: The source MAC address of the frame |
2690 | * @key_type: The key type that the received frame used | 2690 | * @key_type: The key type that the received frame used |
2691 | * @key_id: Key identifier (0..3) | 2691 | * @key_id: Key identifier (0..3). Can be -1 if missing. |
2692 | * @tsc: The TSC value of the frame that generated the MIC failure (6 octets) | 2692 | * @tsc: The TSC value of the frame that generated the MIC failure (6 octets) |
2693 | * @gfp: allocation flags | 2693 | * @gfp: allocation flags |
2694 | * | 2694 | * |
diff --git a/include/net/dst.h b/include/net/dst.h index 7d15d238b6ec..e12ddfb9eb16 100644 --- a/include/net/dst.h +++ b/include/net/dst.h | |||
@@ -77,6 +77,7 @@ struct dst_entry { | |||
77 | #define DST_NOPOLICY 0x0004 | 77 | #define DST_NOPOLICY 0x0004 |
78 | #define DST_NOHASH 0x0008 | 78 | #define DST_NOHASH 0x0008 |
79 | #define DST_NOCACHE 0x0010 | 79 | #define DST_NOCACHE 0x0010 |
80 | #define DST_NOCOUNT 0x0020 | ||
80 | union { | 81 | union { |
81 | struct dst_entry *next; | 82 | struct dst_entry *next; |
82 | struct rtable __rcu *rt_next; | 83 | struct rtable __rcu *rt_next; |
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h index dd6847e5d6e4..6506458ccd33 100644 --- a/include/net/sctp/command.h +++ b/include/net/sctp/command.h | |||
@@ -63,6 +63,7 @@ typedef enum { | |||
63 | SCTP_CMD_ECN_ECNE, /* Do delayed ECNE processing. */ | 63 | SCTP_CMD_ECN_ECNE, /* Do delayed ECNE processing. */ |
64 | SCTP_CMD_ECN_CWR, /* Do delayed CWR processing. */ | 64 | SCTP_CMD_ECN_CWR, /* Do delayed CWR processing. */ |
65 | SCTP_CMD_TIMER_START, /* Start a timer. */ | 65 | SCTP_CMD_TIMER_START, /* Start a timer. */ |
66 | SCTP_CMD_TIMER_START_ONCE, /* Start a timer once */ | ||
66 | SCTP_CMD_TIMER_RESTART, /* Restart a timer. */ | 67 | SCTP_CMD_TIMER_RESTART, /* Restart a timer. */ |
67 | SCTP_CMD_TIMER_STOP, /* Stop a timer. */ | 68 | SCTP_CMD_TIMER_STOP, /* Stop a timer. */ |
68 | SCTP_CMD_INIT_CHOOSE_TRANSPORT, /* Choose transport for an INIT. */ | 69 | SCTP_CMD_INIT_CHOOSE_TRANSPORT, /* Choose transport for an INIT. */ |
diff --git a/include/net/sctp/ulpevent.h b/include/net/sctp/ulpevent.h index 99b027b2adce..ca4693b4e09e 100644 --- a/include/net/sctp/ulpevent.h +++ b/include/net/sctp/ulpevent.h | |||
@@ -80,7 +80,7 @@ static inline struct sctp_ulpevent *sctp_skb2event(struct sk_buff *skb) | |||
80 | 80 | ||
81 | void sctp_ulpevent_free(struct sctp_ulpevent *); | 81 | void sctp_ulpevent_free(struct sctp_ulpevent *); |
82 | int sctp_ulpevent_is_notification(const struct sctp_ulpevent *); | 82 | int sctp_ulpevent_is_notification(const struct sctp_ulpevent *); |
83 | void sctp_queue_purge_ulpevents(struct sk_buff_head *list); | 83 | unsigned int sctp_queue_purge_ulpevents(struct sk_buff_head *list); |
84 | 84 | ||
85 | struct sctp_ulpevent *sctp_ulpevent_make_assoc_change( | 85 | struct sctp_ulpevent *sctp_ulpevent_make_assoc_change( |
86 | const struct sctp_association *asoc, | 86 | const struct sctp_association *asoc, |
diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c index 31a9db711906..3a2cab407b93 100644 --- a/kernel/irq/generic-chip.c +++ b/kernel/irq/generic-chip.c | |||
@@ -101,10 +101,10 @@ void irq_gc_unmask_enable_reg(struct irq_data *d) | |||
101 | } | 101 | } |
102 | 102 | ||
103 | /** | 103 | /** |
104 | * irq_gc_ack - Ack pending interrupt | 104 | * irq_gc_ack_set_bit - Ack pending interrupt via setting bit |
105 | * @d: irq_data | 105 | * @d: irq_data |
106 | */ | 106 | */ |
107 | void irq_gc_ack(struct irq_data *d) | 107 | void irq_gc_ack_set_bit(struct irq_data *d) |
108 | { | 108 | { |
109 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | 109 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
110 | u32 mask = 1 << (d->irq - gc->irq_base); | 110 | u32 mask = 1 << (d->irq - gc->irq_base); |
@@ -115,6 +115,20 @@ void irq_gc_ack(struct irq_data *d) | |||
115 | } | 115 | } |
116 | 116 | ||
117 | /** | 117 | /** |
118 | * irq_gc_ack_clr_bit - Ack pending interrupt via clearing bit | ||
119 | * @d: irq_data | ||
120 | */ | ||
121 | void irq_gc_ack_clr_bit(struct irq_data *d) | ||
122 | { | ||
123 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | ||
124 | u32 mask = ~(1 << (d->irq - gc->irq_base)); | ||
125 | |||
126 | irq_gc_lock(gc); | ||
127 | irq_reg_writel(mask, gc->reg_base + cur_regs(d)->ack); | ||
128 | irq_gc_unlock(gc); | ||
129 | } | ||
130 | |||
131 | /** | ||
118 | * irq_gc_mask_disable_reg_and_ack- Mask and ack pending interrupt | 132 | * irq_gc_mask_disable_reg_and_ack- Mask and ack pending interrupt |
119 | * @d: irq_data | 133 | * @d: irq_data |
120 | */ | 134 | */ |
diff --git a/kernel/jump_label.c b/kernel/jump_label.c index fa27e750dbc0..a8ce45097f3d 100644 --- a/kernel/jump_label.c +++ b/kernel/jump_label.c | |||
@@ -375,15 +375,19 @@ int jump_label_text_reserved(void *start, void *end) | |||
375 | 375 | ||
376 | static void jump_label_update(struct jump_label_key *key, int enable) | 376 | static void jump_label_update(struct jump_label_key *key, int enable) |
377 | { | 377 | { |
378 | struct jump_entry *entry = key->entries; | 378 | struct jump_entry *entry = key->entries, *stop = __stop___jump_table; |
379 | |||
380 | /* if there are no users, entry can be NULL */ | ||
381 | if (entry) | ||
382 | __jump_label_update(key, entry, __stop___jump_table, enable); | ||
383 | 379 | ||
384 | #ifdef CONFIG_MODULES | 380 | #ifdef CONFIG_MODULES |
381 | struct module *mod = __module_address((jump_label_t)key); | ||
382 | |||
385 | __jump_label_mod_update(key, enable); | 383 | __jump_label_mod_update(key, enable); |
384 | |||
385 | if (mod) | ||
386 | stop = mod->jump_entries + mod->num_jump_entries; | ||
386 | #endif | 387 | #endif |
388 | /* if there are no users, entry can be NULL */ | ||
389 | if (entry) | ||
390 | __jump_label_update(key, entry, stop, enable); | ||
387 | } | 391 | } |
388 | 392 | ||
389 | #endif | 393 | #endif |
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index ace55889f702..06efa54f93d6 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c | |||
@@ -1211,7 +1211,11 @@ static void free_unnecessary_pages(void) | |||
1211 | to_free_highmem = alloc_highmem - save; | 1211 | to_free_highmem = alloc_highmem - save; |
1212 | } else { | 1212 | } else { |
1213 | to_free_highmem = 0; | 1213 | to_free_highmem = 0; |
1214 | to_free_normal -= save - alloc_highmem; | 1214 | save -= alloc_highmem; |
1215 | if (to_free_normal > save) | ||
1216 | to_free_normal -= save; | ||
1217 | else | ||
1218 | to_free_normal = 0; | ||
1215 | } | 1219 | } |
1216 | 1220 | ||
1217 | memory_bm_position_reset(©_bm); | 1221 | memory_bm_position_reset(©_bm); |
diff --git a/kernel/rcutree.c b/kernel/rcutree.c index 7e59ffb3d0ba..ba06207b1dd3 100644 --- a/kernel/rcutree.c +++ b/kernel/rcutree.c | |||
@@ -84,9 +84,32 @@ DEFINE_PER_CPU(struct rcu_data, rcu_bh_data); | |||
84 | 84 | ||
85 | static struct rcu_state *rcu_state; | 85 | static struct rcu_state *rcu_state; |
86 | 86 | ||
87 | /* | ||
88 | * The rcu_scheduler_active variable transitions from zero to one just | ||
89 | * before the first task is spawned. So when this variable is zero, RCU | ||
90 | * can assume that there is but one task, allowing RCU to (for example) | ||
91 | * optimized synchronize_sched() to a simple barrier(). When this variable | ||
92 | * is one, RCU must actually do all the hard work required to detect real | ||
93 | * grace periods. This variable is also used to suppress boot-time false | ||
94 | * positives from lockdep-RCU error checking. | ||
95 | */ | ||
87 | int rcu_scheduler_active __read_mostly; | 96 | int rcu_scheduler_active __read_mostly; |
88 | EXPORT_SYMBOL_GPL(rcu_scheduler_active); | 97 | EXPORT_SYMBOL_GPL(rcu_scheduler_active); |
89 | 98 | ||
99 | /* | ||
100 | * The rcu_scheduler_fully_active variable transitions from zero to one | ||
101 | * during the early_initcall() processing, which is after the scheduler | ||
102 | * is capable of creating new tasks. So RCU processing (for example, | ||
103 | * creating tasks for RCU priority boosting) must be delayed until after | ||
104 | * rcu_scheduler_fully_active transitions from zero to one. We also | ||
105 | * currently delay invocation of any RCU callbacks until after this point. | ||
106 | * | ||
107 | * It might later prove better for people registering RCU callbacks during | ||
108 | * early boot to take responsibility for these callbacks, but one step at | ||
109 | * a time. | ||
110 | */ | ||
111 | static int rcu_scheduler_fully_active __read_mostly; | ||
112 | |||
90 | #ifdef CONFIG_RCU_BOOST | 113 | #ifdef CONFIG_RCU_BOOST |
91 | 114 | ||
92 | /* | 115 | /* |
@@ -98,7 +121,6 @@ DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_status); | |||
98 | DEFINE_PER_CPU(int, rcu_cpu_kthread_cpu); | 121 | DEFINE_PER_CPU(int, rcu_cpu_kthread_cpu); |
99 | DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_loops); | 122 | DEFINE_PER_CPU(unsigned int, rcu_cpu_kthread_loops); |
100 | DEFINE_PER_CPU(char, rcu_cpu_has_work); | 123 | DEFINE_PER_CPU(char, rcu_cpu_has_work); |
101 | static char rcu_kthreads_spawnable; | ||
102 | 124 | ||
103 | #endif /* #ifdef CONFIG_RCU_BOOST */ | 125 | #endif /* #ifdef CONFIG_RCU_BOOST */ |
104 | 126 | ||
@@ -1467,6 +1489,8 @@ static void rcu_process_callbacks(struct softirq_action *unused) | |||
1467 | */ | 1489 | */ |
1468 | static void invoke_rcu_callbacks(struct rcu_state *rsp, struct rcu_data *rdp) | 1490 | static void invoke_rcu_callbacks(struct rcu_state *rsp, struct rcu_data *rdp) |
1469 | { | 1491 | { |
1492 | if (unlikely(!ACCESS_ONCE(rcu_scheduler_fully_active))) | ||
1493 | return; | ||
1470 | if (likely(!rsp->boost)) { | 1494 | if (likely(!rsp->boost)) { |
1471 | rcu_do_batch(rsp, rdp); | 1495 | rcu_do_batch(rsp, rdp); |
1472 | return; | 1496 | return; |
diff --git a/kernel/rcutree_plugin.h b/kernel/rcutree_plugin.h index 14dc7dd00902..8aafbb80b8b0 100644 --- a/kernel/rcutree_plugin.h +++ b/kernel/rcutree_plugin.h | |||
@@ -68,6 +68,7 @@ struct rcu_state rcu_preempt_state = RCU_STATE_INITIALIZER(rcu_preempt_state); | |||
68 | DEFINE_PER_CPU(struct rcu_data, rcu_preempt_data); | 68 | DEFINE_PER_CPU(struct rcu_data, rcu_preempt_data); |
69 | static struct rcu_state *rcu_state = &rcu_preempt_state; | 69 | static struct rcu_state *rcu_state = &rcu_preempt_state; |
70 | 70 | ||
71 | static void rcu_read_unlock_special(struct task_struct *t); | ||
71 | static int rcu_preempted_readers_exp(struct rcu_node *rnp); | 72 | static int rcu_preempted_readers_exp(struct rcu_node *rnp); |
72 | 73 | ||
73 | /* | 74 | /* |
@@ -147,7 +148,7 @@ static void rcu_preempt_note_context_switch(int cpu) | |||
147 | struct rcu_data *rdp; | 148 | struct rcu_data *rdp; |
148 | struct rcu_node *rnp; | 149 | struct rcu_node *rnp; |
149 | 150 | ||
150 | if (t->rcu_read_lock_nesting && | 151 | if (t->rcu_read_lock_nesting > 0 && |
151 | (t->rcu_read_unlock_special & RCU_READ_UNLOCK_BLOCKED) == 0) { | 152 | (t->rcu_read_unlock_special & RCU_READ_UNLOCK_BLOCKED) == 0) { |
152 | 153 | ||
153 | /* Possibly blocking in an RCU read-side critical section. */ | 154 | /* Possibly blocking in an RCU read-side critical section. */ |
@@ -190,6 +191,14 @@ static void rcu_preempt_note_context_switch(int cpu) | |||
190 | rnp->gp_tasks = &t->rcu_node_entry; | 191 | rnp->gp_tasks = &t->rcu_node_entry; |
191 | } | 192 | } |
192 | raw_spin_unlock_irqrestore(&rnp->lock, flags); | 193 | raw_spin_unlock_irqrestore(&rnp->lock, flags); |
194 | } else if (t->rcu_read_lock_nesting < 0 && | ||
195 | t->rcu_read_unlock_special) { | ||
196 | |||
197 | /* | ||
198 | * Complete exit from RCU read-side critical section on | ||
199 | * behalf of preempted instance of __rcu_read_unlock(). | ||
200 | */ | ||
201 | rcu_read_unlock_special(t); | ||
193 | } | 202 | } |
194 | 203 | ||
195 | /* | 204 | /* |
@@ -284,7 +293,7 @@ static struct list_head *rcu_next_node_entry(struct task_struct *t, | |||
284 | * notify RCU core processing or task having blocked during the RCU | 293 | * notify RCU core processing or task having blocked during the RCU |
285 | * read-side critical section. | 294 | * read-side critical section. |
286 | */ | 295 | */ |
287 | static void rcu_read_unlock_special(struct task_struct *t) | 296 | static noinline void rcu_read_unlock_special(struct task_struct *t) |
288 | { | 297 | { |
289 | int empty; | 298 | int empty; |
290 | int empty_exp; | 299 | int empty_exp; |
@@ -309,7 +318,7 @@ static void rcu_read_unlock_special(struct task_struct *t) | |||
309 | } | 318 | } |
310 | 319 | ||
311 | /* Hardware IRQ handlers cannot block. */ | 320 | /* Hardware IRQ handlers cannot block. */ |
312 | if (in_irq()) { | 321 | if (in_irq() || in_serving_softirq()) { |
313 | local_irq_restore(flags); | 322 | local_irq_restore(flags); |
314 | return; | 323 | return; |
315 | } | 324 | } |
@@ -342,6 +351,11 @@ static void rcu_read_unlock_special(struct task_struct *t) | |||
342 | #ifdef CONFIG_RCU_BOOST | 351 | #ifdef CONFIG_RCU_BOOST |
343 | if (&t->rcu_node_entry == rnp->boost_tasks) | 352 | if (&t->rcu_node_entry == rnp->boost_tasks) |
344 | rnp->boost_tasks = np; | 353 | rnp->boost_tasks = np; |
354 | /* Snapshot and clear ->rcu_boosted with rcu_node lock held. */ | ||
355 | if (t->rcu_boosted) { | ||
356 | special |= RCU_READ_UNLOCK_BOOSTED; | ||
357 | t->rcu_boosted = 0; | ||
358 | } | ||
345 | #endif /* #ifdef CONFIG_RCU_BOOST */ | 359 | #endif /* #ifdef CONFIG_RCU_BOOST */ |
346 | t->rcu_blocked_node = NULL; | 360 | t->rcu_blocked_node = NULL; |
347 | 361 | ||
@@ -358,7 +372,6 @@ static void rcu_read_unlock_special(struct task_struct *t) | |||
358 | #ifdef CONFIG_RCU_BOOST | 372 | #ifdef CONFIG_RCU_BOOST |
359 | /* Unboost if we were boosted. */ | 373 | /* Unboost if we were boosted. */ |
360 | if (special & RCU_READ_UNLOCK_BOOSTED) { | 374 | if (special & RCU_READ_UNLOCK_BOOSTED) { |
361 | t->rcu_read_unlock_special &= ~RCU_READ_UNLOCK_BOOSTED; | ||
362 | rt_mutex_unlock(t->rcu_boost_mutex); | 375 | rt_mutex_unlock(t->rcu_boost_mutex); |
363 | t->rcu_boost_mutex = NULL; | 376 | t->rcu_boost_mutex = NULL; |
364 | } | 377 | } |
@@ -387,13 +400,22 @@ void __rcu_read_unlock(void) | |||
387 | struct task_struct *t = current; | 400 | struct task_struct *t = current; |
388 | 401 | ||
389 | barrier(); /* needed if we ever invoke rcu_read_unlock in rcutree.c */ | 402 | barrier(); /* needed if we ever invoke rcu_read_unlock in rcutree.c */ |
390 | --t->rcu_read_lock_nesting; | 403 | if (t->rcu_read_lock_nesting != 1) |
391 | barrier(); /* decrement before load of ->rcu_read_unlock_special */ | 404 | --t->rcu_read_lock_nesting; |
392 | if (t->rcu_read_lock_nesting == 0 && | 405 | else { |
393 | unlikely(ACCESS_ONCE(t->rcu_read_unlock_special))) | 406 | t->rcu_read_lock_nesting = INT_MIN; |
394 | rcu_read_unlock_special(t); | 407 | barrier(); /* assign before ->rcu_read_unlock_special load */ |
408 | if (unlikely(ACCESS_ONCE(t->rcu_read_unlock_special))) | ||
409 | rcu_read_unlock_special(t); | ||
410 | barrier(); /* ->rcu_read_unlock_special load before assign */ | ||
411 | t->rcu_read_lock_nesting = 0; | ||
412 | } | ||
395 | #ifdef CONFIG_PROVE_LOCKING | 413 | #ifdef CONFIG_PROVE_LOCKING |
396 | WARN_ON_ONCE(ACCESS_ONCE(t->rcu_read_lock_nesting) < 0); | 414 | { |
415 | int rrln = ACCESS_ONCE(t->rcu_read_lock_nesting); | ||
416 | |||
417 | WARN_ON_ONCE(rrln < 0 && rrln > INT_MIN / 2); | ||
418 | } | ||
397 | #endif /* #ifdef CONFIG_PROVE_LOCKING */ | 419 | #endif /* #ifdef CONFIG_PROVE_LOCKING */ |
398 | } | 420 | } |
399 | EXPORT_SYMBOL_GPL(__rcu_read_unlock); | 421 | EXPORT_SYMBOL_GPL(__rcu_read_unlock); |
@@ -589,7 +611,8 @@ static void rcu_preempt_check_callbacks(int cpu) | |||
589 | rcu_preempt_qs(cpu); | 611 | rcu_preempt_qs(cpu); |
590 | return; | 612 | return; |
591 | } | 613 | } |
592 | if (per_cpu(rcu_preempt_data, cpu).qs_pending) | 614 | if (t->rcu_read_lock_nesting > 0 && |
615 | per_cpu(rcu_preempt_data, cpu).qs_pending) | ||
593 | t->rcu_read_unlock_special |= RCU_READ_UNLOCK_NEED_QS; | 616 | t->rcu_read_unlock_special |= RCU_READ_UNLOCK_NEED_QS; |
594 | } | 617 | } |
595 | 618 | ||
@@ -695,9 +718,12 @@ static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp) | |||
695 | 718 | ||
696 | raw_spin_lock_irqsave(&rnp->lock, flags); | 719 | raw_spin_lock_irqsave(&rnp->lock, flags); |
697 | for (;;) { | 720 | for (;;) { |
698 | if (!sync_rcu_preempt_exp_done(rnp)) | 721 | if (!sync_rcu_preempt_exp_done(rnp)) { |
722 | raw_spin_unlock_irqrestore(&rnp->lock, flags); | ||
699 | break; | 723 | break; |
724 | } | ||
700 | if (rnp->parent == NULL) { | 725 | if (rnp->parent == NULL) { |
726 | raw_spin_unlock_irqrestore(&rnp->lock, flags); | ||
701 | wake_up(&sync_rcu_preempt_exp_wq); | 727 | wake_up(&sync_rcu_preempt_exp_wq); |
702 | break; | 728 | break; |
703 | } | 729 | } |
@@ -707,7 +733,6 @@ static void rcu_report_exp_rnp(struct rcu_state *rsp, struct rcu_node *rnp) | |||
707 | raw_spin_lock(&rnp->lock); /* irqs already disabled */ | 733 | raw_spin_lock(&rnp->lock); /* irqs already disabled */ |
708 | rnp->expmask &= ~mask; | 734 | rnp->expmask &= ~mask; |
709 | } | 735 | } |
710 | raw_spin_unlock_irqrestore(&rnp->lock, flags); | ||
711 | } | 736 | } |
712 | 737 | ||
713 | /* | 738 | /* |
@@ -1174,7 +1199,7 @@ static int rcu_boost(struct rcu_node *rnp) | |||
1174 | t = container_of(tb, struct task_struct, rcu_node_entry); | 1199 | t = container_of(tb, struct task_struct, rcu_node_entry); |
1175 | rt_mutex_init_proxy_locked(&mtx, t); | 1200 | rt_mutex_init_proxy_locked(&mtx, t); |
1176 | t->rcu_boost_mutex = &mtx; | 1201 | t->rcu_boost_mutex = &mtx; |
1177 | t->rcu_read_unlock_special |= RCU_READ_UNLOCK_BOOSTED; | 1202 | t->rcu_boosted = 1; |
1178 | raw_spin_unlock_irqrestore(&rnp->lock, flags); | 1203 | raw_spin_unlock_irqrestore(&rnp->lock, flags); |
1179 | rt_mutex_lock(&mtx); /* Side effect: boosts task t's priority. */ | 1204 | rt_mutex_lock(&mtx); /* Side effect: boosts task t's priority. */ |
1180 | rt_mutex_unlock(&mtx); /* Keep lockdep happy. */ | 1205 | rt_mutex_unlock(&mtx); /* Keep lockdep happy. */ |
@@ -1532,7 +1557,7 @@ static int __cpuinit rcu_spawn_one_cpu_kthread(int cpu) | |||
1532 | struct sched_param sp; | 1557 | struct sched_param sp; |
1533 | struct task_struct *t; | 1558 | struct task_struct *t; |
1534 | 1559 | ||
1535 | if (!rcu_kthreads_spawnable || | 1560 | if (!rcu_scheduler_fully_active || |
1536 | per_cpu(rcu_cpu_kthread_task, cpu) != NULL) | 1561 | per_cpu(rcu_cpu_kthread_task, cpu) != NULL) |
1537 | return 0; | 1562 | return 0; |
1538 | t = kthread_create(rcu_cpu_kthread, (void *)(long)cpu, "rcuc%d", cpu); | 1563 | t = kthread_create(rcu_cpu_kthread, (void *)(long)cpu, "rcuc%d", cpu); |
@@ -1639,7 +1664,7 @@ static int __cpuinit rcu_spawn_one_node_kthread(struct rcu_state *rsp, | |||
1639 | struct sched_param sp; | 1664 | struct sched_param sp; |
1640 | struct task_struct *t; | 1665 | struct task_struct *t; |
1641 | 1666 | ||
1642 | if (!rcu_kthreads_spawnable || | 1667 | if (!rcu_scheduler_fully_active || |
1643 | rnp->qsmaskinit == 0) | 1668 | rnp->qsmaskinit == 0) |
1644 | return 0; | 1669 | return 0; |
1645 | if (rnp->node_kthread_task == NULL) { | 1670 | if (rnp->node_kthread_task == NULL) { |
@@ -1665,7 +1690,7 @@ static int __init rcu_spawn_kthreads(void) | |||
1665 | int cpu; | 1690 | int cpu; |
1666 | struct rcu_node *rnp; | 1691 | struct rcu_node *rnp; |
1667 | 1692 | ||
1668 | rcu_kthreads_spawnable = 1; | 1693 | rcu_scheduler_fully_active = 1; |
1669 | for_each_possible_cpu(cpu) { | 1694 | for_each_possible_cpu(cpu) { |
1670 | per_cpu(rcu_cpu_has_work, cpu) = 0; | 1695 | per_cpu(rcu_cpu_has_work, cpu) = 0; |
1671 | if (cpu_online(cpu)) | 1696 | if (cpu_online(cpu)) |
@@ -1687,7 +1712,7 @@ static void __cpuinit rcu_prepare_kthreads(int cpu) | |||
1687 | struct rcu_node *rnp = rdp->mynode; | 1712 | struct rcu_node *rnp = rdp->mynode; |
1688 | 1713 | ||
1689 | /* Fire up the incoming CPU's kthread and leaf rcu_node kthread. */ | 1714 | /* Fire up the incoming CPU's kthread and leaf rcu_node kthread. */ |
1690 | if (rcu_kthreads_spawnable) { | 1715 | if (rcu_scheduler_fully_active) { |
1691 | (void)rcu_spawn_one_cpu_kthread(cpu); | 1716 | (void)rcu_spawn_one_cpu_kthread(cpu); |
1692 | if (rnp->node_kthread_task == NULL) | 1717 | if (rnp->node_kthread_task == NULL) |
1693 | (void)rcu_spawn_one_node_kthread(rcu_state, rnp); | 1718 | (void)rcu_spawn_one_node_kthread(rcu_state, rnp); |
@@ -1726,6 +1751,13 @@ static void rcu_cpu_kthread_setrt(int cpu, int to_rt) | |||
1726 | { | 1751 | { |
1727 | } | 1752 | } |
1728 | 1753 | ||
1754 | static int __init rcu_scheduler_really_started(void) | ||
1755 | { | ||
1756 | rcu_scheduler_fully_active = 1; | ||
1757 | return 0; | ||
1758 | } | ||
1759 | early_initcall(rcu_scheduler_really_started); | ||
1760 | |||
1729 | static void __cpuinit rcu_prepare_kthreads(int cpu) | 1761 | static void __cpuinit rcu_prepare_kthreads(int cpu) |
1730 | { | 1762 | { |
1731 | } | 1763 | } |
diff --git a/kernel/resource.c b/kernel/resource.c index 798e2fae2a06..3ff40178dce7 100644 --- a/kernel/resource.c +++ b/kernel/resource.c | |||
@@ -38,6 +38,14 @@ struct resource iomem_resource = { | |||
38 | }; | 38 | }; |
39 | EXPORT_SYMBOL(iomem_resource); | 39 | EXPORT_SYMBOL(iomem_resource); |
40 | 40 | ||
41 | /* constraints to be met while allocating resources */ | ||
42 | struct resource_constraint { | ||
43 | resource_size_t min, max, align; | ||
44 | resource_size_t (*alignf)(void *, const struct resource *, | ||
45 | resource_size_t, resource_size_t); | ||
46 | void *alignf_data; | ||
47 | }; | ||
48 | |||
41 | static DEFINE_RWLOCK(resource_lock); | 49 | static DEFINE_RWLOCK(resource_lock); |
42 | 50 | ||
43 | static void *r_next(struct seq_file *m, void *v, loff_t *pos) | 51 | static void *r_next(struct seq_file *m, void *v, loff_t *pos) |
@@ -384,16 +392,13 @@ static bool resource_contains(struct resource *res1, struct resource *res2) | |||
384 | } | 392 | } |
385 | 393 | ||
386 | /* | 394 | /* |
387 | * Find empty slot in the resource tree given range and alignment. | 395 | * Find empty slot in the resource tree with the given range and |
396 | * alignment constraints | ||
388 | */ | 397 | */ |
389 | static int find_resource(struct resource *root, struct resource *new, | 398 | static int __find_resource(struct resource *root, struct resource *old, |
390 | resource_size_t size, resource_size_t min, | 399 | struct resource *new, |
391 | resource_size_t max, resource_size_t align, | 400 | resource_size_t size, |
392 | resource_size_t (*alignf)(void *, | 401 | struct resource_constraint *constraint) |
393 | const struct resource *, | ||
394 | resource_size_t, | ||
395 | resource_size_t), | ||
396 | void *alignf_data) | ||
397 | { | 402 | { |
398 | struct resource *this = root->child; | 403 | struct resource *this = root->child; |
399 | struct resource tmp = *new, avail, alloc; | 404 | struct resource tmp = *new, avail, alloc; |
@@ -404,25 +409,26 @@ static int find_resource(struct resource *root, struct resource *new, | |||
404 | * Skip past an allocated resource that starts at 0, since the assignment | 409 | * Skip past an allocated resource that starts at 0, since the assignment |
405 | * of this->start - 1 to tmp->end below would cause an underflow. | 410 | * of this->start - 1 to tmp->end below would cause an underflow. |
406 | */ | 411 | */ |
407 | if (this && this->start == 0) { | 412 | if (this && this->start == root->start) { |
408 | tmp.start = this->end + 1; | 413 | tmp.start = (this == old) ? old->start : this->end + 1; |
409 | this = this->sibling; | 414 | this = this->sibling; |
410 | } | 415 | } |
411 | for(;;) { | 416 | for(;;) { |
412 | if (this) | 417 | if (this) |
413 | tmp.end = this->start - 1; | 418 | tmp.end = (this == old) ? this->end : this->start - 1; |
414 | else | 419 | else |
415 | tmp.end = root->end; | 420 | tmp.end = root->end; |
416 | 421 | ||
417 | resource_clip(&tmp, min, max); | 422 | resource_clip(&tmp, constraint->min, constraint->max); |
418 | arch_remove_reservations(&tmp); | 423 | arch_remove_reservations(&tmp); |
419 | 424 | ||
420 | /* Check for overflow after ALIGN() */ | 425 | /* Check for overflow after ALIGN() */ |
421 | avail = *new; | 426 | avail = *new; |
422 | avail.start = ALIGN(tmp.start, align); | 427 | avail.start = ALIGN(tmp.start, constraint->align); |
423 | avail.end = tmp.end; | 428 | avail.end = tmp.end; |
424 | if (avail.start >= tmp.start) { | 429 | if (avail.start >= tmp.start) { |
425 | alloc.start = alignf(alignf_data, &avail, size, align); | 430 | alloc.start = constraint->alignf(constraint->alignf_data, &avail, |
431 | size, constraint->align); | ||
426 | alloc.end = alloc.start + size - 1; | 432 | alloc.end = alloc.start + size - 1; |
427 | if (resource_contains(&avail, &alloc)) { | 433 | if (resource_contains(&avail, &alloc)) { |
428 | new->start = alloc.start; | 434 | new->start = alloc.start; |
@@ -432,14 +438,75 @@ static int find_resource(struct resource *root, struct resource *new, | |||
432 | } | 438 | } |
433 | if (!this) | 439 | if (!this) |
434 | break; | 440 | break; |
435 | tmp.start = this->end + 1; | 441 | if (this != old) |
442 | tmp.start = this->end + 1; | ||
436 | this = this->sibling; | 443 | this = this->sibling; |
437 | } | 444 | } |
438 | return -EBUSY; | 445 | return -EBUSY; |
439 | } | 446 | } |
440 | 447 | ||
448 | /* | ||
449 | * Find empty slot in the resource tree given range and alignment. | ||
450 | */ | ||
451 | static int find_resource(struct resource *root, struct resource *new, | ||
452 | resource_size_t size, | ||
453 | struct resource_constraint *constraint) | ||
454 | { | ||
455 | return __find_resource(root, NULL, new, size, constraint); | ||
456 | } | ||
457 | |||
441 | /** | 458 | /** |
442 | * allocate_resource - allocate empty slot in the resource tree given range & alignment | 459 | * reallocate_resource - allocate a slot in the resource tree given range & alignment. |
460 | * The resource will be relocated if the new size cannot be reallocated in the | ||
461 | * current location. | ||
462 | * | ||
463 | * @root: root resource descriptor | ||
464 | * @old: resource descriptor desired by caller | ||
465 | * @newsize: new size of the resource descriptor | ||
466 | * @constraint: the size and alignment constraints to be met. | ||
467 | */ | ||
468 | int reallocate_resource(struct resource *root, struct resource *old, | ||
469 | resource_size_t newsize, | ||
470 | struct resource_constraint *constraint) | ||
471 | { | ||
472 | int err=0; | ||
473 | struct resource new = *old; | ||
474 | struct resource *conflict; | ||
475 | |||
476 | write_lock(&resource_lock); | ||
477 | |||
478 | if ((err = __find_resource(root, old, &new, newsize, constraint))) | ||
479 | goto out; | ||
480 | |||
481 | if (resource_contains(&new, old)) { | ||
482 | old->start = new.start; | ||
483 | old->end = new.end; | ||
484 | goto out; | ||
485 | } | ||
486 | |||
487 | if (old->child) { | ||
488 | err = -EBUSY; | ||
489 | goto out; | ||
490 | } | ||
491 | |||
492 | if (resource_contains(old, &new)) { | ||
493 | old->start = new.start; | ||
494 | old->end = new.end; | ||
495 | } else { | ||
496 | __release_resource(old); | ||
497 | *old = new; | ||
498 | conflict = __request_resource(root, old); | ||
499 | BUG_ON(conflict); | ||
500 | } | ||
501 | out: | ||
502 | write_unlock(&resource_lock); | ||
503 | return err; | ||
504 | } | ||
505 | |||
506 | |||
507 | /** | ||
508 | * allocate_resource - allocate empty slot in the resource tree given range & alignment. | ||
509 | * The resource will be reallocated with a new size if it was already allocated | ||
443 | * @root: root resource descriptor | 510 | * @root: root resource descriptor |
444 | * @new: resource descriptor desired by caller | 511 | * @new: resource descriptor desired by caller |
445 | * @size: requested resource region size | 512 | * @size: requested resource region size |
@@ -459,12 +526,25 @@ int allocate_resource(struct resource *root, struct resource *new, | |||
459 | void *alignf_data) | 526 | void *alignf_data) |
460 | { | 527 | { |
461 | int err; | 528 | int err; |
529 | struct resource_constraint constraint; | ||
462 | 530 | ||
463 | if (!alignf) | 531 | if (!alignf) |
464 | alignf = simple_align_resource; | 532 | alignf = simple_align_resource; |
465 | 533 | ||
534 | constraint.min = min; | ||
535 | constraint.max = max; | ||
536 | constraint.align = align; | ||
537 | constraint.alignf = alignf; | ||
538 | constraint.alignf_data = alignf_data; | ||
539 | |||
540 | if ( new->parent ) { | ||
541 | /* resource is already allocated, try reallocating with | ||
542 | the new constraints */ | ||
543 | return reallocate_resource(root, new, size, &constraint); | ||
544 | } | ||
545 | |||
466 | write_lock(&resource_lock); | 546 | write_lock(&resource_lock); |
467 | err = find_resource(root, new, size, min, max, align, alignf, alignf_data); | 547 | err = find_resource(root, new, size, &constraint); |
468 | if (err >= 0 && __request_resource(root, new)) | 548 | if (err >= 0 && __request_resource(root, new)) |
469 | err = -EBUSY; | 549 | err = -EBUSY; |
470 | write_unlock(&resource_lock); | 550 | write_unlock(&resource_lock); |
diff --git a/kernel/sched.c b/kernel/sched.c index 3f2e502d609b..fde6ff903525 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -292,8 +292,8 @@ static DEFINE_SPINLOCK(task_group_lock); | |||
292 | * (The default weight is 1024 - so there's no practical | 292 | * (The default weight is 1024 - so there's no practical |
293 | * limitation from this.) | 293 | * limitation from this.) |
294 | */ | 294 | */ |
295 | #define MIN_SHARES 2 | 295 | #define MIN_SHARES (1UL << 1) |
296 | #define MAX_SHARES (1UL << (18 + SCHED_LOAD_RESOLUTION)) | 296 | #define MAX_SHARES (1UL << 18) |
297 | 297 | ||
298 | static int root_task_group_load = ROOT_TASK_GROUP_LOAD; | 298 | static int root_task_group_load = ROOT_TASK_GROUP_LOAD; |
299 | #endif | 299 | #endif |
@@ -2544,13 +2544,9 @@ static int ttwu_remote(struct task_struct *p, int wake_flags) | |||
2544 | } | 2544 | } |
2545 | 2545 | ||
2546 | #ifdef CONFIG_SMP | 2546 | #ifdef CONFIG_SMP |
2547 | static void sched_ttwu_pending(void) | 2547 | static void sched_ttwu_do_pending(struct task_struct *list) |
2548 | { | 2548 | { |
2549 | struct rq *rq = this_rq(); | 2549 | struct rq *rq = this_rq(); |
2550 | struct task_struct *list = xchg(&rq->wake_list, NULL); | ||
2551 | |||
2552 | if (!list) | ||
2553 | return; | ||
2554 | 2550 | ||
2555 | raw_spin_lock(&rq->lock); | 2551 | raw_spin_lock(&rq->lock); |
2556 | 2552 | ||
@@ -2563,9 +2559,45 @@ static void sched_ttwu_pending(void) | |||
2563 | raw_spin_unlock(&rq->lock); | 2559 | raw_spin_unlock(&rq->lock); |
2564 | } | 2560 | } |
2565 | 2561 | ||
2562 | #ifdef CONFIG_HOTPLUG_CPU | ||
2563 | |||
2564 | static void sched_ttwu_pending(void) | ||
2565 | { | ||
2566 | struct rq *rq = this_rq(); | ||
2567 | struct task_struct *list = xchg(&rq->wake_list, NULL); | ||
2568 | |||
2569 | if (!list) | ||
2570 | return; | ||
2571 | |||
2572 | sched_ttwu_do_pending(list); | ||
2573 | } | ||
2574 | |||
2575 | #endif /* CONFIG_HOTPLUG_CPU */ | ||
2576 | |||
2566 | void scheduler_ipi(void) | 2577 | void scheduler_ipi(void) |
2567 | { | 2578 | { |
2568 | sched_ttwu_pending(); | 2579 | struct rq *rq = this_rq(); |
2580 | struct task_struct *list = xchg(&rq->wake_list, NULL); | ||
2581 | |||
2582 | if (!list) | ||
2583 | return; | ||
2584 | |||
2585 | /* | ||
2586 | * Not all reschedule IPI handlers call irq_enter/irq_exit, since | ||
2587 | * traditionally all their work was done from the interrupt return | ||
2588 | * path. Now that we actually do some work, we need to make sure | ||
2589 | * we do call them. | ||
2590 | * | ||
2591 | * Some archs already do call them, luckily irq_enter/exit nest | ||
2592 | * properly. | ||
2593 | * | ||
2594 | * Arguably we should visit all archs and update all handlers, | ||
2595 | * however a fair share of IPIs are still resched only so this would | ||
2596 | * somewhat pessimize the simple resched case. | ||
2597 | */ | ||
2598 | irq_enter(); | ||
2599 | sched_ttwu_do_pending(list); | ||
2600 | irq_exit(); | ||
2569 | } | 2601 | } |
2570 | 2602 | ||
2571 | static void ttwu_queue_remote(struct task_struct *p, int cpu) | 2603 | static void ttwu_queue_remote(struct task_struct *p, int cpu) |
@@ -6557,7 +6589,7 @@ static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level, | |||
6557 | break; | 6589 | break; |
6558 | } | 6590 | } |
6559 | 6591 | ||
6560 | if (!group->cpu_power) { | 6592 | if (!group->sgp->power) { |
6561 | printk(KERN_CONT "\n"); | 6593 | printk(KERN_CONT "\n"); |
6562 | printk(KERN_ERR "ERROR: domain->cpu_power not " | 6594 | printk(KERN_ERR "ERROR: domain->cpu_power not " |
6563 | "set\n"); | 6595 | "set\n"); |
@@ -6581,9 +6613,9 @@ static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level, | |||
6581 | cpulist_scnprintf(str, sizeof(str), sched_group_cpus(group)); | 6613 | cpulist_scnprintf(str, sizeof(str), sched_group_cpus(group)); |
6582 | 6614 | ||
6583 | printk(KERN_CONT " %s", str); | 6615 | printk(KERN_CONT " %s", str); |
6584 | if (group->cpu_power != SCHED_POWER_SCALE) { | 6616 | if (group->sgp->power != SCHED_POWER_SCALE) { |
6585 | printk(KERN_CONT " (cpu_power = %d)", | 6617 | printk(KERN_CONT " (cpu_power = %d)", |
6586 | group->cpu_power); | 6618 | group->sgp->power); |
6587 | } | 6619 | } |
6588 | 6620 | ||
6589 | group = group->next; | 6621 | group = group->next; |
@@ -6774,11 +6806,39 @@ static struct root_domain *alloc_rootdomain(void) | |||
6774 | return rd; | 6806 | return rd; |
6775 | } | 6807 | } |
6776 | 6808 | ||
6809 | static void free_sched_groups(struct sched_group *sg, int free_sgp) | ||
6810 | { | ||
6811 | struct sched_group *tmp, *first; | ||
6812 | |||
6813 | if (!sg) | ||
6814 | return; | ||
6815 | |||
6816 | first = sg; | ||
6817 | do { | ||
6818 | tmp = sg->next; | ||
6819 | |||
6820 | if (free_sgp && atomic_dec_and_test(&sg->sgp->ref)) | ||
6821 | kfree(sg->sgp); | ||
6822 | |||
6823 | kfree(sg); | ||
6824 | sg = tmp; | ||
6825 | } while (sg != first); | ||
6826 | } | ||
6827 | |||
6777 | static void free_sched_domain(struct rcu_head *rcu) | 6828 | static void free_sched_domain(struct rcu_head *rcu) |
6778 | { | 6829 | { |
6779 | struct sched_domain *sd = container_of(rcu, struct sched_domain, rcu); | 6830 | struct sched_domain *sd = container_of(rcu, struct sched_domain, rcu); |
6780 | if (atomic_dec_and_test(&sd->groups->ref)) | 6831 | |
6832 | /* | ||
6833 | * If its an overlapping domain it has private groups, iterate and | ||
6834 | * nuke them all. | ||
6835 | */ | ||
6836 | if (sd->flags & SD_OVERLAP) { | ||
6837 | free_sched_groups(sd->groups, 1); | ||
6838 | } else if (atomic_dec_and_test(&sd->groups->ref)) { | ||
6839 | kfree(sd->groups->sgp); | ||
6781 | kfree(sd->groups); | 6840 | kfree(sd->groups); |
6841 | } | ||
6782 | kfree(sd); | 6842 | kfree(sd); |
6783 | } | 6843 | } |
6784 | 6844 | ||
@@ -6945,6 +7005,7 @@ int sched_smt_power_savings = 0, sched_mc_power_savings = 0; | |||
6945 | struct sd_data { | 7005 | struct sd_data { |
6946 | struct sched_domain **__percpu sd; | 7006 | struct sched_domain **__percpu sd; |
6947 | struct sched_group **__percpu sg; | 7007 | struct sched_group **__percpu sg; |
7008 | struct sched_group_power **__percpu sgp; | ||
6948 | }; | 7009 | }; |
6949 | 7010 | ||
6950 | struct s_data { | 7011 | struct s_data { |
@@ -6964,15 +7025,73 @@ struct sched_domain_topology_level; | |||
6964 | typedef struct sched_domain *(*sched_domain_init_f)(struct sched_domain_topology_level *tl, int cpu); | 7025 | typedef struct sched_domain *(*sched_domain_init_f)(struct sched_domain_topology_level *tl, int cpu); |
6965 | typedef const struct cpumask *(*sched_domain_mask_f)(int cpu); | 7026 | typedef const struct cpumask *(*sched_domain_mask_f)(int cpu); |
6966 | 7027 | ||
7028 | #define SDTL_OVERLAP 0x01 | ||
7029 | |||
6967 | struct sched_domain_topology_level { | 7030 | struct sched_domain_topology_level { |
6968 | sched_domain_init_f init; | 7031 | sched_domain_init_f init; |
6969 | sched_domain_mask_f mask; | 7032 | sched_domain_mask_f mask; |
7033 | int flags; | ||
6970 | struct sd_data data; | 7034 | struct sd_data data; |
6971 | }; | 7035 | }; |
6972 | 7036 | ||
6973 | /* | 7037 | static int |
6974 | * Assumes the sched_domain tree is fully constructed | 7038 | build_overlap_sched_groups(struct sched_domain *sd, int cpu) |
6975 | */ | 7039 | { |
7040 | struct sched_group *first = NULL, *last = NULL, *groups = NULL, *sg; | ||
7041 | const struct cpumask *span = sched_domain_span(sd); | ||
7042 | struct cpumask *covered = sched_domains_tmpmask; | ||
7043 | struct sd_data *sdd = sd->private; | ||
7044 | struct sched_domain *child; | ||
7045 | int i; | ||
7046 | |||
7047 | cpumask_clear(covered); | ||
7048 | |||
7049 | for_each_cpu(i, span) { | ||
7050 | struct cpumask *sg_span; | ||
7051 | |||
7052 | if (cpumask_test_cpu(i, covered)) | ||
7053 | continue; | ||
7054 | |||
7055 | sg = kzalloc_node(sizeof(struct sched_group) + cpumask_size(), | ||
7056 | GFP_KERNEL, cpu_to_node(i)); | ||
7057 | |||
7058 | if (!sg) | ||
7059 | goto fail; | ||
7060 | |||
7061 | sg_span = sched_group_cpus(sg); | ||
7062 | |||
7063 | child = *per_cpu_ptr(sdd->sd, i); | ||
7064 | if (child->child) { | ||
7065 | child = child->child; | ||
7066 | cpumask_copy(sg_span, sched_domain_span(child)); | ||
7067 | } else | ||
7068 | cpumask_set_cpu(i, sg_span); | ||
7069 | |||
7070 | cpumask_or(covered, covered, sg_span); | ||
7071 | |||
7072 | sg->sgp = *per_cpu_ptr(sdd->sgp, cpumask_first(sg_span)); | ||
7073 | atomic_inc(&sg->sgp->ref); | ||
7074 | |||
7075 | if (cpumask_test_cpu(cpu, sg_span)) | ||
7076 | groups = sg; | ||
7077 | |||
7078 | if (!first) | ||
7079 | first = sg; | ||
7080 | if (last) | ||
7081 | last->next = sg; | ||
7082 | last = sg; | ||
7083 | last->next = first; | ||
7084 | } | ||
7085 | sd->groups = groups; | ||
7086 | |||
7087 | return 0; | ||
7088 | |||
7089 | fail: | ||
7090 | free_sched_groups(first, 0); | ||
7091 | |||
7092 | return -ENOMEM; | ||
7093 | } | ||
7094 | |||
6976 | static int get_group(int cpu, struct sd_data *sdd, struct sched_group **sg) | 7095 | static int get_group(int cpu, struct sd_data *sdd, struct sched_group **sg) |
6977 | { | 7096 | { |
6978 | struct sched_domain *sd = *per_cpu_ptr(sdd->sd, cpu); | 7097 | struct sched_domain *sd = *per_cpu_ptr(sdd->sd, cpu); |
@@ -6981,24 +7100,24 @@ static int get_group(int cpu, struct sd_data *sdd, struct sched_group **sg) | |||
6981 | if (child) | 7100 | if (child) |
6982 | cpu = cpumask_first(sched_domain_span(child)); | 7101 | cpu = cpumask_first(sched_domain_span(child)); |
6983 | 7102 | ||
6984 | if (sg) | 7103 | if (sg) { |
6985 | *sg = *per_cpu_ptr(sdd->sg, cpu); | 7104 | *sg = *per_cpu_ptr(sdd->sg, cpu); |
7105 | (*sg)->sgp = *per_cpu_ptr(sdd->sgp, cpu); | ||
7106 | atomic_set(&(*sg)->sgp->ref, 1); /* for claim_allocations */ | ||
7107 | } | ||
6986 | 7108 | ||
6987 | return cpu; | 7109 | return cpu; |
6988 | } | 7110 | } |
6989 | 7111 | ||
6990 | /* | 7112 | /* |
6991 | * build_sched_groups takes the cpumask we wish to span, and a pointer | ||
6992 | * to a function which identifies what group(along with sched group) a CPU | ||
6993 | * belongs to. The return value of group_fn must be a >= 0 and < nr_cpu_ids | ||
6994 | * (due to the fact that we keep track of groups covered with a struct cpumask). | ||
6995 | * | ||
6996 | * build_sched_groups will build a circular linked list of the groups | 7113 | * build_sched_groups will build a circular linked list of the groups |
6997 | * covered by the given span, and will set each group's ->cpumask correctly, | 7114 | * covered by the given span, and will set each group's ->cpumask correctly, |
6998 | * and ->cpu_power to 0. | 7115 | * and ->cpu_power to 0. |
7116 | * | ||
7117 | * Assumes the sched_domain tree is fully constructed | ||
6999 | */ | 7118 | */ |
7000 | static void | 7119 | static int |
7001 | build_sched_groups(struct sched_domain *sd) | 7120 | build_sched_groups(struct sched_domain *sd, int cpu) |
7002 | { | 7121 | { |
7003 | struct sched_group *first = NULL, *last = NULL; | 7122 | struct sched_group *first = NULL, *last = NULL; |
7004 | struct sd_data *sdd = sd->private; | 7123 | struct sd_data *sdd = sd->private; |
@@ -7006,6 +7125,12 @@ build_sched_groups(struct sched_domain *sd) | |||
7006 | struct cpumask *covered; | 7125 | struct cpumask *covered; |
7007 | int i; | 7126 | int i; |
7008 | 7127 | ||
7128 | get_group(cpu, sdd, &sd->groups); | ||
7129 | atomic_inc(&sd->groups->ref); | ||
7130 | |||
7131 | if (cpu != cpumask_first(sched_domain_span(sd))) | ||
7132 | return 0; | ||
7133 | |||
7009 | lockdep_assert_held(&sched_domains_mutex); | 7134 | lockdep_assert_held(&sched_domains_mutex); |
7010 | covered = sched_domains_tmpmask; | 7135 | covered = sched_domains_tmpmask; |
7011 | 7136 | ||
@@ -7020,7 +7145,7 @@ build_sched_groups(struct sched_domain *sd) | |||
7020 | continue; | 7145 | continue; |
7021 | 7146 | ||
7022 | cpumask_clear(sched_group_cpus(sg)); | 7147 | cpumask_clear(sched_group_cpus(sg)); |
7023 | sg->cpu_power = 0; | 7148 | sg->sgp->power = 0; |
7024 | 7149 | ||
7025 | for_each_cpu(j, span) { | 7150 | for_each_cpu(j, span) { |
7026 | if (get_group(j, sdd, NULL) != group) | 7151 | if (get_group(j, sdd, NULL) != group) |
@@ -7037,6 +7162,8 @@ build_sched_groups(struct sched_domain *sd) | |||
7037 | last = sg; | 7162 | last = sg; |
7038 | } | 7163 | } |
7039 | last->next = first; | 7164 | last->next = first; |
7165 | |||
7166 | return 0; | ||
7040 | } | 7167 | } |
7041 | 7168 | ||
7042 | /* | 7169 | /* |
@@ -7051,12 +7178,17 @@ build_sched_groups(struct sched_domain *sd) | |||
7051 | */ | 7178 | */ |
7052 | static void init_sched_groups_power(int cpu, struct sched_domain *sd) | 7179 | static void init_sched_groups_power(int cpu, struct sched_domain *sd) |
7053 | { | 7180 | { |
7054 | WARN_ON(!sd || !sd->groups); | 7181 | struct sched_group *sg = sd->groups; |
7055 | 7182 | ||
7056 | if (cpu != group_first_cpu(sd->groups)) | 7183 | WARN_ON(!sd || !sg); |
7057 | return; | 7184 | |
7185 | do { | ||
7186 | sg->group_weight = cpumask_weight(sched_group_cpus(sg)); | ||
7187 | sg = sg->next; | ||
7188 | } while (sg != sd->groups); | ||
7058 | 7189 | ||
7059 | sd->groups->group_weight = cpumask_weight(sched_group_cpus(sd->groups)); | 7190 | if (cpu != group_first_cpu(sg)) |
7191 | return; | ||
7060 | 7192 | ||
7061 | update_group_power(sd, cpu); | 7193 | update_group_power(sd, cpu); |
7062 | } | 7194 | } |
@@ -7177,15 +7309,15 @@ static enum s_alloc __visit_domain_allocation_hell(struct s_data *d, | |||
7177 | static void claim_allocations(int cpu, struct sched_domain *sd) | 7309 | static void claim_allocations(int cpu, struct sched_domain *sd) |
7178 | { | 7310 | { |
7179 | struct sd_data *sdd = sd->private; | 7311 | struct sd_data *sdd = sd->private; |
7180 | struct sched_group *sg = sd->groups; | ||
7181 | 7312 | ||
7182 | WARN_ON_ONCE(*per_cpu_ptr(sdd->sd, cpu) != sd); | 7313 | WARN_ON_ONCE(*per_cpu_ptr(sdd->sd, cpu) != sd); |
7183 | *per_cpu_ptr(sdd->sd, cpu) = NULL; | 7314 | *per_cpu_ptr(sdd->sd, cpu) = NULL; |
7184 | 7315 | ||
7185 | if (cpu == cpumask_first(sched_group_cpus(sg))) { | 7316 | if (atomic_read(&(*per_cpu_ptr(sdd->sg, cpu))->ref)) |
7186 | WARN_ON_ONCE(*per_cpu_ptr(sdd->sg, cpu) != sg); | ||
7187 | *per_cpu_ptr(sdd->sg, cpu) = NULL; | 7317 | *per_cpu_ptr(sdd->sg, cpu) = NULL; |
7188 | } | 7318 | |
7319 | if (atomic_read(&(*per_cpu_ptr(sdd->sgp, cpu))->ref)) | ||
7320 | *per_cpu_ptr(sdd->sgp, cpu) = NULL; | ||
7189 | } | 7321 | } |
7190 | 7322 | ||
7191 | #ifdef CONFIG_SCHED_SMT | 7323 | #ifdef CONFIG_SCHED_SMT |
@@ -7210,7 +7342,7 @@ static struct sched_domain_topology_level default_topology[] = { | |||
7210 | #endif | 7342 | #endif |
7211 | { sd_init_CPU, cpu_cpu_mask, }, | 7343 | { sd_init_CPU, cpu_cpu_mask, }, |
7212 | #ifdef CONFIG_NUMA | 7344 | #ifdef CONFIG_NUMA |
7213 | { sd_init_NODE, cpu_node_mask, }, | 7345 | { sd_init_NODE, cpu_node_mask, SDTL_OVERLAP, }, |
7214 | { sd_init_ALLNODES, cpu_allnodes_mask, }, | 7346 | { sd_init_ALLNODES, cpu_allnodes_mask, }, |
7215 | #endif | 7347 | #endif |
7216 | { NULL, }, | 7348 | { NULL, }, |
@@ -7234,9 +7366,14 @@ static int __sdt_alloc(const struct cpumask *cpu_map) | |||
7234 | if (!sdd->sg) | 7366 | if (!sdd->sg) |
7235 | return -ENOMEM; | 7367 | return -ENOMEM; |
7236 | 7368 | ||
7369 | sdd->sgp = alloc_percpu(struct sched_group_power *); | ||
7370 | if (!sdd->sgp) | ||
7371 | return -ENOMEM; | ||
7372 | |||
7237 | for_each_cpu(j, cpu_map) { | 7373 | for_each_cpu(j, cpu_map) { |
7238 | struct sched_domain *sd; | 7374 | struct sched_domain *sd; |
7239 | struct sched_group *sg; | 7375 | struct sched_group *sg; |
7376 | struct sched_group_power *sgp; | ||
7240 | 7377 | ||
7241 | sd = kzalloc_node(sizeof(struct sched_domain) + cpumask_size(), | 7378 | sd = kzalloc_node(sizeof(struct sched_domain) + cpumask_size(), |
7242 | GFP_KERNEL, cpu_to_node(j)); | 7379 | GFP_KERNEL, cpu_to_node(j)); |
@@ -7251,6 +7388,13 @@ static int __sdt_alloc(const struct cpumask *cpu_map) | |||
7251 | return -ENOMEM; | 7388 | return -ENOMEM; |
7252 | 7389 | ||
7253 | *per_cpu_ptr(sdd->sg, j) = sg; | 7390 | *per_cpu_ptr(sdd->sg, j) = sg; |
7391 | |||
7392 | sgp = kzalloc_node(sizeof(struct sched_group_power), | ||
7393 | GFP_KERNEL, cpu_to_node(j)); | ||
7394 | if (!sgp) | ||
7395 | return -ENOMEM; | ||
7396 | |||
7397 | *per_cpu_ptr(sdd->sgp, j) = sgp; | ||
7254 | } | 7398 | } |
7255 | } | 7399 | } |
7256 | 7400 | ||
@@ -7266,11 +7410,15 @@ static void __sdt_free(const struct cpumask *cpu_map) | |||
7266 | struct sd_data *sdd = &tl->data; | 7410 | struct sd_data *sdd = &tl->data; |
7267 | 7411 | ||
7268 | for_each_cpu(j, cpu_map) { | 7412 | for_each_cpu(j, cpu_map) { |
7269 | kfree(*per_cpu_ptr(sdd->sd, j)); | 7413 | struct sched_domain *sd = *per_cpu_ptr(sdd->sd, j); |
7414 | if (sd && (sd->flags & SD_OVERLAP)) | ||
7415 | free_sched_groups(sd->groups, 0); | ||
7270 | kfree(*per_cpu_ptr(sdd->sg, j)); | 7416 | kfree(*per_cpu_ptr(sdd->sg, j)); |
7417 | kfree(*per_cpu_ptr(sdd->sgp, j)); | ||
7271 | } | 7418 | } |
7272 | free_percpu(sdd->sd); | 7419 | free_percpu(sdd->sd); |
7273 | free_percpu(sdd->sg); | 7420 | free_percpu(sdd->sg); |
7421 | free_percpu(sdd->sgp); | ||
7274 | } | 7422 | } |
7275 | } | 7423 | } |
7276 | 7424 | ||
@@ -7316,8 +7464,13 @@ static int build_sched_domains(const struct cpumask *cpu_map, | |||
7316 | struct sched_domain_topology_level *tl; | 7464 | struct sched_domain_topology_level *tl; |
7317 | 7465 | ||
7318 | sd = NULL; | 7466 | sd = NULL; |
7319 | for (tl = sched_domain_topology; tl->init; tl++) | 7467 | for (tl = sched_domain_topology; tl->init; tl++) { |
7320 | sd = build_sched_domain(tl, &d, cpu_map, attr, sd, i); | 7468 | sd = build_sched_domain(tl, &d, cpu_map, attr, sd, i); |
7469 | if (tl->flags & SDTL_OVERLAP || sched_feat(FORCE_SD_OVERLAP)) | ||
7470 | sd->flags |= SD_OVERLAP; | ||
7471 | if (cpumask_equal(cpu_map, sched_domain_span(sd))) | ||
7472 | break; | ||
7473 | } | ||
7321 | 7474 | ||
7322 | while (sd->child) | 7475 | while (sd->child) |
7323 | sd = sd->child; | 7476 | sd = sd->child; |
@@ -7329,13 +7482,13 @@ static int build_sched_domains(const struct cpumask *cpu_map, | |||
7329 | for_each_cpu(i, cpu_map) { | 7482 | for_each_cpu(i, cpu_map) { |
7330 | for (sd = *per_cpu_ptr(d.sd, i); sd; sd = sd->parent) { | 7483 | for (sd = *per_cpu_ptr(d.sd, i); sd; sd = sd->parent) { |
7331 | sd->span_weight = cpumask_weight(sched_domain_span(sd)); | 7484 | sd->span_weight = cpumask_weight(sched_domain_span(sd)); |
7332 | get_group(i, sd->private, &sd->groups); | 7485 | if (sd->flags & SD_OVERLAP) { |
7333 | atomic_inc(&sd->groups->ref); | 7486 | if (build_overlap_sched_groups(sd, i)) |
7334 | 7487 | goto error; | |
7335 | if (i != cpumask_first(sched_domain_span(sd))) | 7488 | } else { |
7336 | continue; | 7489 | if (build_sched_groups(sd, i)) |
7337 | 7490 | goto error; | |
7338 | build_sched_groups(sd); | 7491 | } |
7339 | } | 7492 | } |
7340 | } | 7493 | } |
7341 | 7494 | ||
@@ -7757,6 +7910,9 @@ static void init_cfs_rq(struct cfs_rq *cfs_rq, struct rq *rq) | |||
7757 | #endif | 7910 | #endif |
7758 | #endif | 7911 | #endif |
7759 | cfs_rq->min_vruntime = (u64)(-(1LL << 20)); | 7912 | cfs_rq->min_vruntime = (u64)(-(1LL << 20)); |
7913 | #ifndef CONFIG_64BIT | ||
7914 | cfs_rq->min_vruntime_copy = cfs_rq->min_vruntime; | ||
7915 | #endif | ||
7760 | } | 7916 | } |
7761 | 7917 | ||
7762 | static void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq) | 7918 | static void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq) |
@@ -8450,10 +8606,7 @@ int sched_group_set_shares(struct task_group *tg, unsigned long shares) | |||
8450 | if (!tg->se[0]) | 8606 | if (!tg->se[0]) |
8451 | return -EINVAL; | 8607 | return -EINVAL; |
8452 | 8608 | ||
8453 | if (shares < MIN_SHARES) | 8609 | shares = clamp(shares, scale_load(MIN_SHARES), scale_load(MAX_SHARES)); |
8454 | shares = MIN_SHARES; | ||
8455 | else if (shares > MAX_SHARES) | ||
8456 | shares = MAX_SHARES; | ||
8457 | 8610 | ||
8458 | mutex_lock(&shares_mutex); | 8611 | mutex_lock(&shares_mutex); |
8459 | if (tg->shares == shares) | 8612 | if (tg->shares == shares) |
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 433491c2dc8f..c768588e180b 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
@@ -1585,7 +1585,7 @@ find_idlest_group(struct sched_domain *sd, struct task_struct *p, | |||
1585 | } | 1585 | } |
1586 | 1586 | ||
1587 | /* Adjust by relative CPU power of the group */ | 1587 | /* Adjust by relative CPU power of the group */ |
1588 | avg_load = (avg_load * SCHED_POWER_SCALE) / group->cpu_power; | 1588 | avg_load = (avg_load * SCHED_POWER_SCALE) / group->sgp->power; |
1589 | 1589 | ||
1590 | if (local_group) { | 1590 | if (local_group) { |
1591 | this_load = avg_load; | 1591 | this_load = avg_load; |
@@ -2631,7 +2631,7 @@ static void update_cpu_power(struct sched_domain *sd, int cpu) | |||
2631 | power >>= SCHED_POWER_SHIFT; | 2631 | power >>= SCHED_POWER_SHIFT; |
2632 | } | 2632 | } |
2633 | 2633 | ||
2634 | sdg->cpu_power_orig = power; | 2634 | sdg->sgp->power_orig = power; |
2635 | 2635 | ||
2636 | if (sched_feat(ARCH_POWER)) | 2636 | if (sched_feat(ARCH_POWER)) |
2637 | power *= arch_scale_freq_power(sd, cpu); | 2637 | power *= arch_scale_freq_power(sd, cpu); |
@@ -2647,7 +2647,7 @@ static void update_cpu_power(struct sched_domain *sd, int cpu) | |||
2647 | power = 1; | 2647 | power = 1; |
2648 | 2648 | ||
2649 | cpu_rq(cpu)->cpu_power = power; | 2649 | cpu_rq(cpu)->cpu_power = power; |
2650 | sdg->cpu_power = power; | 2650 | sdg->sgp->power = power; |
2651 | } | 2651 | } |
2652 | 2652 | ||
2653 | static void update_group_power(struct sched_domain *sd, int cpu) | 2653 | static void update_group_power(struct sched_domain *sd, int cpu) |
@@ -2665,11 +2665,11 @@ static void update_group_power(struct sched_domain *sd, int cpu) | |||
2665 | 2665 | ||
2666 | group = child->groups; | 2666 | group = child->groups; |
2667 | do { | 2667 | do { |
2668 | power += group->cpu_power; | 2668 | power += group->sgp->power; |
2669 | group = group->next; | 2669 | group = group->next; |
2670 | } while (group != child->groups); | 2670 | } while (group != child->groups); |
2671 | 2671 | ||
2672 | sdg->cpu_power = power; | 2672 | sdg->sgp->power = power; |
2673 | } | 2673 | } |
2674 | 2674 | ||
2675 | /* | 2675 | /* |
@@ -2691,7 +2691,7 @@ fix_small_capacity(struct sched_domain *sd, struct sched_group *group) | |||
2691 | /* | 2691 | /* |
2692 | * If ~90% of the cpu_power is still there, we're good. | 2692 | * If ~90% of the cpu_power is still there, we're good. |
2693 | */ | 2693 | */ |
2694 | if (group->cpu_power * 32 > group->cpu_power_orig * 29) | 2694 | if (group->sgp->power * 32 > group->sgp->power_orig * 29) |
2695 | return 1; | 2695 | return 1; |
2696 | 2696 | ||
2697 | return 0; | 2697 | return 0; |
@@ -2771,7 +2771,7 @@ static inline void update_sg_lb_stats(struct sched_domain *sd, | |||
2771 | } | 2771 | } |
2772 | 2772 | ||
2773 | /* Adjust by relative CPU power of the group */ | 2773 | /* Adjust by relative CPU power of the group */ |
2774 | sgs->avg_load = (sgs->group_load*SCHED_POWER_SCALE) / group->cpu_power; | 2774 | sgs->avg_load = (sgs->group_load*SCHED_POWER_SCALE) / group->sgp->power; |
2775 | 2775 | ||
2776 | /* | 2776 | /* |
2777 | * Consider the group unbalanced when the imbalance is larger | 2777 | * Consider the group unbalanced when the imbalance is larger |
@@ -2788,7 +2788,7 @@ static inline void update_sg_lb_stats(struct sched_domain *sd, | |||
2788 | if ((max_cpu_load - min_cpu_load) >= avg_load_per_task && max_nr_running > 1) | 2788 | if ((max_cpu_load - min_cpu_load) >= avg_load_per_task && max_nr_running > 1) |
2789 | sgs->group_imb = 1; | 2789 | sgs->group_imb = 1; |
2790 | 2790 | ||
2791 | sgs->group_capacity = DIV_ROUND_CLOSEST(group->cpu_power, | 2791 | sgs->group_capacity = DIV_ROUND_CLOSEST(group->sgp->power, |
2792 | SCHED_POWER_SCALE); | 2792 | SCHED_POWER_SCALE); |
2793 | if (!sgs->group_capacity) | 2793 | if (!sgs->group_capacity) |
2794 | sgs->group_capacity = fix_small_capacity(sd, group); | 2794 | sgs->group_capacity = fix_small_capacity(sd, group); |
@@ -2877,7 +2877,7 @@ static inline void update_sd_lb_stats(struct sched_domain *sd, int this_cpu, | |||
2877 | return; | 2877 | return; |
2878 | 2878 | ||
2879 | sds->total_load += sgs.group_load; | 2879 | sds->total_load += sgs.group_load; |
2880 | sds->total_pwr += sg->cpu_power; | 2880 | sds->total_pwr += sg->sgp->power; |
2881 | 2881 | ||
2882 | /* | 2882 | /* |
2883 | * In case the child domain prefers tasks go to siblings | 2883 | * In case the child domain prefers tasks go to siblings |
@@ -2962,7 +2962,7 @@ static int check_asym_packing(struct sched_domain *sd, | |||
2962 | if (this_cpu > busiest_cpu) | 2962 | if (this_cpu > busiest_cpu) |
2963 | return 0; | 2963 | return 0; |
2964 | 2964 | ||
2965 | *imbalance = DIV_ROUND_CLOSEST(sds->max_load * sds->busiest->cpu_power, | 2965 | *imbalance = DIV_ROUND_CLOSEST(sds->max_load * sds->busiest->sgp->power, |
2966 | SCHED_POWER_SCALE); | 2966 | SCHED_POWER_SCALE); |
2967 | return 1; | 2967 | return 1; |
2968 | } | 2968 | } |
@@ -2993,7 +2993,7 @@ static inline void fix_small_imbalance(struct sd_lb_stats *sds, | |||
2993 | 2993 | ||
2994 | scaled_busy_load_per_task = sds->busiest_load_per_task | 2994 | scaled_busy_load_per_task = sds->busiest_load_per_task |
2995 | * SCHED_POWER_SCALE; | 2995 | * SCHED_POWER_SCALE; |
2996 | scaled_busy_load_per_task /= sds->busiest->cpu_power; | 2996 | scaled_busy_load_per_task /= sds->busiest->sgp->power; |
2997 | 2997 | ||
2998 | if (sds->max_load - sds->this_load + scaled_busy_load_per_task >= | 2998 | if (sds->max_load - sds->this_load + scaled_busy_load_per_task >= |
2999 | (scaled_busy_load_per_task * imbn)) { | 2999 | (scaled_busy_load_per_task * imbn)) { |
@@ -3007,28 +3007,28 @@ static inline void fix_small_imbalance(struct sd_lb_stats *sds, | |||
3007 | * moving them. | 3007 | * moving them. |
3008 | */ | 3008 | */ |
3009 | 3009 | ||
3010 | pwr_now += sds->busiest->cpu_power * | 3010 | pwr_now += sds->busiest->sgp->power * |
3011 | min(sds->busiest_load_per_task, sds->max_load); | 3011 | min(sds->busiest_load_per_task, sds->max_load); |
3012 | pwr_now += sds->this->cpu_power * | 3012 | pwr_now += sds->this->sgp->power * |
3013 | min(sds->this_load_per_task, sds->this_load); | 3013 | min(sds->this_load_per_task, sds->this_load); |
3014 | pwr_now /= SCHED_POWER_SCALE; | 3014 | pwr_now /= SCHED_POWER_SCALE; |
3015 | 3015 | ||
3016 | /* Amount of load we'd subtract */ | 3016 | /* Amount of load we'd subtract */ |
3017 | tmp = (sds->busiest_load_per_task * SCHED_POWER_SCALE) / | 3017 | tmp = (sds->busiest_load_per_task * SCHED_POWER_SCALE) / |
3018 | sds->busiest->cpu_power; | 3018 | sds->busiest->sgp->power; |
3019 | if (sds->max_load > tmp) | 3019 | if (sds->max_load > tmp) |
3020 | pwr_move += sds->busiest->cpu_power * | 3020 | pwr_move += sds->busiest->sgp->power * |
3021 | min(sds->busiest_load_per_task, sds->max_load - tmp); | 3021 | min(sds->busiest_load_per_task, sds->max_load - tmp); |
3022 | 3022 | ||
3023 | /* Amount of load we'd add */ | 3023 | /* Amount of load we'd add */ |
3024 | if (sds->max_load * sds->busiest->cpu_power < | 3024 | if (sds->max_load * sds->busiest->sgp->power < |
3025 | sds->busiest_load_per_task * SCHED_POWER_SCALE) | 3025 | sds->busiest_load_per_task * SCHED_POWER_SCALE) |
3026 | tmp = (sds->max_load * sds->busiest->cpu_power) / | 3026 | tmp = (sds->max_load * sds->busiest->sgp->power) / |
3027 | sds->this->cpu_power; | 3027 | sds->this->sgp->power; |
3028 | else | 3028 | else |
3029 | tmp = (sds->busiest_load_per_task * SCHED_POWER_SCALE) / | 3029 | tmp = (sds->busiest_load_per_task * SCHED_POWER_SCALE) / |
3030 | sds->this->cpu_power; | 3030 | sds->this->sgp->power; |
3031 | pwr_move += sds->this->cpu_power * | 3031 | pwr_move += sds->this->sgp->power * |
3032 | min(sds->this_load_per_task, sds->this_load + tmp); | 3032 | min(sds->this_load_per_task, sds->this_load + tmp); |
3033 | pwr_move /= SCHED_POWER_SCALE; | 3033 | pwr_move /= SCHED_POWER_SCALE; |
3034 | 3034 | ||
@@ -3074,7 +3074,7 @@ static inline void calculate_imbalance(struct sd_lb_stats *sds, int this_cpu, | |||
3074 | 3074 | ||
3075 | load_above_capacity *= (SCHED_LOAD_SCALE * SCHED_POWER_SCALE); | 3075 | load_above_capacity *= (SCHED_LOAD_SCALE * SCHED_POWER_SCALE); |
3076 | 3076 | ||
3077 | load_above_capacity /= sds->busiest->cpu_power; | 3077 | load_above_capacity /= sds->busiest->sgp->power; |
3078 | } | 3078 | } |
3079 | 3079 | ||
3080 | /* | 3080 | /* |
@@ -3090,8 +3090,8 @@ static inline void calculate_imbalance(struct sd_lb_stats *sds, int this_cpu, | |||
3090 | max_pull = min(sds->max_load - sds->avg_load, load_above_capacity); | 3090 | max_pull = min(sds->max_load - sds->avg_load, load_above_capacity); |
3091 | 3091 | ||
3092 | /* How much load to actually move to equalise the imbalance */ | 3092 | /* How much load to actually move to equalise the imbalance */ |
3093 | *imbalance = min(max_pull * sds->busiest->cpu_power, | 3093 | *imbalance = min(max_pull * sds->busiest->sgp->power, |
3094 | (sds->avg_load - sds->this_load) * sds->this->cpu_power) | 3094 | (sds->avg_load - sds->this_load) * sds->this->sgp->power) |
3095 | / SCHED_POWER_SCALE; | 3095 | / SCHED_POWER_SCALE; |
3096 | 3096 | ||
3097 | /* | 3097 | /* |
diff --git a/kernel/sched_features.h b/kernel/sched_features.h index be40f7371ee1..1e7066d76c26 100644 --- a/kernel/sched_features.h +++ b/kernel/sched_features.h | |||
@@ -70,3 +70,5 @@ SCHED_FEAT(NONIRQ_POWER, 1) | |||
70 | * using the scheduler IPI. Reduces rq->lock contention/bounces. | 70 | * using the scheduler IPI. Reduces rq->lock contention/bounces. |
71 | */ | 71 | */ |
72 | SCHED_FEAT(TTWU_QUEUE, 1) | 72 | SCHED_FEAT(TTWU_QUEUE, 1) |
73 | |||
74 | SCHED_FEAT(FORCE_SD_OVERLAP, 0) | ||
diff --git a/kernel/signal.c b/kernel/signal.c index ff7678603328..415d85d6f6c6 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -1178,18 +1178,25 @@ struct sighand_struct *__lock_task_sighand(struct task_struct *tsk, | |||
1178 | { | 1178 | { |
1179 | struct sighand_struct *sighand; | 1179 | struct sighand_struct *sighand; |
1180 | 1180 | ||
1181 | rcu_read_lock(); | ||
1182 | for (;;) { | 1181 | for (;;) { |
1182 | local_irq_save(*flags); | ||
1183 | rcu_read_lock(); | ||
1183 | sighand = rcu_dereference(tsk->sighand); | 1184 | sighand = rcu_dereference(tsk->sighand); |
1184 | if (unlikely(sighand == NULL)) | 1185 | if (unlikely(sighand == NULL)) { |
1186 | rcu_read_unlock(); | ||
1187 | local_irq_restore(*flags); | ||
1185 | break; | 1188 | break; |
1189 | } | ||
1186 | 1190 | ||
1187 | spin_lock_irqsave(&sighand->siglock, *flags); | 1191 | spin_lock(&sighand->siglock); |
1188 | if (likely(sighand == tsk->sighand)) | 1192 | if (likely(sighand == tsk->sighand)) { |
1193 | rcu_read_unlock(); | ||
1189 | break; | 1194 | break; |
1190 | spin_unlock_irqrestore(&sighand->siglock, *flags); | 1195 | } |
1196 | spin_unlock(&sighand->siglock); | ||
1197 | rcu_read_unlock(); | ||
1198 | local_irq_restore(*flags); | ||
1191 | } | 1199 | } |
1192 | rcu_read_unlock(); | ||
1193 | 1200 | ||
1194 | return sighand; | 1201 | return sighand; |
1195 | } | 1202 | } |
diff --git a/kernel/softirq.c b/kernel/softirq.c index 40cf63ddd4b3..fca82c32042b 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c | |||
@@ -315,16 +315,24 @@ static inline void invoke_softirq(void) | |||
315 | { | 315 | { |
316 | if (!force_irqthreads) | 316 | if (!force_irqthreads) |
317 | __do_softirq(); | 317 | __do_softirq(); |
318 | else | 318 | else { |
319 | __local_bh_disable((unsigned long)__builtin_return_address(0), | ||
320 | SOFTIRQ_OFFSET); | ||
319 | wakeup_softirqd(); | 321 | wakeup_softirqd(); |
322 | __local_bh_enable(SOFTIRQ_OFFSET); | ||
323 | } | ||
320 | } | 324 | } |
321 | #else | 325 | #else |
322 | static inline void invoke_softirq(void) | 326 | static inline void invoke_softirq(void) |
323 | { | 327 | { |
324 | if (!force_irqthreads) | 328 | if (!force_irqthreads) |
325 | do_softirq(); | 329 | do_softirq(); |
326 | else | 330 | else { |
331 | __local_bh_disable((unsigned long)__builtin_return_address(0), | ||
332 | SOFTIRQ_OFFSET); | ||
327 | wakeup_softirqd(); | 333 | wakeup_softirqd(); |
334 | __local_bh_enable(SOFTIRQ_OFFSET); | ||
335 | } | ||
328 | } | 336 | } |
329 | #endif | 337 | #endif |
330 | 338 | ||
diff --git a/lib/debugobjects.c b/lib/debugobjects.c index 9d86e45086f5..a78b7c6e042c 100644 --- a/lib/debugobjects.c +++ b/lib/debugobjects.c | |||
@@ -198,7 +198,7 @@ static void free_object(struct debug_obj *obj) | |||
198 | * initialized: | 198 | * initialized: |
199 | */ | 199 | */ |
200 | if (obj_pool_free > ODEBUG_POOL_SIZE && obj_cache) | 200 | if (obj_pool_free > ODEBUG_POOL_SIZE && obj_cache) |
201 | sched = !work_pending(&debug_obj_work); | 201 | sched = keventd_up() && !work_pending(&debug_obj_work); |
202 | hlist_add_head(&obj->node, &obj_pool); | 202 | hlist_add_head(&obj->node, &obj_pool); |
203 | obj_pool_free++; | 203 | obj_pool_free++; |
204 | obj_pool_used--; | 204 | obj_pool_used--; |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index ddffc74cdebe..e013b8e57d25 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -108,10 +108,12 @@ enum mem_cgroup_events_index { | |||
108 | enum mem_cgroup_events_target { | 108 | enum mem_cgroup_events_target { |
109 | MEM_CGROUP_TARGET_THRESH, | 109 | MEM_CGROUP_TARGET_THRESH, |
110 | MEM_CGROUP_TARGET_SOFTLIMIT, | 110 | MEM_CGROUP_TARGET_SOFTLIMIT, |
111 | MEM_CGROUP_TARGET_NUMAINFO, | ||
111 | MEM_CGROUP_NTARGETS, | 112 | MEM_CGROUP_NTARGETS, |
112 | }; | 113 | }; |
113 | #define THRESHOLDS_EVENTS_TARGET (128) | 114 | #define THRESHOLDS_EVENTS_TARGET (128) |
114 | #define SOFTLIMIT_EVENTS_TARGET (1024) | 115 | #define SOFTLIMIT_EVENTS_TARGET (1024) |
116 | #define NUMAINFO_EVENTS_TARGET (1024) | ||
115 | 117 | ||
116 | struct mem_cgroup_stat_cpu { | 118 | struct mem_cgroup_stat_cpu { |
117 | long count[MEM_CGROUP_STAT_NSTATS]; | 119 | long count[MEM_CGROUP_STAT_NSTATS]; |
@@ -237,7 +239,8 @@ struct mem_cgroup { | |||
237 | int last_scanned_node; | 239 | int last_scanned_node; |
238 | #if MAX_NUMNODES > 1 | 240 | #if MAX_NUMNODES > 1 |
239 | nodemask_t scan_nodes; | 241 | nodemask_t scan_nodes; |
240 | unsigned long next_scan_node_update; | 242 | atomic_t numainfo_events; |
243 | atomic_t numainfo_updating; | ||
241 | #endif | 244 | #endif |
242 | /* | 245 | /* |
243 | * Should the accounting and control be hierarchical, per subtree? | 246 | * Should the accounting and control be hierarchical, per subtree? |
@@ -577,15 +580,6 @@ static long mem_cgroup_read_stat(struct mem_cgroup *mem, | |||
577 | return val; | 580 | return val; |
578 | } | 581 | } |
579 | 582 | ||
580 | static long mem_cgroup_local_usage(struct mem_cgroup *mem) | ||
581 | { | ||
582 | long ret; | ||
583 | |||
584 | ret = mem_cgroup_read_stat(mem, MEM_CGROUP_STAT_RSS); | ||
585 | ret += mem_cgroup_read_stat(mem, MEM_CGROUP_STAT_CACHE); | ||
586 | return ret; | ||
587 | } | ||
588 | |||
589 | static void mem_cgroup_swap_statistics(struct mem_cgroup *mem, | 583 | static void mem_cgroup_swap_statistics(struct mem_cgroup *mem, |
590 | bool charge) | 584 | bool charge) |
591 | { | 585 | { |
@@ -689,6 +683,9 @@ static void __mem_cgroup_target_update(struct mem_cgroup *mem, int target) | |||
689 | case MEM_CGROUP_TARGET_SOFTLIMIT: | 683 | case MEM_CGROUP_TARGET_SOFTLIMIT: |
690 | next = val + SOFTLIMIT_EVENTS_TARGET; | 684 | next = val + SOFTLIMIT_EVENTS_TARGET; |
691 | break; | 685 | break; |
686 | case MEM_CGROUP_TARGET_NUMAINFO: | ||
687 | next = val + NUMAINFO_EVENTS_TARGET; | ||
688 | break; | ||
692 | default: | 689 | default: |
693 | return; | 690 | return; |
694 | } | 691 | } |
@@ -707,11 +704,19 @@ static void memcg_check_events(struct mem_cgroup *mem, struct page *page) | |||
707 | mem_cgroup_threshold(mem); | 704 | mem_cgroup_threshold(mem); |
708 | __mem_cgroup_target_update(mem, MEM_CGROUP_TARGET_THRESH); | 705 | __mem_cgroup_target_update(mem, MEM_CGROUP_TARGET_THRESH); |
709 | if (unlikely(__memcg_event_check(mem, | 706 | if (unlikely(__memcg_event_check(mem, |
710 | MEM_CGROUP_TARGET_SOFTLIMIT))){ | 707 | MEM_CGROUP_TARGET_SOFTLIMIT))) { |
711 | mem_cgroup_update_tree(mem, page); | 708 | mem_cgroup_update_tree(mem, page); |
712 | __mem_cgroup_target_update(mem, | 709 | __mem_cgroup_target_update(mem, |
713 | MEM_CGROUP_TARGET_SOFTLIMIT); | 710 | MEM_CGROUP_TARGET_SOFTLIMIT); |
711 | } | ||
712 | #if MAX_NUMNODES > 1 | ||
713 | if (unlikely(__memcg_event_check(mem, | ||
714 | MEM_CGROUP_TARGET_NUMAINFO))) { | ||
715 | atomic_inc(&mem->numainfo_events); | ||
716 | __mem_cgroup_target_update(mem, | ||
717 | MEM_CGROUP_TARGET_NUMAINFO); | ||
714 | } | 718 | } |
719 | #endif | ||
715 | } | 720 | } |
716 | } | 721 | } |
717 | 722 | ||
@@ -1129,7 +1134,6 @@ unsigned long mem_cgroup_zone_nr_lru_pages(struct mem_cgroup *memcg, | |||
1129 | return MEM_CGROUP_ZSTAT(mz, lru); | 1134 | return MEM_CGROUP_ZSTAT(mz, lru); |
1130 | } | 1135 | } |
1131 | 1136 | ||
1132 | #ifdef CONFIG_NUMA | ||
1133 | static unsigned long mem_cgroup_node_nr_file_lru_pages(struct mem_cgroup *memcg, | 1137 | static unsigned long mem_cgroup_node_nr_file_lru_pages(struct mem_cgroup *memcg, |
1134 | int nid) | 1138 | int nid) |
1135 | { | 1139 | { |
@@ -1141,6 +1145,17 @@ static unsigned long mem_cgroup_node_nr_file_lru_pages(struct mem_cgroup *memcg, | |||
1141 | return ret; | 1145 | return ret; |
1142 | } | 1146 | } |
1143 | 1147 | ||
1148 | static unsigned long mem_cgroup_node_nr_anon_lru_pages(struct mem_cgroup *memcg, | ||
1149 | int nid) | ||
1150 | { | ||
1151 | unsigned long ret; | ||
1152 | |||
1153 | ret = mem_cgroup_get_zonestat_node(memcg, nid, LRU_INACTIVE_ANON) + | ||
1154 | mem_cgroup_get_zonestat_node(memcg, nid, LRU_ACTIVE_ANON); | ||
1155 | return ret; | ||
1156 | } | ||
1157 | |||
1158 | #if MAX_NUMNODES > 1 | ||
1144 | static unsigned long mem_cgroup_nr_file_lru_pages(struct mem_cgroup *memcg) | 1159 | static unsigned long mem_cgroup_nr_file_lru_pages(struct mem_cgroup *memcg) |
1145 | { | 1160 | { |
1146 | u64 total = 0; | 1161 | u64 total = 0; |
@@ -1152,17 +1167,6 @@ static unsigned long mem_cgroup_nr_file_lru_pages(struct mem_cgroup *memcg) | |||
1152 | return total; | 1167 | return total; |
1153 | } | 1168 | } |
1154 | 1169 | ||
1155 | static unsigned long mem_cgroup_node_nr_anon_lru_pages(struct mem_cgroup *memcg, | ||
1156 | int nid) | ||
1157 | { | ||
1158 | unsigned long ret; | ||
1159 | |||
1160 | ret = mem_cgroup_get_zonestat_node(memcg, nid, LRU_INACTIVE_ANON) + | ||
1161 | mem_cgroup_get_zonestat_node(memcg, nid, LRU_ACTIVE_ANON); | ||
1162 | |||
1163 | return ret; | ||
1164 | } | ||
1165 | |||
1166 | static unsigned long mem_cgroup_nr_anon_lru_pages(struct mem_cgroup *memcg) | 1170 | static unsigned long mem_cgroup_nr_anon_lru_pages(struct mem_cgroup *memcg) |
1167 | { | 1171 | { |
1168 | u64 total = 0; | 1172 | u64 total = 0; |
@@ -1559,6 +1563,28 @@ mem_cgroup_select_victim(struct mem_cgroup *root_mem) | |||
1559 | return ret; | 1563 | return ret; |
1560 | } | 1564 | } |
1561 | 1565 | ||
1566 | /** | ||
1567 | * test_mem_cgroup_node_reclaimable | ||
1568 | * @mem: the target memcg | ||
1569 | * @nid: the node ID to be checked. | ||
1570 | * @noswap : specify true here if the user wants flle only information. | ||
1571 | * | ||
1572 | * This function returns whether the specified memcg contains any | ||
1573 | * reclaimable pages on a node. Returns true if there are any reclaimable | ||
1574 | * pages in the node. | ||
1575 | */ | ||
1576 | static bool test_mem_cgroup_node_reclaimable(struct mem_cgroup *mem, | ||
1577 | int nid, bool noswap) | ||
1578 | { | ||
1579 | if (mem_cgroup_node_nr_file_lru_pages(mem, nid)) | ||
1580 | return true; | ||
1581 | if (noswap || !total_swap_pages) | ||
1582 | return false; | ||
1583 | if (mem_cgroup_node_nr_anon_lru_pages(mem, nid)) | ||
1584 | return true; | ||
1585 | return false; | ||
1586 | |||
1587 | } | ||
1562 | #if MAX_NUMNODES > 1 | 1588 | #if MAX_NUMNODES > 1 |
1563 | 1589 | ||
1564 | /* | 1590 | /* |
@@ -1570,26 +1596,26 @@ mem_cgroup_select_victim(struct mem_cgroup *root_mem) | |||
1570 | static void mem_cgroup_may_update_nodemask(struct mem_cgroup *mem) | 1596 | static void mem_cgroup_may_update_nodemask(struct mem_cgroup *mem) |
1571 | { | 1597 | { |
1572 | int nid; | 1598 | int nid; |
1573 | 1599 | /* | |
1574 | if (time_after(mem->next_scan_node_update, jiffies)) | 1600 | * numainfo_events > 0 means there was at least NUMAINFO_EVENTS_TARGET |
1601 | * pagein/pageout changes since the last update. | ||
1602 | */ | ||
1603 | if (!atomic_read(&mem->numainfo_events)) | ||
1604 | return; | ||
1605 | if (atomic_inc_return(&mem->numainfo_updating) > 1) | ||
1575 | return; | 1606 | return; |
1576 | 1607 | ||
1577 | mem->next_scan_node_update = jiffies + 10*HZ; | ||
1578 | /* make a nodemask where this memcg uses memory from */ | 1608 | /* make a nodemask where this memcg uses memory from */ |
1579 | mem->scan_nodes = node_states[N_HIGH_MEMORY]; | 1609 | mem->scan_nodes = node_states[N_HIGH_MEMORY]; |
1580 | 1610 | ||
1581 | for_each_node_mask(nid, node_states[N_HIGH_MEMORY]) { | 1611 | for_each_node_mask(nid, node_states[N_HIGH_MEMORY]) { |
1582 | 1612 | ||
1583 | if (mem_cgroup_get_zonestat_node(mem, nid, LRU_INACTIVE_FILE) || | 1613 | if (!test_mem_cgroup_node_reclaimable(mem, nid, false)) |
1584 | mem_cgroup_get_zonestat_node(mem, nid, LRU_ACTIVE_FILE)) | 1614 | node_clear(nid, mem->scan_nodes); |
1585 | continue; | ||
1586 | |||
1587 | if (total_swap_pages && | ||
1588 | (mem_cgroup_get_zonestat_node(mem, nid, LRU_INACTIVE_ANON) || | ||
1589 | mem_cgroup_get_zonestat_node(mem, nid, LRU_ACTIVE_ANON))) | ||
1590 | continue; | ||
1591 | node_clear(nid, mem->scan_nodes); | ||
1592 | } | 1615 | } |
1616 | |||
1617 | atomic_set(&mem->numainfo_events, 0); | ||
1618 | atomic_set(&mem->numainfo_updating, 0); | ||
1593 | } | 1619 | } |
1594 | 1620 | ||
1595 | /* | 1621 | /* |
@@ -1627,11 +1653,51 @@ int mem_cgroup_select_victim_node(struct mem_cgroup *mem) | |||
1627 | return node; | 1653 | return node; |
1628 | } | 1654 | } |
1629 | 1655 | ||
1656 | /* | ||
1657 | * Check all nodes whether it contains reclaimable pages or not. | ||
1658 | * For quick scan, we make use of scan_nodes. This will allow us to skip | ||
1659 | * unused nodes. But scan_nodes is lazily updated and may not cotain | ||
1660 | * enough new information. We need to do double check. | ||
1661 | */ | ||
1662 | bool mem_cgroup_reclaimable(struct mem_cgroup *mem, bool noswap) | ||
1663 | { | ||
1664 | int nid; | ||
1665 | |||
1666 | /* | ||
1667 | * quick check...making use of scan_node. | ||
1668 | * We can skip unused nodes. | ||
1669 | */ | ||
1670 | if (!nodes_empty(mem->scan_nodes)) { | ||
1671 | for (nid = first_node(mem->scan_nodes); | ||
1672 | nid < MAX_NUMNODES; | ||
1673 | nid = next_node(nid, mem->scan_nodes)) { | ||
1674 | |||
1675 | if (test_mem_cgroup_node_reclaimable(mem, nid, noswap)) | ||
1676 | return true; | ||
1677 | } | ||
1678 | } | ||
1679 | /* | ||
1680 | * Check rest of nodes. | ||
1681 | */ | ||
1682 | for_each_node_state(nid, N_HIGH_MEMORY) { | ||
1683 | if (node_isset(nid, mem->scan_nodes)) | ||
1684 | continue; | ||
1685 | if (test_mem_cgroup_node_reclaimable(mem, nid, noswap)) | ||
1686 | return true; | ||
1687 | } | ||
1688 | return false; | ||
1689 | } | ||
1690 | |||
1630 | #else | 1691 | #else |
1631 | int mem_cgroup_select_victim_node(struct mem_cgroup *mem) | 1692 | int mem_cgroup_select_victim_node(struct mem_cgroup *mem) |
1632 | { | 1693 | { |
1633 | return 0; | 1694 | return 0; |
1634 | } | 1695 | } |
1696 | |||
1697 | bool mem_cgroup_reclaimable(struct mem_cgroup *mem, bool noswap) | ||
1698 | { | ||
1699 | return test_mem_cgroup_node_reclaimable(mem, 0, noswap); | ||
1700 | } | ||
1635 | #endif | 1701 | #endif |
1636 | 1702 | ||
1637 | /* | 1703 | /* |
@@ -1702,7 +1768,7 @@ static int mem_cgroup_hierarchical_reclaim(struct mem_cgroup *root_mem, | |||
1702 | } | 1768 | } |
1703 | } | 1769 | } |
1704 | } | 1770 | } |
1705 | if (!mem_cgroup_local_usage(victim)) { | 1771 | if (!mem_cgroup_reclaimable(victim, noswap)) { |
1706 | /* this cgroup's local usage == 0 */ | 1772 | /* this cgroup's local usage == 0 */ |
1707 | css_put(&victim->css); | 1773 | css_put(&victim->css); |
1708 | continue; | 1774 | continue; |
diff --git a/mm/memory.c b/mm/memory.c index 40b7531ee8ba..9b8a01d941cb 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -305,6 +305,7 @@ int __tlb_remove_page(struct mmu_gather *tlb, struct page *page) | |||
305 | if (batch->nr == batch->max) { | 305 | if (batch->nr == batch->max) { |
306 | if (!tlb_next_batch(tlb)) | 306 | if (!tlb_next_batch(tlb)) |
307 | return 0; | 307 | return 0; |
308 | batch = tlb->active; | ||
308 | } | 309 | } |
309 | VM_BUG_ON(batch->nr > batch->max); | 310 | VM_BUG_ON(batch->nr > batch->max); |
310 | 311 | ||
diff --git a/mm/nommu.c b/mm/nommu.c index 1fd0c51b10a6..9edc897a3970 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
@@ -1813,10 +1813,13 @@ struct page *follow_page(struct vm_area_struct *vma, unsigned long address, | |||
1813 | return NULL; | 1813 | return NULL; |
1814 | } | 1814 | } |
1815 | 1815 | ||
1816 | int remap_pfn_range(struct vm_area_struct *vma, unsigned long from, | 1816 | int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, |
1817 | unsigned long to, unsigned long size, pgprot_t prot) | 1817 | unsigned long pfn, unsigned long size, pgprot_t prot) |
1818 | { | 1818 | { |
1819 | vma->vm_start = vma->vm_pgoff << PAGE_SHIFT; | 1819 | if (addr != (pfn << PAGE_SHIFT)) |
1820 | return -EINVAL; | ||
1821 | |||
1822 | vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP; | ||
1820 | return 0; | 1823 | return 0; |
1821 | } | 1824 | } |
1822 | EXPORT_SYMBOL(remap_pfn_range); | 1825 | EXPORT_SYMBOL(remap_pfn_range); |
diff --git a/mm/vmscan.c b/mm/vmscan.c index 4f49535d4cd3..d036e59d302b 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -2310,7 +2310,8 @@ static bool pgdat_balanced(pg_data_t *pgdat, unsigned long balanced_pages, | |||
2310 | for (i = 0; i <= classzone_idx; i++) | 2310 | for (i = 0; i <= classzone_idx; i++) |
2311 | present_pages += pgdat->node_zones[i].present_pages; | 2311 | present_pages += pgdat->node_zones[i].present_pages; |
2312 | 2312 | ||
2313 | return balanced_pages > (present_pages >> 2); | 2313 | /* A special case here: if zone has no page, we think it's balanced */ |
2314 | return balanced_pages >= (present_pages >> 2); | ||
2314 | } | 2315 | } |
2315 | 2316 | ||
2316 | /* is kswapd sleeping prematurely? */ | 2317 | /* is kswapd sleeping prematurely? */ |
@@ -2326,7 +2327,7 @@ static bool sleeping_prematurely(pg_data_t *pgdat, int order, long remaining, | |||
2326 | return true; | 2327 | return true; |
2327 | 2328 | ||
2328 | /* Check the watermark levels */ | 2329 | /* Check the watermark levels */ |
2329 | for (i = 0; i < pgdat->nr_zones; i++) { | 2330 | for (i = 0; i <= classzone_idx; i++) { |
2330 | struct zone *zone = pgdat->node_zones + i; | 2331 | struct zone *zone = pgdat->node_zones + i; |
2331 | 2332 | ||
2332 | if (!populated_zone(zone)) | 2333 | if (!populated_zone(zone)) |
@@ -2344,7 +2345,7 @@ static bool sleeping_prematurely(pg_data_t *pgdat, int order, long remaining, | |||
2344 | } | 2345 | } |
2345 | 2346 | ||
2346 | if (!zone_watermark_ok_safe(zone, order, high_wmark_pages(zone), | 2347 | if (!zone_watermark_ok_safe(zone, order, high_wmark_pages(zone), |
2347 | classzone_idx, 0)) | 2348 | i, 0)) |
2348 | all_zones_ok = false; | 2349 | all_zones_ok = false; |
2349 | else | 2350 | else |
2350 | balanced += zone->present_pages; | 2351 | balanced += zone->present_pages; |
@@ -2451,7 +2452,6 @@ loop_again: | |||
2451 | if (!zone_watermark_ok_safe(zone, order, | 2452 | if (!zone_watermark_ok_safe(zone, order, |
2452 | high_wmark_pages(zone), 0, 0)) { | 2453 | high_wmark_pages(zone), 0, 0)) { |
2453 | end_zone = i; | 2454 | end_zone = i; |
2454 | *classzone_idx = i; | ||
2455 | break; | 2455 | break; |
2456 | } | 2456 | } |
2457 | } | 2457 | } |
@@ -2510,18 +2510,18 @@ loop_again: | |||
2510 | KSWAPD_ZONE_BALANCE_GAP_RATIO); | 2510 | KSWAPD_ZONE_BALANCE_GAP_RATIO); |
2511 | if (!zone_watermark_ok_safe(zone, order, | 2511 | if (!zone_watermark_ok_safe(zone, order, |
2512 | high_wmark_pages(zone) + balance_gap, | 2512 | high_wmark_pages(zone) + balance_gap, |
2513 | end_zone, 0)) | 2513 | end_zone, 0)) { |
2514 | shrink_zone(priority, zone, &sc); | 2514 | shrink_zone(priority, zone, &sc); |
2515 | reclaim_state->reclaimed_slab = 0; | ||
2516 | nr_slab = shrink_slab(&shrink, sc.nr_scanned, lru_pages); | ||
2517 | sc.nr_reclaimed += reclaim_state->reclaimed_slab; | ||
2518 | total_scanned += sc.nr_scanned; | ||
2519 | 2515 | ||
2520 | if (zone->all_unreclaimable) | 2516 | reclaim_state->reclaimed_slab = 0; |
2521 | continue; | 2517 | nr_slab = shrink_slab(&shrink, sc.nr_scanned, lru_pages); |
2522 | if (nr_slab == 0 && | 2518 | sc.nr_reclaimed += reclaim_state->reclaimed_slab; |
2523 | !zone_reclaimable(zone)) | 2519 | total_scanned += sc.nr_scanned; |
2524 | zone->all_unreclaimable = 1; | 2520 | |
2521 | if (nr_slab == 0 && !zone_reclaimable(zone)) | ||
2522 | zone->all_unreclaimable = 1; | ||
2523 | } | ||
2524 | |||
2525 | /* | 2525 | /* |
2526 | * If we've done a decent amount of scanning and | 2526 | * If we've done a decent amount of scanning and |
2527 | * the reclaim ratio is low, start doing writepage | 2527 | * the reclaim ratio is low, start doing writepage |
@@ -2531,6 +2531,12 @@ loop_again: | |||
2531 | total_scanned > sc.nr_reclaimed + sc.nr_reclaimed / 2) | 2531 | total_scanned > sc.nr_reclaimed + sc.nr_reclaimed / 2) |
2532 | sc.may_writepage = 1; | 2532 | sc.may_writepage = 1; |
2533 | 2533 | ||
2534 | if (zone->all_unreclaimable) { | ||
2535 | if (end_zone && end_zone == i) | ||
2536 | end_zone--; | ||
2537 | continue; | ||
2538 | } | ||
2539 | |||
2534 | if (!zone_watermark_ok_safe(zone, order, | 2540 | if (!zone_watermark_ok_safe(zone, order, |
2535 | high_wmark_pages(zone), end_zone, 0)) { | 2541 | high_wmark_pages(zone), end_zone, 0)) { |
2536 | all_zones_ok = 0; | 2542 | all_zones_ok = 0; |
@@ -2709,8 +2715,8 @@ static void kswapd_try_to_sleep(pg_data_t *pgdat, int order, int classzone_idx) | |||
2709 | */ | 2715 | */ |
2710 | static int kswapd(void *p) | 2716 | static int kswapd(void *p) |
2711 | { | 2717 | { |
2712 | unsigned long order; | 2718 | unsigned long order, new_order; |
2713 | int classzone_idx; | 2719 | int classzone_idx, new_classzone_idx; |
2714 | pg_data_t *pgdat = (pg_data_t*)p; | 2720 | pg_data_t *pgdat = (pg_data_t*)p; |
2715 | struct task_struct *tsk = current; | 2721 | struct task_struct *tsk = current; |
2716 | 2722 | ||
@@ -2740,17 +2746,23 @@ static int kswapd(void *p) | |||
2740 | tsk->flags |= PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD; | 2746 | tsk->flags |= PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD; |
2741 | set_freezable(); | 2747 | set_freezable(); |
2742 | 2748 | ||
2743 | order = 0; | 2749 | order = new_order = 0; |
2744 | classzone_idx = MAX_NR_ZONES - 1; | 2750 | classzone_idx = new_classzone_idx = pgdat->nr_zones - 1; |
2745 | for ( ; ; ) { | 2751 | for ( ; ; ) { |
2746 | unsigned long new_order; | ||
2747 | int new_classzone_idx; | ||
2748 | int ret; | 2752 | int ret; |
2749 | 2753 | ||
2750 | new_order = pgdat->kswapd_max_order; | 2754 | /* |
2751 | new_classzone_idx = pgdat->classzone_idx; | 2755 | * If the last balance_pgdat was unsuccessful it's unlikely a |
2752 | pgdat->kswapd_max_order = 0; | 2756 | * new request of a similar or harder type will succeed soon |
2753 | pgdat->classzone_idx = MAX_NR_ZONES - 1; | 2757 | * so consider going to sleep on the basis we reclaimed at |
2758 | */ | ||
2759 | if (classzone_idx >= new_classzone_idx && order == new_order) { | ||
2760 | new_order = pgdat->kswapd_max_order; | ||
2761 | new_classzone_idx = pgdat->classzone_idx; | ||
2762 | pgdat->kswapd_max_order = 0; | ||
2763 | pgdat->classzone_idx = pgdat->nr_zones - 1; | ||
2764 | } | ||
2765 | |||
2754 | if (order < new_order || classzone_idx > new_classzone_idx) { | 2766 | if (order < new_order || classzone_idx > new_classzone_idx) { |
2755 | /* | 2767 | /* |
2756 | * Don't sleep if someone wants a larger 'order' | 2768 | * Don't sleep if someone wants a larger 'order' |
@@ -2763,7 +2775,7 @@ static int kswapd(void *p) | |||
2763 | order = pgdat->kswapd_max_order; | 2775 | order = pgdat->kswapd_max_order; |
2764 | classzone_idx = pgdat->classzone_idx; | 2776 | classzone_idx = pgdat->classzone_idx; |
2765 | pgdat->kswapd_max_order = 0; | 2777 | pgdat->kswapd_max_order = 0; |
2766 | pgdat->classzone_idx = MAX_NR_ZONES - 1; | 2778 | pgdat->classzone_idx = pgdat->nr_zones - 1; |
2767 | } | 2779 | } |
2768 | 2780 | ||
2769 | ret = try_to_freeze(); | 2781 | ret = try_to_freeze(); |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 7ea5cf9ea08a..6e82148edfc8 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -528,7 +528,11 @@ static int vlan_dev_init(struct net_device *dev) | |||
528 | (1<<__LINK_STATE_DORMANT))) | | 528 | (1<<__LINK_STATE_DORMANT))) | |
529 | (1<<__LINK_STATE_PRESENT); | 529 | (1<<__LINK_STATE_PRESENT); |
530 | 530 | ||
531 | dev->hw_features = NETIF_F_ALL_TX_OFFLOADS; | 531 | dev->hw_features = NETIF_F_ALL_CSUM | NETIF_F_SG | |
532 | NETIF_F_FRAGLIST | NETIF_F_ALL_TSO | | ||
533 | NETIF_F_HIGHDMA | NETIF_F_SCTP_CSUM | | ||
534 | NETIF_F_ALL_FCOE; | ||
535 | |||
532 | dev->features |= real_dev->vlan_features | NETIF_F_LLTX; | 536 | dev->features |= real_dev->vlan_features | NETIF_F_LLTX; |
533 | dev->gso_max_size = real_dev->gso_max_size; | 537 | dev->gso_max_size = real_dev->gso_max_size; |
534 | 538 | ||
@@ -586,9 +590,14 @@ static void vlan_dev_uninit(struct net_device *dev) | |||
586 | static u32 vlan_dev_fix_features(struct net_device *dev, u32 features) | 590 | static u32 vlan_dev_fix_features(struct net_device *dev, u32 features) |
587 | { | 591 | { |
588 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; | 592 | struct net_device *real_dev = vlan_dev_info(dev)->real_dev; |
593 | u32 old_features = features; | ||
589 | 594 | ||
590 | features &= real_dev->features; | 595 | features &= real_dev->features; |
591 | features &= real_dev->vlan_features; | 596 | features &= real_dev->vlan_features; |
597 | |||
598 | if (old_features & NETIF_F_SOFT_FEATURES) | ||
599 | features |= old_features & NETIF_F_SOFT_FEATURES; | ||
600 | |||
592 | if (dev_ethtool_get_rx_csum(real_dev)) | 601 | if (dev_ethtool_get_rx_csum(real_dev)) |
593 | features |= NETIF_F_RXCSUM; | 602 | features |= NETIF_F_RXCSUM; |
594 | features |= NETIF_F_LLTX; | 603 | features |= NETIF_F_LLTX; |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index d3a05b9ade7a..bcd158f40bb9 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -393,6 +393,9 @@ int hci_conn_del(struct hci_conn *conn) | |||
393 | 393 | ||
394 | hci_dev_put(hdev); | 394 | hci_dev_put(hdev); |
395 | 395 | ||
396 | if (conn->handle == 0) | ||
397 | kfree(conn); | ||
398 | |||
396 | return 0; | 399 | return 0; |
397 | } | 400 | } |
398 | 401 | ||
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index c405a954a603..43b4c2deb7cc 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -464,7 +464,8 @@ static void hidp_idle_timeout(unsigned long arg) | |||
464 | { | 464 | { |
465 | struct hidp_session *session = (struct hidp_session *) arg; | 465 | struct hidp_session *session = (struct hidp_session *) arg; |
466 | 466 | ||
467 | kthread_stop(session->task); | 467 | atomic_inc(&session->terminate); |
468 | wake_up_process(session->task); | ||
468 | } | 469 | } |
469 | 470 | ||
470 | static void hidp_set_timer(struct hidp_session *session) | 471 | static void hidp_set_timer(struct hidp_session *session) |
@@ -535,7 +536,8 @@ static void hidp_process_hid_control(struct hidp_session *session, | |||
535 | skb_queue_purge(&session->ctrl_transmit); | 536 | skb_queue_purge(&session->ctrl_transmit); |
536 | skb_queue_purge(&session->intr_transmit); | 537 | skb_queue_purge(&session->intr_transmit); |
537 | 538 | ||
538 | kthread_stop(session->task); | 539 | atomic_inc(&session->terminate); |
540 | wake_up_process(current); | ||
539 | } | 541 | } |
540 | } | 542 | } |
541 | 543 | ||
@@ -706,9 +708,8 @@ static int hidp_session(void *arg) | |||
706 | add_wait_queue(sk_sleep(intr_sk), &intr_wait); | 708 | add_wait_queue(sk_sleep(intr_sk), &intr_wait); |
707 | session->waiting_for_startup = 0; | 709 | session->waiting_for_startup = 0; |
708 | wake_up_interruptible(&session->startup_queue); | 710 | wake_up_interruptible(&session->startup_queue); |
709 | while (!kthread_should_stop()) { | 711 | set_current_state(TASK_INTERRUPTIBLE); |
710 | set_current_state(TASK_INTERRUPTIBLE); | 712 | while (!atomic_read(&session->terminate)) { |
711 | |||
712 | if (ctrl_sk->sk_state != BT_CONNECTED || | 713 | if (ctrl_sk->sk_state != BT_CONNECTED || |
713 | intr_sk->sk_state != BT_CONNECTED) | 714 | intr_sk->sk_state != BT_CONNECTED) |
714 | break; | 715 | break; |
@@ -726,6 +727,7 @@ static int hidp_session(void *arg) | |||
726 | hidp_process_transmit(session); | 727 | hidp_process_transmit(session); |
727 | 728 | ||
728 | schedule(); | 729 | schedule(); |
730 | set_current_state(TASK_INTERRUPTIBLE); | ||
729 | } | 731 | } |
730 | set_current_state(TASK_RUNNING); | 732 | set_current_state(TASK_RUNNING); |
731 | remove_wait_queue(sk_sleep(intr_sk), &intr_wait); | 733 | remove_wait_queue(sk_sleep(intr_sk), &intr_wait); |
@@ -1060,7 +1062,8 @@ int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, | |||
1060 | err_add_device: | 1062 | err_add_device: |
1061 | hid_destroy_device(session->hid); | 1063 | hid_destroy_device(session->hid); |
1062 | session->hid = NULL; | 1064 | session->hid = NULL; |
1063 | kthread_stop(session->task); | 1065 | atomic_inc(&session->terminate); |
1066 | wake_up_process(session->task); | ||
1064 | 1067 | ||
1065 | unlink: | 1068 | unlink: |
1066 | hidp_del_timer(session); | 1069 | hidp_del_timer(session); |
@@ -1111,7 +1114,8 @@ int hidp_del_connection(struct hidp_conndel_req *req) | |||
1111 | skb_queue_purge(&session->ctrl_transmit); | 1114 | skb_queue_purge(&session->ctrl_transmit); |
1112 | skb_queue_purge(&session->intr_transmit); | 1115 | skb_queue_purge(&session->intr_transmit); |
1113 | 1116 | ||
1114 | kthread_stop(session->task); | 1117 | atomic_inc(&session->terminate); |
1118 | wake_up_process(session->task); | ||
1115 | } | 1119 | } |
1116 | } else | 1120 | } else |
1117 | err = -ENOENT; | 1121 | err = -ENOENT; |
diff --git a/net/bluetooth/hidp/hidp.h b/net/bluetooth/hidp/hidp.h index 19e95004b286..af1bcc823f26 100644 --- a/net/bluetooth/hidp/hidp.h +++ b/net/bluetooth/hidp/hidp.h | |||
@@ -142,6 +142,7 @@ struct hidp_session { | |||
142 | uint ctrl_mtu; | 142 | uint ctrl_mtu; |
143 | uint intr_mtu; | 143 | uint intr_mtu; |
144 | 144 | ||
145 | atomic_t terminate; | ||
145 | struct task_struct *task; | 146 | struct task_struct *task; |
146 | 147 | ||
147 | unsigned char keys[8]; | 148 | unsigned char keys[8]; |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 56fdd9162da9..7705e26e699f 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -620,7 +620,8 @@ static void l2cap_conn_start(struct l2cap_conn *conn) | |||
620 | struct sock *parent = bt_sk(sk)->parent; | 620 | struct sock *parent = bt_sk(sk)->parent; |
621 | rsp.result = cpu_to_le16(L2CAP_CR_PEND); | 621 | rsp.result = cpu_to_le16(L2CAP_CR_PEND); |
622 | rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND); | 622 | rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND); |
623 | parent->sk_data_ready(parent, 0); | 623 | if (parent) |
624 | parent->sk_data_ready(parent, 0); | ||
624 | 625 | ||
625 | } else { | 626 | } else { |
626 | sk->sk_state = BT_CONFIG; | 627 | sk->sk_state = BT_CONFIG; |
@@ -2323,7 +2324,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2323 | 2324 | ||
2324 | sk = chan->sk; | 2325 | sk = chan->sk; |
2325 | 2326 | ||
2326 | if (sk->sk_state != BT_CONFIG) { | 2327 | if (sk->sk_state != BT_CONFIG && sk->sk_state != BT_CONNECT2) { |
2327 | struct l2cap_cmd_rej rej; | 2328 | struct l2cap_cmd_rej rej; |
2328 | 2329 | ||
2329 | rej.reason = cpu_to_le16(0x0002); | 2330 | rej.reason = cpu_to_le16(0x0002); |
@@ -2334,7 +2335,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, struct l2cap_cmd_hdr | |||
2334 | 2335 | ||
2335 | /* Reject if config buffer is too small. */ | 2336 | /* Reject if config buffer is too small. */ |
2336 | len = cmd_len - sizeof(*req); | 2337 | len = cmd_len - sizeof(*req); |
2337 | if (chan->conf_len + len > sizeof(chan->conf_req)) { | 2338 | if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) { |
2338 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, | 2339 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, |
2339 | l2cap_build_conf_rsp(chan, rsp, | 2340 | l2cap_build_conf_rsp(chan, rsp, |
2340 | L2CAP_CONF_REJECT, flags), rsp); | 2341 | L2CAP_CONF_REJECT, flags), rsp); |
@@ -4009,7 +4010,8 @@ static int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
4009 | struct sock *parent = bt_sk(sk)->parent; | 4010 | struct sock *parent = bt_sk(sk)->parent; |
4010 | res = L2CAP_CR_PEND; | 4011 | res = L2CAP_CR_PEND; |
4011 | stat = L2CAP_CS_AUTHOR_PEND; | 4012 | stat = L2CAP_CS_AUTHOR_PEND; |
4012 | parent->sk_data_ready(parent, 0); | 4013 | if (parent) |
4014 | parent->sk_data_ready(parent, 0); | ||
4013 | } else { | 4015 | } else { |
4014 | sk->sk_state = BT_CONFIG; | 4016 | sk->sk_state = BT_CONFIG; |
4015 | res = L2CAP_CR_SUCCESS; | 4017 | res = L2CAP_CR_SUCCESS; |
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index c188c803c09c..32b8f9f7f79e 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c | |||
@@ -49,7 +49,9 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) | |||
49 | skb_pull(skb, ETH_HLEN); | 49 | skb_pull(skb, ETH_HLEN); |
50 | 50 | ||
51 | rcu_read_lock(); | 51 | rcu_read_lock(); |
52 | if (is_multicast_ether_addr(dest)) { | 52 | if (is_broadcast_ether_addr(dest)) |
53 | br_flood_deliver(br, skb); | ||
54 | else if (is_multicast_ether_addr(dest)) { | ||
53 | if (unlikely(netpoll_tx_running(dev))) { | 55 | if (unlikely(netpoll_tx_running(dev))) { |
54 | br_flood_deliver(br, skb); | 56 | br_flood_deliver(br, skb); |
55 | goto out; | 57 | goto out; |
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index f3ac1e858ee1..f06ee39c73fd 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
@@ -60,7 +60,7 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
60 | br = p->br; | 60 | br = p->br; |
61 | br_fdb_update(br, p, eth_hdr(skb)->h_source); | 61 | br_fdb_update(br, p, eth_hdr(skb)->h_source); |
62 | 62 | ||
63 | if (is_multicast_ether_addr(dest) && | 63 | if (!is_broadcast_ether_addr(dest) && is_multicast_ether_addr(dest) && |
64 | br_multicast_rcv(br, p, skb)) | 64 | br_multicast_rcv(br, p, skb)) |
65 | goto drop; | 65 | goto drop; |
66 | 66 | ||
@@ -77,7 +77,9 @@ int br_handle_frame_finish(struct sk_buff *skb) | |||
77 | 77 | ||
78 | dst = NULL; | 78 | dst = NULL; |
79 | 79 | ||
80 | if (is_multicast_ether_addr(dest)) { | 80 | if (is_broadcast_ether_addr(dest)) |
81 | skb2 = skb; | ||
82 | else if (is_multicast_ether_addr(dest)) { | ||
81 | mdst = br_mdb_get(br, skb); | 83 | mdst = br_mdb_get(br, skb); |
82 | if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) { | 84 | if (mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) { |
83 | if ((mdst && mdst->mglist) || | 85 | if ((mdst && mdst->mglist) || |
diff --git a/net/ceph/ceph_fs.c b/net/ceph/ceph_fs.c index a3a3a31d3c37..41466ccb972a 100644 --- a/net/ceph/ceph_fs.c +++ b/net/ceph/ceph_fs.c | |||
@@ -36,16 +36,19 @@ int ceph_flags_to_mode(int flags) | |||
36 | if ((flags & O_DIRECTORY) == O_DIRECTORY) | 36 | if ((flags & O_DIRECTORY) == O_DIRECTORY) |
37 | return CEPH_FILE_MODE_PIN; | 37 | return CEPH_FILE_MODE_PIN; |
38 | #endif | 38 | #endif |
39 | if ((flags & O_APPEND) == O_APPEND) | ||
40 | flags |= O_WRONLY; | ||
41 | 39 | ||
42 | if ((flags & O_ACCMODE) == O_RDWR) | 40 | switch (flags & O_ACCMODE) { |
43 | mode = CEPH_FILE_MODE_RDWR; | 41 | case O_WRONLY: |
44 | else if ((flags & O_ACCMODE) == O_WRONLY) | ||
45 | mode = CEPH_FILE_MODE_WR; | 42 | mode = CEPH_FILE_MODE_WR; |
46 | else | 43 | break; |
44 | case O_RDONLY: | ||
47 | mode = CEPH_FILE_MODE_RD; | 45 | mode = CEPH_FILE_MODE_RD; |
48 | 46 | break; | |
47 | case O_RDWR: | ||
48 | case O_ACCMODE: /* this is what the VFS does */ | ||
49 | mode = CEPH_FILE_MODE_RDWR; | ||
50 | break; | ||
51 | } | ||
49 | #ifdef O_LAZY | 52 | #ifdef O_LAZY |
50 | if (flags & O_LAZY) | 53 | if (flags & O_LAZY) |
51 | mode |= CEPH_FILE_MODE_LAZY; | 54 | mode |= CEPH_FILE_MODE_LAZY; |
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index 9cb627a4073a..7330c2757c0c 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c | |||
@@ -477,8 +477,9 @@ struct ceph_osd_request *ceph_osdc_new_request(struct ceph_osd_client *osdc, | |||
477 | calc_layout(osdc, vino, layout, off, plen, req, ops); | 477 | calc_layout(osdc, vino, layout, off, plen, req, ops); |
478 | req->r_file_layout = *layout; /* keep a copy */ | 478 | req->r_file_layout = *layout; /* keep a copy */ |
479 | 479 | ||
480 | /* in case it differs from natural alignment that calc_layout | 480 | /* in case it differs from natural (file) alignment that |
481 | filled in for us */ | 481 | calc_layout filled in for us */ |
482 | req->r_num_pages = calc_pages_for(page_align, *plen); | ||
482 | req->r_page_alignment = page_align; | 483 | req->r_page_alignment = page_align; |
483 | 484 | ||
484 | ceph_osdc_build_request(req, off, plen, ops, | 485 | ceph_osdc_build_request(req, off, plen, ops, |
@@ -2027,8 +2028,9 @@ static struct ceph_msg *get_reply(struct ceph_connection *con, | |||
2027 | int want = calc_pages_for(req->r_page_alignment, data_len); | 2028 | int want = calc_pages_for(req->r_page_alignment, data_len); |
2028 | 2029 | ||
2029 | if (unlikely(req->r_num_pages < want)) { | 2030 | if (unlikely(req->r_num_pages < want)) { |
2030 | pr_warning("tid %lld reply %d > expected %d pages\n", | 2031 | pr_warning("tid %lld reply has %d bytes %d pages, we" |
2031 | tid, want, m->nr_pages); | 2032 | " had only %d pages ready\n", tid, data_len, |
2033 | want, req->r_num_pages); | ||
2032 | *skip = 1; | 2034 | *skip = 1; |
2033 | ceph_msg_put(m); | 2035 | ceph_msg_put(m); |
2034 | m = NULL; | 2036 | m = NULL; |
diff --git a/net/core/dst.c b/net/core/dst.c index 9ccca038444f..6135f3671692 100644 --- a/net/core/dst.c +++ b/net/core/dst.c | |||
@@ -190,7 +190,8 @@ void *dst_alloc(struct dst_ops *ops, struct net_device *dev, | |||
190 | dst->lastuse = jiffies; | 190 | dst->lastuse = jiffies; |
191 | dst->flags = flags; | 191 | dst->flags = flags; |
192 | dst->next = NULL; | 192 | dst->next = NULL; |
193 | dst_entries_add(ops, 1); | 193 | if (!(flags & DST_NOCOUNT)) |
194 | dst_entries_add(ops, 1); | ||
194 | return dst; | 195 | return dst; |
195 | } | 196 | } |
196 | EXPORT_SYMBOL(dst_alloc); | 197 | EXPORT_SYMBOL(dst_alloc); |
@@ -243,7 +244,8 @@ again: | |||
243 | neigh_release(neigh); | 244 | neigh_release(neigh); |
244 | } | 245 | } |
245 | 246 | ||
246 | dst_entries_add(dst->ops, -1); | 247 | if (!(dst->flags & DST_NOCOUNT)) |
248 | dst_entries_add(dst->ops, -1); | ||
247 | 249 | ||
248 | if (dst->ops->destroy) | 250 | if (dst->ops->destroy) |
249 | dst->ops->destroy(dst); | 251 | dst->ops->destroy(dst); |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index eae1f676f870..ef1528af7abf 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -465,8 +465,10 @@ int inet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
465 | if (addr_len < sizeof(struct sockaddr_in)) | 465 | if (addr_len < sizeof(struct sockaddr_in)) |
466 | goto out; | 466 | goto out; |
467 | 467 | ||
468 | if (addr->sin_family != AF_INET) | 468 | if (addr->sin_family != AF_INET) { |
469 | err = -EAFNOSUPPORT; | ||
469 | goto out; | 470 | goto out; |
471 | } | ||
470 | 472 | ||
471 | chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr); | 473 | chk_addr_ret = inet_addr_type(sock_net(sk), addr->sin_addr.s_addr); |
472 | 474 | ||
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 4a7e16b5d3f3..84f26e8e6c60 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -828,7 +828,7 @@ static int __ip_append_data(struct sock *sk, | |||
828 | cork->length += length; | 828 | cork->length += length; |
829 | if (((length > mtu) || (skb && skb_is_gso(skb))) && | 829 | if (((length > mtu) || (skb && skb_is_gso(skb))) && |
830 | (sk->sk_protocol == IPPROTO_UDP) && | 830 | (sk->sk_protocol == IPPROTO_UDP) && |
831 | (rt->dst.dev->features & NETIF_F_UFO)) { | 831 | (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len) { |
832 | err = ip_ufo_append_data(sk, queue, getfrag, from, length, | 832 | err = ip_ufo_append_data(sk, queue, getfrag, from, length, |
833 | hh_len, fragheaderlen, transhdrlen, | 833 | hh_len, fragheaderlen, transhdrlen, |
834 | mtu, flags); | 834 | mtu, flags); |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 054a59d21eb0..46febcacb729 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -3220,7 +3220,7 @@ __setup("thash_entries=", set_thash_entries); | |||
3220 | void __init tcp_init(void) | 3220 | void __init tcp_init(void) |
3221 | { | 3221 | { |
3222 | struct sk_buff *skb = NULL; | 3222 | struct sk_buff *skb = NULL; |
3223 | unsigned long nr_pages, limit; | 3223 | unsigned long limit; |
3224 | int i, max_share, cnt; | 3224 | int i, max_share, cnt; |
3225 | unsigned long jiffy = jiffies; | 3225 | unsigned long jiffy = jiffies; |
3226 | 3226 | ||
@@ -3277,13 +3277,7 @@ void __init tcp_init(void) | |||
3277 | sysctl_tcp_max_orphans = cnt / 2; | 3277 | sysctl_tcp_max_orphans = cnt / 2; |
3278 | sysctl_max_syn_backlog = max(128, cnt / 256); | 3278 | sysctl_max_syn_backlog = max(128, cnt / 256); |
3279 | 3279 | ||
3280 | /* Set the pressure threshold to be a fraction of global memory that | 3280 | limit = nr_free_buffer_pages() / 8; |
3281 | * is up to 1/2 at 256 MB, decreasing toward zero with the amount of | ||
3282 | * memory, with a floor of 128 pages. | ||
3283 | */ | ||
3284 | nr_pages = totalram_pages - totalhigh_pages; | ||
3285 | limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); | ||
3286 | limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); | ||
3287 | limit = max(limit, 128UL); | 3281 | limit = max(limit, 128UL); |
3288 | sysctl_tcp_mem[0] = limit / 4 * 3; | 3282 | sysctl_tcp_mem[0] = limit / 4 * 3; |
3289 | sysctl_tcp_mem[1] = limit; | 3283 | sysctl_tcp_mem[1] = limit; |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 48cd88e62553..198f75b7bdd3 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -2209,16 +2209,10 @@ void __init udp_table_init(struct udp_table *table, const char *name) | |||
2209 | 2209 | ||
2210 | void __init udp_init(void) | 2210 | void __init udp_init(void) |
2211 | { | 2211 | { |
2212 | unsigned long nr_pages, limit; | 2212 | unsigned long limit; |
2213 | 2213 | ||
2214 | udp_table_init(&udp_table, "UDP"); | 2214 | udp_table_init(&udp_table, "UDP"); |
2215 | /* Set the pressure threshold up by the same strategy of TCP. It is a | 2215 | limit = nr_free_buffer_pages() / 8; |
2216 | * fraction of global memory that is up to 1/2 at 256 MB, decreasing | ||
2217 | * toward zero with the amount of memory, with a floor of 128 pages. | ||
2218 | */ | ||
2219 | nr_pages = totalram_pages - totalhigh_pages; | ||
2220 | limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); | ||
2221 | limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); | ||
2222 | limit = max(limit, 128UL); | 2216 | limit = max(limit, 128UL); |
2223 | sysctl_udp_mem[0] = limit / 4 * 3; | 2217 | sysctl_udp_mem[0] = limit / 4 * 3; |
2224 | sysctl_udp_mem[1] = limit; | 2218 | sysctl_udp_mem[1] = limit; |
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index 2d51840e53a1..327a617d594c 100644 --- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c | |||
@@ -32,7 +32,12 @@ static int xfrm4_tunnel_check_size(struct sk_buff *skb) | |||
32 | dst = skb_dst(skb); | 32 | dst = skb_dst(skb); |
33 | mtu = dst_mtu(dst); | 33 | mtu = dst_mtu(dst); |
34 | if (skb->len > mtu) { | 34 | if (skb->len > mtu) { |
35 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, htonl(mtu)); | 35 | if (skb->sk) |
36 | ip_local_error(skb->sk, EMSGSIZE, ip_hdr(skb)->daddr, | ||
37 | inet_sk(skb->sk)->inet_dport, mtu); | ||
38 | else | ||
39 | icmp_send(skb, ICMP_DEST_UNREACH, | ||
40 | ICMP_FRAG_NEEDED, htonl(mtu)); | ||
36 | ret = -EMSGSIZE; | 41 | ret = -EMSGSIZE; |
37 | } | 42 | } |
38 | out: | 43 | out: |
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index d450a2f9fc06..3b5669a2582d 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -274,7 +274,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
274 | return -EINVAL; | 274 | return -EINVAL; |
275 | 275 | ||
276 | if (addr->sin6_family != AF_INET6) | 276 | if (addr->sin6_family != AF_INET6) |
277 | return -EINVAL; | 277 | return -EAFNOSUPPORT; |
278 | 278 | ||
279 | addr_type = ipv6_addr_type(&addr->sin6_addr); | 279 | addr_type = ipv6_addr_type(&addr->sin6_addr); |
280 | if ((addr_type & IPV6_ADDR_MULTICAST) && sock->type == SOCK_STREAM) | 280 | if ((addr_type & IPV6_ADDR_MULTICAST) && sock->type == SOCK_STREAM) |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index de2b1decd786..0ef1f086feb8 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -228,9 +228,10 @@ static struct rt6_info ip6_blk_hole_entry_template = { | |||
228 | 228 | ||
229 | /* allocate dst with ip6_dst_ops */ | 229 | /* allocate dst with ip6_dst_ops */ |
230 | static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops, | 230 | static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops, |
231 | struct net_device *dev) | 231 | struct net_device *dev, |
232 | int flags) | ||
232 | { | 233 | { |
233 | struct rt6_info *rt = dst_alloc(ops, dev, 0, 0, 0); | 234 | struct rt6_info *rt = dst_alloc(ops, dev, 0, 0, flags); |
234 | 235 | ||
235 | memset(&rt->rt6i_table, 0, sizeof(*rt) - sizeof(struct dst_entry)); | 236 | memset(&rt->rt6i_table, 0, sizeof(*rt) - sizeof(struct dst_entry)); |
236 | 237 | ||
@@ -1042,7 +1043,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, | |||
1042 | if (unlikely(idev == NULL)) | 1043 | if (unlikely(idev == NULL)) |
1043 | return NULL; | 1044 | return NULL; |
1044 | 1045 | ||
1045 | rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev); | 1046 | rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev, 0); |
1046 | if (unlikely(rt == NULL)) { | 1047 | if (unlikely(rt == NULL)) { |
1047 | in6_dev_put(idev); | 1048 | in6_dev_put(idev); |
1048 | goto out; | 1049 | goto out; |
@@ -1062,14 +1063,6 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, | |||
1062 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); | 1063 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); |
1063 | rt->dst.output = ip6_output; | 1064 | rt->dst.output = ip6_output; |
1064 | 1065 | ||
1065 | #if 0 /* there's no chance to use these for ndisc */ | ||
1066 | rt->dst.flags = ipv6_addr_type(addr) & IPV6_ADDR_UNICAST | ||
1067 | ? DST_HOST | ||
1068 | : 0; | ||
1069 | ipv6_addr_copy(&rt->rt6i_dst.addr, addr); | ||
1070 | rt->rt6i_dst.plen = 128; | ||
1071 | #endif | ||
1072 | |||
1073 | spin_lock_bh(&icmp6_dst_lock); | 1066 | spin_lock_bh(&icmp6_dst_lock); |
1074 | rt->dst.next = icmp6_dst_gc_list; | 1067 | rt->dst.next = icmp6_dst_gc_list; |
1075 | icmp6_dst_gc_list = &rt->dst; | 1068 | icmp6_dst_gc_list = &rt->dst; |
@@ -1214,7 +1207,7 @@ int ip6_route_add(struct fib6_config *cfg) | |||
1214 | goto out; | 1207 | goto out; |
1215 | } | 1208 | } |
1216 | 1209 | ||
1217 | rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, NULL); | 1210 | rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, NULL, DST_NOCOUNT); |
1218 | 1211 | ||
1219 | if (rt == NULL) { | 1212 | if (rt == NULL) { |
1220 | err = -ENOMEM; | 1213 | err = -ENOMEM; |
@@ -1244,7 +1237,7 @@ int ip6_route_add(struct fib6_config *cfg) | |||
1244 | ipv6_addr_prefix(&rt->rt6i_dst.addr, &cfg->fc_dst, cfg->fc_dst_len); | 1237 | ipv6_addr_prefix(&rt->rt6i_dst.addr, &cfg->fc_dst, cfg->fc_dst_len); |
1245 | rt->rt6i_dst.plen = cfg->fc_dst_len; | 1238 | rt->rt6i_dst.plen = cfg->fc_dst_len; |
1246 | if (rt->rt6i_dst.plen == 128) | 1239 | if (rt->rt6i_dst.plen == 128) |
1247 | rt->dst.flags = DST_HOST; | 1240 | rt->dst.flags |= DST_HOST; |
1248 | 1241 | ||
1249 | #ifdef CONFIG_IPV6_SUBTREES | 1242 | #ifdef CONFIG_IPV6_SUBTREES |
1250 | ipv6_addr_prefix(&rt->rt6i_src.addr, &cfg->fc_src, cfg->fc_src_len); | 1243 | ipv6_addr_prefix(&rt->rt6i_src.addr, &cfg->fc_src, cfg->fc_src_len); |
@@ -1734,7 +1727,7 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort) | |||
1734 | { | 1727 | { |
1735 | struct net *net = dev_net(ort->rt6i_dev); | 1728 | struct net *net = dev_net(ort->rt6i_dev); |
1736 | struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, | 1729 | struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, |
1737 | ort->dst.dev); | 1730 | ort->dst.dev, 0); |
1738 | 1731 | ||
1739 | if (rt) { | 1732 | if (rt) { |
1740 | rt->dst.input = ort->dst.input; | 1733 | rt->dst.input = ort->dst.input; |
@@ -2013,7 +2006,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, | |||
2013 | { | 2006 | { |
2014 | struct net *net = dev_net(idev->dev); | 2007 | struct net *net = dev_net(idev->dev); |
2015 | struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, | 2008 | struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, |
2016 | net->loopback_dev); | 2009 | net->loopback_dev, 0); |
2017 | struct neighbour *neigh; | 2010 | struct neighbour *neigh; |
2018 | 2011 | ||
2019 | if (rt == NULL) { | 2012 | if (rt == NULL) { |
@@ -2025,7 +2018,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev, | |||
2025 | 2018 | ||
2026 | in6_dev_hold(idev); | 2019 | in6_dev_hold(idev); |
2027 | 2020 | ||
2028 | rt->dst.flags = DST_HOST; | 2021 | rt->dst.flags |= DST_HOST; |
2029 | rt->dst.input = ip6_input; | 2022 | rt->dst.input = ip6_input; |
2030 | rt->dst.output = ip6_output; | 2023 | rt->dst.output = ip6_output; |
2031 | rt->rt6i_idev = idev; | 2024 | rt->rt6i_idev = idev; |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 58ffa7d069c7..669d2e32efb6 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -877,7 +877,8 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, | |||
877 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { | 877 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { |
878 | local->sched_scan_ies.ie[i] = kzalloc(2 + | 878 | local->sched_scan_ies.ie[i] = kzalloc(2 + |
879 | IEEE80211_MAX_SSID_LEN + | 879 | IEEE80211_MAX_SSID_LEN + |
880 | local->scan_ies_len, | 880 | local->scan_ies_len + |
881 | req->ie_len, | ||
881 | GFP_KERNEL); | 882 | GFP_KERNEL); |
882 | if (!local->sched_scan_ies.ie[i]) { | 883 | if (!local->sched_scan_ies.ie[i]) { |
883 | ret = -ENOMEM; | 884 | ret = -ENOMEM; |
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index 9dc3b5f26e80..8f6a302d2ac3 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -86,6 +86,11 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
86 | struct sk_buff *skb = rx->skb; | 86 | struct sk_buff *skb = rx->skb; |
87 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 87 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
88 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 88 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
89 | int queue = rx->queue; | ||
90 | |||
91 | /* otherwise, TKIP is vulnerable to TID 0 vs. non-QoS replays */ | ||
92 | if (rx->queue == NUM_RX_DATA_QUEUES - 1) | ||
93 | queue = 0; | ||
89 | 94 | ||
90 | /* | 95 | /* |
91 | * it makes no sense to check for MIC errors on anything other | 96 | * it makes no sense to check for MIC errors on anything other |
@@ -148,13 +153,19 @@ ieee80211_rx_h_michael_mic_verify(struct ieee80211_rx_data *rx) | |||
148 | 153 | ||
149 | update_iv: | 154 | update_iv: |
150 | /* update IV in key information to be able to detect replays */ | 155 | /* update IV in key information to be able to detect replays */ |
151 | rx->key->u.tkip.rx[rx->queue].iv32 = rx->tkip_iv32; | 156 | rx->key->u.tkip.rx[queue].iv32 = rx->tkip_iv32; |
152 | rx->key->u.tkip.rx[rx->queue].iv16 = rx->tkip_iv16; | 157 | rx->key->u.tkip.rx[queue].iv16 = rx->tkip_iv16; |
153 | 158 | ||
154 | return RX_CONTINUE; | 159 | return RX_CONTINUE; |
155 | 160 | ||
156 | mic_fail: | 161 | mic_fail: |
157 | mac80211_ev_michael_mic_failure(rx->sdata, rx->key->conf.keyidx, | 162 | /* |
163 | * In some cases the key can be unset - e.g. a multicast packet, in | ||
164 | * a driver that supports HW encryption. Send up the key idx only if | ||
165 | * the key is set. | ||
166 | */ | ||
167 | mac80211_ev_michael_mic_failure(rx->sdata, | ||
168 | rx->key ? rx->key->conf.keyidx : -1, | ||
158 | (void *) skb->data, NULL, GFP_ATOMIC); | 169 | (void *) skb->data, NULL, GFP_ATOMIC); |
159 | return RX_DROP_UNUSABLE; | 170 | return RX_DROP_UNUSABLE; |
160 | } | 171 | } |
@@ -235,6 +246,11 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
235 | struct ieee80211_key *key = rx->key; | 246 | struct ieee80211_key *key = rx->key; |
236 | struct sk_buff *skb = rx->skb; | 247 | struct sk_buff *skb = rx->skb; |
237 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 248 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
249 | int queue = rx->queue; | ||
250 | |||
251 | /* otherwise, TKIP is vulnerable to TID 0 vs. non-QoS replays */ | ||
252 | if (rx->queue == NUM_RX_DATA_QUEUES - 1) | ||
253 | queue = 0; | ||
238 | 254 | ||
239 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 255 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
240 | 256 | ||
@@ -255,7 +271,7 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
255 | res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm, | 271 | res = ieee80211_tkip_decrypt_data(rx->local->wep_rx_tfm, |
256 | key, skb->data + hdrlen, | 272 | key, skb->data + hdrlen, |
257 | skb->len - hdrlen, rx->sta->sta.addr, | 273 | skb->len - hdrlen, rx->sta->sta.addr, |
258 | hdr->addr1, hwaccel, rx->queue, | 274 | hdr->addr1, hwaccel, queue, |
259 | &rx->tkip_iv32, | 275 | &rx->tkip_iv32, |
260 | &rx->tkip_iv16); | 276 | &rx->tkip_iv16); |
261 | if (res != TKIP_DECRYPT_OK) | 277 | if (res != TKIP_DECRYPT_OK) |
diff --git a/net/sctp/output.c b/net/sctp/output.c index b4f3cf06d8da..08b3cead6503 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c | |||
@@ -500,23 +500,20 @@ int sctp_packet_transmit(struct sctp_packet *packet) | |||
500 | * Note: Adler-32 is no longer applicable, as has been replaced | 500 | * Note: Adler-32 is no longer applicable, as has been replaced |
501 | * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. | 501 | * by CRC32-C as described in <draft-ietf-tsvwg-sctpcsum-02.txt>. |
502 | */ | 502 | */ |
503 | if (!sctp_checksum_disable && | 503 | if (!sctp_checksum_disable) { |
504 | !(dst->dev->features & (NETIF_F_NO_CSUM | NETIF_F_SCTP_CSUM))) { | 504 | if (!(dst->dev->features & NETIF_F_SCTP_CSUM)) { |
505 | __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len); | 505 | __u32 crc32 = sctp_start_cksum((__u8 *)sh, cksum_buf_len); |
506 | 506 | ||
507 | /* 3) Put the resultant value into the checksum field in the | 507 | /* 3) Put the resultant value into the checksum field in the |
508 | * common header, and leave the rest of the bits unchanged. | 508 | * common header, and leave the rest of the bits unchanged. |
509 | */ | 509 | */ |
510 | sh->checksum = sctp_end_cksum(crc32); | 510 | sh->checksum = sctp_end_cksum(crc32); |
511 | } else { | 511 | } else { |
512 | if (dst->dev->features & NETIF_F_SCTP_CSUM) { | ||
513 | /* no need to seed pseudo checksum for SCTP */ | 512 | /* no need to seed pseudo checksum for SCTP */ |
514 | nskb->ip_summed = CHECKSUM_PARTIAL; | 513 | nskb->ip_summed = CHECKSUM_PARTIAL; |
515 | nskb->csum_start = (skb_transport_header(nskb) - | 514 | nskb->csum_start = (skb_transport_header(nskb) - |
516 | nskb->head); | 515 | nskb->head); |
517 | nskb->csum_offset = offsetof(struct sctphdr, checksum); | 516 | nskb->csum_offset = offsetof(struct sctphdr, checksum); |
518 | } else { | ||
519 | nskb->ip_summed = CHECKSUM_UNNECESSARY; | ||
520 | } | 517 | } |
521 | } | 518 | } |
522 | 519 | ||
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 1c88c8911dc5..d03682109b7a 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -1582,6 +1582,8 @@ static void sctp_check_transmitted(struct sctp_outq *q, | |||
1582 | #endif /* SCTP_DEBUG */ | 1582 | #endif /* SCTP_DEBUG */ |
1583 | if (transport) { | 1583 | if (transport) { |
1584 | if (bytes_acked) { | 1584 | if (bytes_acked) { |
1585 | struct sctp_association *asoc = transport->asoc; | ||
1586 | |||
1585 | /* We may have counted DATA that was migrated | 1587 | /* We may have counted DATA that was migrated |
1586 | * to this transport due to DEL-IP operation. | 1588 | * to this transport due to DEL-IP operation. |
1587 | * Subtract those bytes, since the were never | 1589 | * Subtract those bytes, since the were never |
@@ -1600,6 +1602,17 @@ static void sctp_check_transmitted(struct sctp_outq *q, | |||
1600 | transport->error_count = 0; | 1602 | transport->error_count = 0; |
1601 | transport->asoc->overall_error_count = 0; | 1603 | transport->asoc->overall_error_count = 0; |
1602 | 1604 | ||
1605 | /* | ||
1606 | * While in SHUTDOWN PENDING, we may have started | ||
1607 | * the T5 shutdown guard timer after reaching the | ||
1608 | * retransmission limit. Stop that timer as soon | ||
1609 | * as the receiver acknowledged any data. | ||
1610 | */ | ||
1611 | if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING && | ||
1612 | del_timer(&asoc->timers | ||
1613 | [SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD])) | ||
1614 | sctp_association_put(asoc); | ||
1615 | |||
1603 | /* Mark the destination transport address as | 1616 | /* Mark the destination transport address as |
1604 | * active if it is not so marked. | 1617 | * active if it is not so marked. |
1605 | */ | 1618 | */ |
@@ -1629,10 +1642,15 @@ static void sctp_check_transmitted(struct sctp_outq *q, | |||
1629 | * A sender is doing zero window probing when the | 1642 | * A sender is doing zero window probing when the |
1630 | * receiver's advertised window is zero, and there is | 1643 | * receiver's advertised window is zero, and there is |
1631 | * only one data chunk in flight to the receiver. | 1644 | * only one data chunk in flight to the receiver. |
1645 | * | ||
1646 | * Allow the association to timeout while in SHUTDOWN | ||
1647 | * PENDING or SHUTDOWN RECEIVED in case the receiver | ||
1648 | * stays in zero window mode forever. | ||
1632 | */ | 1649 | */ |
1633 | if (!q->asoc->peer.rwnd && | 1650 | if (!q->asoc->peer.rwnd && |
1634 | !list_empty(&tlist) && | 1651 | !list_empty(&tlist) && |
1635 | (sack_ctsn+2 == q->asoc->next_tsn)) { | 1652 | (sack_ctsn+2 == q->asoc->next_tsn) && |
1653 | q->asoc->state < SCTP_STATE_SHUTDOWN_PENDING) { | ||
1636 | SCTP_DEBUG_PRINTK("%s: SACK received for zero " | 1654 | SCTP_DEBUG_PRINTK("%s: SACK received for zero " |
1637 | "window probe: %u\n", | 1655 | "window probe: %u\n", |
1638 | __func__, sack_ctsn); | 1656 | __func__, sack_ctsn); |
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index 67380a29e2e9..207175b2f40a 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -1058,7 +1058,6 @@ SCTP_STATIC __init int sctp_init(void) | |||
1058 | int status = -EINVAL; | 1058 | int status = -EINVAL; |
1059 | unsigned long goal; | 1059 | unsigned long goal; |
1060 | unsigned long limit; | 1060 | unsigned long limit; |
1061 | unsigned long nr_pages; | ||
1062 | int max_share; | 1061 | int max_share; |
1063 | int order; | 1062 | int order; |
1064 | 1063 | ||
@@ -1148,15 +1147,7 @@ SCTP_STATIC __init int sctp_init(void) | |||
1148 | /* Initialize handle used for association ids. */ | 1147 | /* Initialize handle used for association ids. */ |
1149 | idr_init(&sctp_assocs_id); | 1148 | idr_init(&sctp_assocs_id); |
1150 | 1149 | ||
1151 | /* Set the pressure threshold to be a fraction of global memory that | 1150 | limit = nr_free_buffer_pages() / 8; |
1152 | * is up to 1/2 at 256 MB, decreasing toward zero with the amount of | ||
1153 | * memory, with a floor of 128 pages. | ||
1154 | * Note this initializes the data in sctpv6_prot too | ||
1155 | * Unabashedly stolen from tcp_init | ||
1156 | */ | ||
1157 | nr_pages = totalram_pages - totalhigh_pages; | ||
1158 | limit = min(nr_pages, 1UL<<(28-PAGE_SHIFT)) >> (20-PAGE_SHIFT); | ||
1159 | limit = (limit * (nr_pages >> (20-PAGE_SHIFT))) >> (PAGE_SHIFT-11); | ||
1160 | limit = max(limit, 128UL); | 1151 | limit = max(limit, 128UL); |
1161 | sysctl_sctp_mem[0] = limit / 4 * 3; | 1152 | sysctl_sctp_mem[0] = limit / 4 * 3; |
1162 | sysctl_sctp_mem[1] = limit; | 1153 | sysctl_sctp_mem[1] = limit; |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 534c2e5feb05..6e0f88295aaf 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -670,10 +670,19 @@ static void sctp_cmd_transport_on(sctp_cmd_seq_t *cmds, | |||
670 | /* 8.3 Upon the receipt of the HEARTBEAT ACK, the sender of the | 670 | /* 8.3 Upon the receipt of the HEARTBEAT ACK, the sender of the |
671 | * HEARTBEAT should clear the error counter of the destination | 671 | * HEARTBEAT should clear the error counter of the destination |
672 | * transport address to which the HEARTBEAT was sent. | 672 | * transport address to which the HEARTBEAT was sent. |
673 | * The association's overall error count is also cleared. | ||
674 | */ | 673 | */ |
675 | t->error_count = 0; | 674 | t->error_count = 0; |
676 | t->asoc->overall_error_count = 0; | 675 | |
676 | /* | ||
677 | * Although RFC4960 specifies that the overall error count must | ||
678 | * be cleared when a HEARTBEAT ACK is received, we make an | ||
679 | * exception while in SHUTDOWN PENDING. If the peer keeps its | ||
680 | * window shut forever, we may never be able to transmit our | ||
681 | * outstanding data and rely on the retransmission limit be reached | ||
682 | * to shutdown the association. | ||
683 | */ | ||
684 | if (t->asoc->state != SCTP_STATE_SHUTDOWN_PENDING) | ||
685 | t->asoc->overall_error_count = 0; | ||
677 | 686 | ||
678 | /* Clear the hb_sent flag to signal that we had a good | 687 | /* Clear the hb_sent flag to signal that we had a good |
679 | * acknowledgement. | 688 | * acknowledgement. |
@@ -1437,6 +1446,13 @@ static int sctp_cmd_interpreter(sctp_event_t event_type, | |||
1437 | sctp_cmd_setup_t2(commands, asoc, cmd->obj.ptr); | 1446 | sctp_cmd_setup_t2(commands, asoc, cmd->obj.ptr); |
1438 | break; | 1447 | break; |
1439 | 1448 | ||
1449 | case SCTP_CMD_TIMER_START_ONCE: | ||
1450 | timer = &asoc->timers[cmd->obj.to]; | ||
1451 | |||
1452 | if (timer_pending(timer)) | ||
1453 | break; | ||
1454 | /* fall through */ | ||
1455 | |||
1440 | case SCTP_CMD_TIMER_START: | 1456 | case SCTP_CMD_TIMER_START: |
1441 | timer = &asoc->timers[cmd->obj.to]; | 1457 | timer = &asoc->timers[cmd->obj.to]; |
1442 | timeout = asoc->timeouts[cmd->obj.to]; | 1458 | timeout = asoc->timeouts[cmd->obj.to]; |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index a297283154d5..246117142b5c 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
@@ -5154,7 +5154,7 @@ sctp_disposition_t sctp_sf_do_9_2_start_shutdown( | |||
5154 | * The sender of the SHUTDOWN MAY also start an overall guard timer | 5154 | * The sender of the SHUTDOWN MAY also start an overall guard timer |
5155 | * 'T5-shutdown-guard' to bound the overall time for shutdown sequence. | 5155 | * 'T5-shutdown-guard' to bound the overall time for shutdown sequence. |
5156 | */ | 5156 | */ |
5157 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START, | 5157 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_RESTART, |
5158 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); | 5158 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); |
5159 | 5159 | ||
5160 | if (asoc->autoclose) | 5160 | if (asoc->autoclose) |
@@ -5299,14 +5299,28 @@ sctp_disposition_t sctp_sf_do_6_3_3_rtx(const struct sctp_endpoint *ep, | |||
5299 | SCTP_INC_STATS(SCTP_MIB_T3_RTX_EXPIREDS); | 5299 | SCTP_INC_STATS(SCTP_MIB_T3_RTX_EXPIREDS); |
5300 | 5300 | ||
5301 | if (asoc->overall_error_count >= asoc->max_retrans) { | 5301 | if (asoc->overall_error_count >= asoc->max_retrans) { |
5302 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | 5302 | if (asoc->state == SCTP_STATE_SHUTDOWN_PENDING) { |
5303 | SCTP_ERROR(ETIMEDOUT)); | 5303 | /* |
5304 | /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ | 5304 | * We are here likely because the receiver had its rwnd |
5305 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, | 5305 | * closed for a while and we have not been able to |
5306 | SCTP_PERR(SCTP_ERROR_NO_ERROR)); | 5306 | * transmit the locally queued data within the maximum |
5307 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); | 5307 | * retransmission attempts limit. Start the T5 |
5308 | SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); | 5308 | * shutdown guard timer to give the receiver one last |
5309 | return SCTP_DISPOSITION_DELETE_TCB; | 5309 | * chance and some additional time to recover before |
5310 | * aborting. | ||
5311 | */ | ||
5312 | sctp_add_cmd_sf(commands, SCTP_CMD_TIMER_START_ONCE, | ||
5313 | SCTP_TO(SCTP_EVENT_TIMEOUT_T5_SHUTDOWN_GUARD)); | ||
5314 | } else { | ||
5315 | sctp_add_cmd_sf(commands, SCTP_CMD_SET_SK_ERR, | ||
5316 | SCTP_ERROR(ETIMEDOUT)); | ||
5317 | /* CMD_ASSOC_FAILED calls CMD_DELETE_TCB. */ | ||
5318 | sctp_add_cmd_sf(commands, SCTP_CMD_ASSOC_FAILED, | ||
5319 | SCTP_PERR(SCTP_ERROR_NO_ERROR)); | ||
5320 | SCTP_INC_STATS(SCTP_MIB_ABORTEDS); | ||
5321 | SCTP_DEC_STATS(SCTP_MIB_CURRESTAB); | ||
5322 | return SCTP_DISPOSITION_DELETE_TCB; | ||
5323 | } | ||
5310 | } | 5324 | } |
5311 | 5325 | ||
5312 | /* E1) For the destination address for which the timer | 5326 | /* E1) For the destination address for which the timer |
diff --git a/net/sctp/sm_statetable.c b/net/sctp/sm_statetable.c index 0338dc6fdc9d..7c211a7f90f4 100644 --- a/net/sctp/sm_statetable.c +++ b/net/sctp/sm_statetable.c | |||
@@ -827,7 +827,7 @@ static const sctp_sm_table_entry_t other_event_table[SCTP_NUM_OTHER_TYPES][SCTP_ | |||
827 | /* SCTP_STATE_ESTABLISHED */ \ | 827 | /* SCTP_STATE_ESTABLISHED */ \ |
828 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | 828 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ |
829 | /* SCTP_STATE_SHUTDOWN_PENDING */ \ | 829 | /* SCTP_STATE_SHUTDOWN_PENDING */ \ |
830 | TYPE_SCTP_FUNC(sctp_sf_timer_ignore), \ | 830 | TYPE_SCTP_FUNC(sctp_sf_t5_timer_expire), \ |
831 | /* SCTP_STATE_SHUTDOWN_SENT */ \ | 831 | /* SCTP_STATE_SHUTDOWN_SENT */ \ |
832 | TYPE_SCTP_FUNC(sctp_sf_t5_timer_expire), \ | 832 | TYPE_SCTP_FUNC(sctp_sf_t5_timer_expire), \ |
833 | /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ | 833 | /* SCTP_STATE_SHUTDOWN_RECEIVED */ \ |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 6766913a53e6..d3ccf7973c59 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -1384,6 +1384,7 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout) | |||
1384 | struct sctp_endpoint *ep; | 1384 | struct sctp_endpoint *ep; |
1385 | struct sctp_association *asoc; | 1385 | struct sctp_association *asoc; |
1386 | struct list_head *pos, *temp; | 1386 | struct list_head *pos, *temp; |
1387 | unsigned int data_was_unread; | ||
1387 | 1388 | ||
1388 | SCTP_DEBUG_PRINTK("sctp_close(sk: 0x%p, timeout:%ld)\n", sk, timeout); | 1389 | SCTP_DEBUG_PRINTK("sctp_close(sk: 0x%p, timeout:%ld)\n", sk, timeout); |
1389 | 1390 | ||
@@ -1393,6 +1394,10 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout) | |||
1393 | 1394 | ||
1394 | ep = sctp_sk(sk)->ep; | 1395 | ep = sctp_sk(sk)->ep; |
1395 | 1396 | ||
1397 | /* Clean up any skbs sitting on the receive queue. */ | ||
1398 | data_was_unread = sctp_queue_purge_ulpevents(&sk->sk_receive_queue); | ||
1399 | data_was_unread += sctp_queue_purge_ulpevents(&sctp_sk(sk)->pd_lobby); | ||
1400 | |||
1396 | /* Walk all associations on an endpoint. */ | 1401 | /* Walk all associations on an endpoint. */ |
1397 | list_for_each_safe(pos, temp, &ep->asocs) { | 1402 | list_for_each_safe(pos, temp, &ep->asocs) { |
1398 | asoc = list_entry(pos, struct sctp_association, asocs); | 1403 | asoc = list_entry(pos, struct sctp_association, asocs); |
@@ -1410,7 +1415,9 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout) | |||
1410 | } | 1415 | } |
1411 | } | 1416 | } |
1412 | 1417 | ||
1413 | if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) { | 1418 | if (data_was_unread || !skb_queue_empty(&asoc->ulpq.lobby) || |
1419 | !skb_queue_empty(&asoc->ulpq.reasm) || | ||
1420 | (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime)) { | ||
1414 | struct sctp_chunk *chunk; | 1421 | struct sctp_chunk *chunk; |
1415 | 1422 | ||
1416 | chunk = sctp_make_abort_user(asoc, NULL, 0); | 1423 | chunk = sctp_make_abort_user(asoc, NULL, 0); |
@@ -1420,10 +1427,6 @@ SCTP_STATIC void sctp_close(struct sock *sk, long timeout) | |||
1420 | sctp_primitive_SHUTDOWN(asoc, NULL); | 1427 | sctp_primitive_SHUTDOWN(asoc, NULL); |
1421 | } | 1428 | } |
1422 | 1429 | ||
1423 | /* Clean up any skbs sitting on the receive queue. */ | ||
1424 | sctp_queue_purge_ulpevents(&sk->sk_receive_queue); | ||
1425 | sctp_queue_purge_ulpevents(&sctp_sk(sk)->pd_lobby); | ||
1426 | |||
1427 | /* On a TCP-style socket, block for at most linger_time if set. */ | 1430 | /* On a TCP-style socket, block for at most linger_time if set. */ |
1428 | if (sctp_style(sk, TCP) && timeout) | 1431 | if (sctp_style(sk, TCP) && timeout) |
1429 | sctp_wait_for_close(sk, timeout); | 1432 | sctp_wait_for_close(sk, timeout); |
@@ -2073,10 +2076,33 @@ static int sctp_setsockopt_disable_fragments(struct sock *sk, | |||
2073 | static int sctp_setsockopt_events(struct sock *sk, char __user *optval, | 2076 | static int sctp_setsockopt_events(struct sock *sk, char __user *optval, |
2074 | unsigned int optlen) | 2077 | unsigned int optlen) |
2075 | { | 2078 | { |
2079 | struct sctp_association *asoc; | ||
2080 | struct sctp_ulpevent *event; | ||
2081 | |||
2076 | if (optlen > sizeof(struct sctp_event_subscribe)) | 2082 | if (optlen > sizeof(struct sctp_event_subscribe)) |
2077 | return -EINVAL; | 2083 | return -EINVAL; |
2078 | if (copy_from_user(&sctp_sk(sk)->subscribe, optval, optlen)) | 2084 | if (copy_from_user(&sctp_sk(sk)->subscribe, optval, optlen)) |
2079 | return -EFAULT; | 2085 | return -EFAULT; |
2086 | |||
2087 | /* | ||
2088 | * At the time when a user app subscribes to SCTP_SENDER_DRY_EVENT, | ||
2089 | * if there is no data to be sent or retransmit, the stack will | ||
2090 | * immediately send up this notification. | ||
2091 | */ | ||
2092 | if (sctp_ulpevent_type_enabled(SCTP_SENDER_DRY_EVENT, | ||
2093 | &sctp_sk(sk)->subscribe)) { | ||
2094 | asoc = sctp_id2assoc(sk, 0); | ||
2095 | |||
2096 | if (asoc && sctp_outq_is_empty(&asoc->outqueue)) { | ||
2097 | event = sctp_ulpevent_make_sender_dry_event(asoc, | ||
2098 | GFP_ATOMIC); | ||
2099 | if (!event) | ||
2100 | return -ENOMEM; | ||
2101 | |||
2102 | sctp_ulpq_tail_event(&asoc->ulpq, event); | ||
2103 | } | ||
2104 | } | ||
2105 | |||
2080 | return 0; | 2106 | return 0; |
2081 | } | 2107 | } |
2082 | 2108 | ||
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index e70e5fc87890..8a84017834c2 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c | |||
@@ -1081,9 +1081,19 @@ void sctp_ulpevent_free(struct sctp_ulpevent *event) | |||
1081 | } | 1081 | } |
1082 | 1082 | ||
1083 | /* Purge the skb lists holding ulpevents. */ | 1083 | /* Purge the skb lists holding ulpevents. */ |
1084 | void sctp_queue_purge_ulpevents(struct sk_buff_head *list) | 1084 | unsigned int sctp_queue_purge_ulpevents(struct sk_buff_head *list) |
1085 | { | 1085 | { |
1086 | struct sk_buff *skb; | 1086 | struct sk_buff *skb; |
1087 | while ((skb = skb_dequeue(list)) != NULL) | 1087 | unsigned int data_unread = 0; |
1088 | sctp_ulpevent_free(sctp_skb2event(skb)); | 1088 | |
1089 | while ((skb = skb_dequeue(list)) != NULL) { | ||
1090 | struct sctp_ulpevent *event = sctp_skb2event(skb); | ||
1091 | |||
1092 | if (!sctp_ulpevent_is_notification(event)) | ||
1093 | data_unread += skb->len; | ||
1094 | |||
1095 | sctp_ulpevent_free(event); | ||
1096 | } | ||
1097 | |||
1098 | return data_unread; | ||
1089 | } | 1099 | } |
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 9a80a922c527..e45d2fbbe5a8 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c | |||
@@ -597,7 +597,7 @@ void rpcb_getport_async(struct rpc_task *task) | |||
597 | u32 bind_version; | 597 | u32 bind_version; |
598 | struct rpc_xprt *xprt; | 598 | struct rpc_xprt *xprt; |
599 | struct rpc_clnt *rpcb_clnt; | 599 | struct rpc_clnt *rpcb_clnt; |
600 | static struct rpcbind_args *map; | 600 | struct rpcbind_args *map; |
601 | struct rpc_task *child; | 601 | struct rpc_task *child; |
602 | struct sockaddr_storage addr; | 602 | struct sockaddr_storage addr; |
603 | struct sockaddr *sap = (struct sockaddr *)&addr; | 603 | struct sockaddr *sap = (struct sockaddr *)&addr; |
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index a27406b1654f..4814e246a874 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c | |||
@@ -616,30 +616,25 @@ static void __rpc_execute(struct rpc_task *task) | |||
616 | BUG_ON(RPC_IS_QUEUED(task)); | 616 | BUG_ON(RPC_IS_QUEUED(task)); |
617 | 617 | ||
618 | for (;;) { | 618 | for (;;) { |
619 | void (*do_action)(struct rpc_task *); | ||
619 | 620 | ||
620 | /* | 621 | /* |
621 | * Execute any pending callback. | 622 | * Execute any pending callback first. |
622 | */ | 623 | */ |
623 | if (task->tk_callback) { | 624 | do_action = task->tk_callback; |
624 | void (*save_callback)(struct rpc_task *); | 625 | task->tk_callback = NULL; |
625 | 626 | if (do_action == NULL) { | |
626 | /* | ||
627 | * We set tk_callback to NULL before calling it, | ||
628 | * in case it sets the tk_callback field itself: | ||
629 | */ | ||
630 | save_callback = task->tk_callback; | ||
631 | task->tk_callback = NULL; | ||
632 | save_callback(task); | ||
633 | } else { | ||
634 | /* | 627 | /* |
635 | * Perform the next FSM step. | 628 | * Perform the next FSM step. |
636 | * tk_action may be NULL when the task has been killed | 629 | * tk_action may be NULL if the task has been killed. |
637 | * by someone else. | 630 | * In particular, note that rpc_killall_tasks may |
631 | * do this at any time, so beware when dereferencing. | ||
638 | */ | 632 | */ |
639 | if (task->tk_action == NULL) | 633 | do_action = task->tk_action; |
634 | if (do_action == NULL) | ||
640 | break; | 635 | break; |
641 | task->tk_action(task); | ||
642 | } | 636 | } |
637 | do_action(task); | ||
643 | 638 | ||
644 | /* | 639 | /* |
645 | * Lockless check for whether task is sleeping or not. | 640 | * Lockless check for whether task is sleeping or not. |
diff --git a/net/wireless/core.c b/net/wireless/core.c index c22ef3492ee6..880dbe2e6f94 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -366,6 +366,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv) | |||
366 | 366 | ||
367 | mutex_init(&rdev->mtx); | 367 | mutex_init(&rdev->mtx); |
368 | mutex_init(&rdev->devlist_mtx); | 368 | mutex_init(&rdev->devlist_mtx); |
369 | mutex_init(&rdev->sched_scan_mtx); | ||
369 | INIT_LIST_HEAD(&rdev->netdev_list); | 370 | INIT_LIST_HEAD(&rdev->netdev_list); |
370 | spin_lock_init(&rdev->bss_lock); | 371 | spin_lock_init(&rdev->bss_lock); |
371 | INIT_LIST_HEAD(&rdev->bss_list); | 372 | INIT_LIST_HEAD(&rdev->bss_list); |
@@ -701,6 +702,7 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev) | |||
701 | rfkill_destroy(rdev->rfkill); | 702 | rfkill_destroy(rdev->rfkill); |
702 | mutex_destroy(&rdev->mtx); | 703 | mutex_destroy(&rdev->mtx); |
703 | mutex_destroy(&rdev->devlist_mtx); | 704 | mutex_destroy(&rdev->devlist_mtx); |
705 | mutex_destroy(&rdev->sched_scan_mtx); | ||
704 | list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list) | 706 | list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list) |
705 | cfg80211_put_bss(&scan->pub); | 707 | cfg80211_put_bss(&scan->pub); |
706 | cfg80211_rdev_free_wowlan(rdev); | 708 | cfg80211_rdev_free_wowlan(rdev); |
@@ -737,12 +739,16 @@ static void wdev_cleanup_work(struct work_struct *work) | |||
737 | ___cfg80211_scan_done(rdev, true); | 739 | ___cfg80211_scan_done(rdev, true); |
738 | } | 740 | } |
739 | 741 | ||
742 | cfg80211_unlock_rdev(rdev); | ||
743 | |||
744 | mutex_lock(&rdev->sched_scan_mtx); | ||
745 | |||
740 | if (WARN_ON(rdev->sched_scan_req && | 746 | if (WARN_ON(rdev->sched_scan_req && |
741 | rdev->sched_scan_req->dev == wdev->netdev)) { | 747 | rdev->sched_scan_req->dev == wdev->netdev)) { |
742 | __cfg80211_stop_sched_scan(rdev, false); | 748 | __cfg80211_stop_sched_scan(rdev, false); |
743 | } | 749 | } |
744 | 750 | ||
745 | cfg80211_unlock_rdev(rdev); | 751 | mutex_unlock(&rdev->sched_scan_mtx); |
746 | 752 | ||
747 | mutex_lock(&rdev->devlist_mtx); | 753 | mutex_lock(&rdev->devlist_mtx); |
748 | rdev->opencount--; | 754 | rdev->opencount--; |
@@ -830,9 +836,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb, | |||
830 | break; | 836 | break; |
831 | case NL80211_IFTYPE_P2P_CLIENT: | 837 | case NL80211_IFTYPE_P2P_CLIENT: |
832 | case NL80211_IFTYPE_STATION: | 838 | case NL80211_IFTYPE_STATION: |
833 | cfg80211_lock_rdev(rdev); | 839 | mutex_lock(&rdev->sched_scan_mtx); |
834 | __cfg80211_stop_sched_scan(rdev, false); | 840 | __cfg80211_stop_sched_scan(rdev, false); |
835 | cfg80211_unlock_rdev(rdev); | 841 | mutex_unlock(&rdev->sched_scan_mtx); |
836 | 842 | ||
837 | wdev_lock(wdev); | 843 | wdev_lock(wdev); |
838 | #ifdef CONFIG_CFG80211_WEXT | 844 | #ifdef CONFIG_CFG80211_WEXT |
diff --git a/net/wireless/core.h b/net/wireless/core.h index 3dce1f167eba..a570ff9214ec 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -65,6 +65,8 @@ struct cfg80211_registered_device { | |||
65 | struct work_struct scan_done_wk; | 65 | struct work_struct scan_done_wk; |
66 | struct work_struct sched_scan_results_wk; | 66 | struct work_struct sched_scan_results_wk; |
67 | 67 | ||
68 | struct mutex sched_scan_mtx; | ||
69 | |||
68 | #ifdef CONFIG_NL80211_TESTMODE | 70 | #ifdef CONFIG_NL80211_TESTMODE |
69 | struct genl_info *testmode_info; | 71 | struct genl_info *testmode_info; |
70 | #endif | 72 | #endif |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 98fa8eb6cc4b..cea338150d05 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -3461,9 +3461,6 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
3461 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) | 3461 | if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) |
3462 | return -EINVAL; | 3462 | return -EINVAL; |
3463 | 3463 | ||
3464 | if (rdev->sched_scan_req) | ||
3465 | return -EINPROGRESS; | ||
3466 | |||
3467 | if (!info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]) | 3464 | if (!info->attrs[NL80211_ATTR_SCHED_SCAN_INTERVAL]) |
3468 | return -EINVAL; | 3465 | return -EINVAL; |
3469 | 3466 | ||
@@ -3502,12 +3499,21 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
3502 | if (ie_len > wiphy->max_scan_ie_len) | 3499 | if (ie_len > wiphy->max_scan_ie_len) |
3503 | return -EINVAL; | 3500 | return -EINVAL; |
3504 | 3501 | ||
3502 | mutex_lock(&rdev->sched_scan_mtx); | ||
3503 | |||
3504 | if (rdev->sched_scan_req) { | ||
3505 | err = -EINPROGRESS; | ||
3506 | goto out; | ||
3507 | } | ||
3508 | |||
3505 | request = kzalloc(sizeof(*request) | 3509 | request = kzalloc(sizeof(*request) |
3506 | + sizeof(*request->ssids) * n_ssids | 3510 | + sizeof(*request->ssids) * n_ssids |
3507 | + sizeof(*request->channels) * n_channels | 3511 | + sizeof(*request->channels) * n_channels |
3508 | + ie_len, GFP_KERNEL); | 3512 | + ie_len, GFP_KERNEL); |
3509 | if (!request) | 3513 | if (!request) { |
3510 | return -ENOMEM; | 3514 | err = -ENOMEM; |
3515 | goto out; | ||
3516 | } | ||
3511 | 3517 | ||
3512 | if (n_ssids) | 3518 | if (n_ssids) |
3513 | request->ssids = (void *)&request->channels[n_channels]; | 3519 | request->ssids = (void *)&request->channels[n_channels]; |
@@ -3605,6 +3611,7 @@ static int nl80211_start_sched_scan(struct sk_buff *skb, | |||
3605 | out_free: | 3611 | out_free: |
3606 | kfree(request); | 3612 | kfree(request); |
3607 | out: | 3613 | out: |
3614 | mutex_unlock(&rdev->sched_scan_mtx); | ||
3608 | return err; | 3615 | return err; |
3609 | } | 3616 | } |
3610 | 3617 | ||
@@ -3612,12 +3619,17 @@ static int nl80211_stop_sched_scan(struct sk_buff *skb, | |||
3612 | struct genl_info *info) | 3619 | struct genl_info *info) |
3613 | { | 3620 | { |
3614 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; | 3621 | struct cfg80211_registered_device *rdev = info->user_ptr[0]; |
3622 | int err; | ||
3615 | 3623 | ||
3616 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || | 3624 | if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || |
3617 | !rdev->ops->sched_scan_stop) | 3625 | !rdev->ops->sched_scan_stop) |
3618 | return -EOPNOTSUPP; | 3626 | return -EOPNOTSUPP; |
3619 | 3627 | ||
3620 | return __cfg80211_stop_sched_scan(rdev, false); | 3628 | mutex_lock(&rdev->sched_scan_mtx); |
3629 | err = __cfg80211_stop_sched_scan(rdev, false); | ||
3630 | mutex_unlock(&rdev->sched_scan_mtx); | ||
3631 | |||
3632 | return err; | ||
3621 | } | 3633 | } |
3622 | 3634 | ||
3623 | static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags, | 3635 | static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags, |
@@ -6463,7 +6475,8 @@ void nl80211_michael_mic_failure(struct cfg80211_registered_device *rdev, | |||
6463 | if (addr) | 6475 | if (addr) |
6464 | NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); | 6476 | NLA_PUT(msg, NL80211_ATTR_MAC, ETH_ALEN, addr); |
6465 | NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE, key_type); | 6477 | NLA_PUT_U32(msg, NL80211_ATTR_KEY_TYPE, key_type); |
6466 | NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_id); | 6478 | if (key_id != -1) |
6479 | NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_id); | ||
6467 | if (tsc) | 6480 | if (tsc) |
6468 | NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc); | 6481 | NLA_PUT(msg, NL80211_ATTR_KEY_SEQ, 6, tsc); |
6469 | 6482 | ||
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 7a6c67667d70..ae0c2256ba3b 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -100,14 +100,14 @@ void __cfg80211_sched_scan_results(struct work_struct *wk) | |||
100 | rdev = container_of(wk, struct cfg80211_registered_device, | 100 | rdev = container_of(wk, struct cfg80211_registered_device, |
101 | sched_scan_results_wk); | 101 | sched_scan_results_wk); |
102 | 102 | ||
103 | cfg80211_lock_rdev(rdev); | 103 | mutex_lock(&rdev->sched_scan_mtx); |
104 | 104 | ||
105 | /* we don't have sched_scan_req anymore if the scan is stopping */ | 105 | /* we don't have sched_scan_req anymore if the scan is stopping */ |
106 | if (rdev->sched_scan_req) | 106 | if (rdev->sched_scan_req) |
107 | nl80211_send_sched_scan_results(rdev, | 107 | nl80211_send_sched_scan_results(rdev, |
108 | rdev->sched_scan_req->dev); | 108 | rdev->sched_scan_req->dev); |
109 | 109 | ||
110 | cfg80211_unlock_rdev(rdev); | 110 | mutex_unlock(&rdev->sched_scan_mtx); |
111 | } | 111 | } |
112 | 112 | ||
113 | void cfg80211_sched_scan_results(struct wiphy *wiphy) | 113 | void cfg80211_sched_scan_results(struct wiphy *wiphy) |
@@ -123,9 +123,9 @@ void cfg80211_sched_scan_stopped(struct wiphy *wiphy) | |||
123 | { | 123 | { |
124 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); | 124 | struct cfg80211_registered_device *rdev = wiphy_to_dev(wiphy); |
125 | 125 | ||
126 | cfg80211_lock_rdev(rdev); | 126 | mutex_lock(&rdev->sched_scan_mtx); |
127 | __cfg80211_stop_sched_scan(rdev, true); | 127 | __cfg80211_stop_sched_scan(rdev, true); |
128 | cfg80211_unlock_rdev(rdev); | 128 | mutex_unlock(&rdev->sched_scan_mtx); |
129 | } | 129 | } |
130 | EXPORT_SYMBOL(cfg80211_sched_scan_stopped); | 130 | EXPORT_SYMBOL(cfg80211_sched_scan_stopped); |
131 | 131 | ||
@@ -135,7 +135,7 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev, | |||
135 | int err; | 135 | int err; |
136 | struct net_device *dev; | 136 | struct net_device *dev; |
137 | 137 | ||
138 | ASSERT_RDEV_LOCK(rdev); | 138 | lockdep_assert_held(&rdev->sched_scan_mtx); |
139 | 139 | ||
140 | if (!rdev->sched_scan_req) | 140 | if (!rdev->sched_scan_req) |
141 | return 0; | 141 | return 0; |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 9bec2e8a838c..5ce74a385525 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -50,7 +50,7 @@ static struct xfrm_policy_afinfo *xfrm_policy_get_afinfo(unsigned short family); | |||
50 | static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo); | 50 | static void xfrm_policy_put_afinfo(struct xfrm_policy_afinfo *afinfo); |
51 | static void xfrm_init_pmtu(struct dst_entry *dst); | 51 | static void xfrm_init_pmtu(struct dst_entry *dst); |
52 | static int stale_bundle(struct dst_entry *dst); | 52 | static int stale_bundle(struct dst_entry *dst); |
53 | static int xfrm_bundle_ok(struct xfrm_dst *xdst, int family); | 53 | static int xfrm_bundle_ok(struct xfrm_dst *xdst); |
54 | 54 | ||
55 | 55 | ||
56 | static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol, | 56 | static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol, |
@@ -2241,7 +2241,7 @@ static struct dst_entry *xfrm_dst_check(struct dst_entry *dst, u32 cookie) | |||
2241 | 2241 | ||
2242 | static int stale_bundle(struct dst_entry *dst) | 2242 | static int stale_bundle(struct dst_entry *dst) |
2243 | { | 2243 | { |
2244 | return !xfrm_bundle_ok((struct xfrm_dst *)dst, AF_UNSPEC); | 2244 | return !xfrm_bundle_ok((struct xfrm_dst *)dst); |
2245 | } | 2245 | } |
2246 | 2246 | ||
2247 | void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev) | 2247 | void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev) |
@@ -2313,7 +2313,7 @@ static void xfrm_init_pmtu(struct dst_entry *dst) | |||
2313 | * still valid. | 2313 | * still valid. |
2314 | */ | 2314 | */ |
2315 | 2315 | ||
2316 | static int xfrm_bundle_ok(struct xfrm_dst *first, int family) | 2316 | static int xfrm_bundle_ok(struct xfrm_dst *first) |
2317 | { | 2317 | { |
2318 | struct dst_entry *dst = &first->u.dst; | 2318 | struct dst_entry *dst = &first->u.dst; |
2319 | struct xfrm_dst *last; | 2319 | struct xfrm_dst *last; |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index d70f85eb7864..9414b9c5b1e4 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -1345,6 +1345,8 @@ out: | |||
1345 | xfrm_state_check_expire(x1); | 1345 | xfrm_state_check_expire(x1); |
1346 | 1346 | ||
1347 | err = 0; | 1347 | err = 0; |
1348 | x->km.state = XFRM_STATE_DEAD; | ||
1349 | __xfrm_state_put(x); | ||
1348 | } | 1350 | } |
1349 | spin_unlock_bh(&x1->lock); | 1351 | spin_unlock_bh(&x1->lock); |
1350 | 1352 | ||
diff --git a/scripts/depmod.sh b/scripts/depmod.sh index 3b029cba2baf..a27235685949 100755 --- a/scripts/depmod.sh +++ b/scripts/depmod.sh | |||
@@ -21,13 +21,15 @@ fi | |||
21 | # older versions of depmod require the version string to start with three | 21 | # older versions of depmod require the version string to start with three |
22 | # numbers, so we cheat with a symlink here | 22 | # numbers, so we cheat with a symlink here |
23 | depmod_hack_needed=true | 23 | depmod_hack_needed=true |
24 | mkdir -p .tmp_depmod/lib/modules/$KERNELRELEASE | 24 | tmp_dir=$(mktemp -d ${TMPDIR:-/tmp}/depmod.XXXXXX) |
25 | if "$DEPMOD" -b .tmp_depmod $KERNELRELEASE 2>/dev/null; then | 25 | mkdir -p "$tmp_dir/lib/modules/$KERNELRELEASE" |
26 | if test -e .tmp_depmod/lib/modules/$KERNELRELEASE/modules.dep -o \ | 26 | if "$DEPMOD" -b "$tmp_dir" $KERNELRELEASE 2>/dev/null; then |
27 | -e .tmp_depmod/lib/modules/$KERNELRELEASE/modules.dep.bin; then | 27 | if test -e "$tmp_dir/lib/modules/$KERNELRELEASE/modules.dep" -o \ |
28 | -e "$tmp_dir/lib/modules/$KERNELRELEASE/modules.dep.bin"; then | ||
28 | depmod_hack_needed=false | 29 | depmod_hack_needed=false |
29 | fi | 30 | fi |
30 | fi | 31 | fi |
32 | rm -rf "$tmp_dir" | ||
31 | if $depmod_hack_needed; then | 33 | if $depmod_hack_needed; then |
32 | symlink="$INSTALL_MOD_PATH/lib/modules/99.98.$KERNELRELEASE" | 34 | symlink="$INSTALL_MOD_PATH/lib/modules/99.98.$KERNELRELEASE" |
33 | ln -s "$KERNELRELEASE" "$symlink" | 35 | ln -s "$KERNELRELEASE" "$symlink" |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d21191dcfe88..b48fb43b5448 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -2715,17 +2715,30 @@ typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol, | |||
2715 | 2715 | ||
2716 | static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, | 2716 | static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, |
2717 | struct snd_ctl_elem_value *ucontrol, | 2717 | struct snd_ctl_elem_value *ucontrol, |
2718 | getput_call_t func) | 2718 | getput_call_t func, bool check_adc_switch) |
2719 | { | 2719 | { |
2720 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 2720 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
2721 | struct alc_spec *spec = codec->spec; | 2721 | struct alc_spec *spec = codec->spec; |
2722 | unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 2722 | int i, err = 0; |
2723 | int err; | ||
2724 | 2723 | ||
2725 | mutex_lock(&codec->control_mutex); | 2724 | mutex_lock(&codec->control_mutex); |
2726 | kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx], | 2725 | if (check_adc_switch && spec->dual_adc_switch) { |
2727 | 3, 0, HDA_INPUT); | 2726 | for (i = 0; i < spec->num_adc_nids; i++) { |
2728 | err = func(kcontrol, ucontrol); | 2727 | kcontrol->private_value = |
2728 | HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], | ||
2729 | 3, 0, HDA_INPUT); | ||
2730 | err = func(kcontrol, ucontrol); | ||
2731 | if (err < 0) | ||
2732 | goto error; | ||
2733 | } | ||
2734 | } else { | ||
2735 | i = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | ||
2736 | kcontrol->private_value = | ||
2737 | HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], | ||
2738 | 3, 0, HDA_INPUT); | ||
2739 | err = func(kcontrol, ucontrol); | ||
2740 | } | ||
2741 | error: | ||
2729 | mutex_unlock(&codec->control_mutex); | 2742 | mutex_unlock(&codec->control_mutex); |
2730 | return err; | 2743 | return err; |
2731 | } | 2744 | } |
@@ -2734,14 +2747,14 @@ static int alc_cap_vol_get(struct snd_kcontrol *kcontrol, | |||
2734 | struct snd_ctl_elem_value *ucontrol) | 2747 | struct snd_ctl_elem_value *ucontrol) |
2735 | { | 2748 | { |
2736 | return alc_cap_getput_caller(kcontrol, ucontrol, | 2749 | return alc_cap_getput_caller(kcontrol, ucontrol, |
2737 | snd_hda_mixer_amp_volume_get); | 2750 | snd_hda_mixer_amp_volume_get, false); |
2738 | } | 2751 | } |
2739 | 2752 | ||
2740 | static int alc_cap_vol_put(struct snd_kcontrol *kcontrol, | 2753 | static int alc_cap_vol_put(struct snd_kcontrol *kcontrol, |
2741 | struct snd_ctl_elem_value *ucontrol) | 2754 | struct snd_ctl_elem_value *ucontrol) |
2742 | { | 2755 | { |
2743 | return alc_cap_getput_caller(kcontrol, ucontrol, | 2756 | return alc_cap_getput_caller(kcontrol, ucontrol, |
2744 | snd_hda_mixer_amp_volume_put); | 2757 | snd_hda_mixer_amp_volume_put, true); |
2745 | } | 2758 | } |
2746 | 2759 | ||
2747 | /* capture mixer elements */ | 2760 | /* capture mixer elements */ |
@@ -2751,14 +2764,14 @@ static int alc_cap_sw_get(struct snd_kcontrol *kcontrol, | |||
2751 | struct snd_ctl_elem_value *ucontrol) | 2764 | struct snd_ctl_elem_value *ucontrol) |
2752 | { | 2765 | { |
2753 | return alc_cap_getput_caller(kcontrol, ucontrol, | 2766 | return alc_cap_getput_caller(kcontrol, ucontrol, |
2754 | snd_hda_mixer_amp_switch_get); | 2767 | snd_hda_mixer_amp_switch_get, false); |
2755 | } | 2768 | } |
2756 | 2769 | ||
2757 | static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, | 2770 | static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, |
2758 | struct snd_ctl_elem_value *ucontrol) | 2771 | struct snd_ctl_elem_value *ucontrol) |
2759 | { | 2772 | { |
2760 | return alc_cap_getput_caller(kcontrol, ucontrol, | 2773 | return alc_cap_getput_caller(kcontrol, ucontrol, |
2761 | snd_hda_mixer_amp_switch_put); | 2774 | snd_hda_mixer_amp_switch_put, true); |
2762 | } | 2775 | } |
2763 | 2776 | ||
2764 | #define _DEFINE_CAPMIX(num) \ | 2777 | #define _DEFINE_CAPMIX(num) \ |
diff --git a/sound/soc/blackfin/bf5xx-i2s-pcm.c b/sound/soc/blackfin/bf5xx-i2s-pcm.c index b5101efd1c87..f1fd95bb6416 100644 --- a/sound/soc/blackfin/bf5xx-i2s-pcm.c +++ b/sound/soc/blackfin/bf5xx-i2s-pcm.c | |||
@@ -138,11 +138,20 @@ static snd_pcm_uframes_t bf5xx_pcm_pointer(struct snd_pcm_substream *substream) | |||
138 | pr_debug("%s enter\n", __func__); | 138 | pr_debug("%s enter\n", __func__); |
139 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 139 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
140 | diff = sport_curr_offset_tx(sport); | 140 | diff = sport_curr_offset_tx(sport); |
141 | frames = bytes_to_frames(substream->runtime, diff); | ||
142 | } else { | 141 | } else { |
143 | diff = sport_curr_offset_rx(sport); | 142 | diff = sport_curr_offset_rx(sport); |
144 | frames = bytes_to_frames(substream->runtime, diff); | ||
145 | } | 143 | } |
144 | |||
145 | /* | ||
146 | * TX at least can report one frame beyond the end of the | ||
147 | * buffer if we hit the wraparound case - clamp to within the | ||
148 | * buffer as the ALSA APIs require. | ||
149 | */ | ||
150 | if (diff == snd_pcm_lib_buffer_bytes(substream)) | ||
151 | diff = 0; | ||
152 | |||
153 | frames = bytes_to_frames(substream->runtime, diff); | ||
154 | |||
146 | return frames; | 155 | return frames; |
147 | } | 156 | } |
148 | 157 | ||
diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 4be0570e3f1f..65f46047b1cb 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c | |||
@@ -357,7 +357,7 @@ static int ak4642_dai_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) | |||
357 | default: | 357 | default: |
358 | return -EINVAL; | 358 | return -EINVAL; |
359 | } | 359 | } |
360 | snd_soc_update_bits(codec, PW_MGMT2, MS, data); | 360 | snd_soc_update_bits(codec, PW_MGMT2, MS | MCKO | PMPLL, data); |
361 | snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko); | 361 | snd_soc_update_bits(codec, MD_CTL1, BCKO_MASK, bcko); |
362 | 362 | ||
363 | /* format type */ | 363 | /* format type */ |
diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index e2a7608d3944..7859bdcc93db 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c | |||
@@ -161,10 +161,18 @@ static int aic26_hw_params(struct snd_pcm_substream *substream, | |||
161 | dev_dbg(&aic26->spi->dev, "bad format\n"); return -EINVAL; | 161 | dev_dbg(&aic26->spi->dev, "bad format\n"); return -EINVAL; |
162 | } | 162 | } |
163 | 163 | ||
164 | /* Configure PLL */ | 164 | /** |
165 | * Configure PLL | ||
166 | * fsref = (mclk * PLLM) / 2048 | ||
167 | * where PLLM = J.DDDD (DDDD register ranges from 0 to 9999, decimal) | ||
168 | */ | ||
165 | pval = 1; | 169 | pval = 1; |
166 | jval = (fsref == 44100) ? 7 : 8; | 170 | /* compute J portion of multiplier */ |
167 | dval = (fsref == 44100) ? 5264 : 1920; | 171 | jval = fsref / (aic26->mclk / 2048); |
172 | /* compute fractional DDDD component of multiplier */ | ||
173 | dval = fsref - (jval * (aic26->mclk / 2048)); | ||
174 | dval = (10000 * dval) / (aic26->mclk / 2048); | ||
175 | dev_dbg(&aic26->spi->dev, "Setting PLLM to %d.%04d\n", jval, dval); | ||
168 | qval = 0; | 176 | qval = 0; |
169 | reg = 0x8000 | qval << 11 | pval << 8 | jval << 2; | 177 | reg = 0x8000 | qval << 11 | pval << 8 | jval << 2; |
170 | aic26_reg_write(codec, AIC26_REG_PLL_PROG1, reg); | 178 | aic26_reg_write(codec, AIC26_REG_PLL_PROG1, reg); |
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index c3d96fc8c267..789453d44ec5 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
@@ -1114,12 +1114,19 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power) | |||
1114 | 1114 | ||
1115 | /* Sync reg_cache with the hardware */ | 1115 | /* Sync reg_cache with the hardware */ |
1116 | codec->cache_only = 0; | 1116 | codec->cache_only = 0; |
1117 | for (i = 0; i < ARRAY_SIZE(aic3x_reg); i++) | 1117 | for (i = AIC3X_SAMPLE_RATE_SEL_REG; i < ARRAY_SIZE(aic3x_reg); i++) |
1118 | snd_soc_write(codec, i, cache[i]); | 1118 | snd_soc_write(codec, i, cache[i]); |
1119 | if (aic3x->model == AIC3X_MODEL_3007) | 1119 | if (aic3x->model == AIC3X_MODEL_3007) |
1120 | aic3x_init_3007(codec); | 1120 | aic3x_init_3007(codec); |
1121 | codec->cache_sync = 0; | 1121 | codec->cache_sync = 0; |
1122 | } else { | 1122 | } else { |
1123 | /* | ||
1124 | * Do soft reset to this codec instance in order to clear | ||
1125 | * possible VDD leakage currents in case the supply regulators | ||
1126 | * remain on | ||
1127 | */ | ||
1128 | snd_soc_write(codec, AIC3X_RESET, SOFT_RESET); | ||
1129 | codec->cache_sync = 1; | ||
1123 | aic3x->power = 0; | 1130 | aic3x->power = 0; |
1124 | /* HW writes are needless when bias is off */ | 1131 | /* HW writes are needless when bias is off */ |
1125 | codec->cache_only = 1; | 1132 | codec->cache_only = 1; |
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 2dc964b55e4f..76b4361e9b80 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c | |||
@@ -175,6 +175,7 @@ static const struct snd_kcontrol_new wm8731_input_mux_controls = | |||
175 | SOC_DAPM_ENUM("Input Select", wm8731_insel_enum); | 175 | SOC_DAPM_ENUM("Input Select", wm8731_insel_enum); |
176 | 176 | ||
177 | static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = { | 177 | static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = { |
178 | SND_SOC_DAPM_SUPPLY("ACTIVE",WM8731_ACTIVE, 0, 0, NULL, 0), | ||
178 | SND_SOC_DAPM_SUPPLY("OSC", WM8731_PWR, 5, 1, NULL, 0), | 179 | SND_SOC_DAPM_SUPPLY("OSC", WM8731_PWR, 5, 1, NULL, 0), |
179 | SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, | 180 | SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, |
180 | &wm8731_output_mixer_controls[0], | 181 | &wm8731_output_mixer_controls[0], |
@@ -204,6 +205,8 @@ static int wm8731_check_osc(struct snd_soc_dapm_widget *source, | |||
204 | static const struct snd_soc_dapm_route wm8731_intercon[] = { | 205 | static const struct snd_soc_dapm_route wm8731_intercon[] = { |
205 | {"DAC", NULL, "OSC", wm8731_check_osc}, | 206 | {"DAC", NULL, "OSC", wm8731_check_osc}, |
206 | {"ADC", NULL, "OSC", wm8731_check_osc}, | 207 | {"ADC", NULL, "OSC", wm8731_check_osc}, |
208 | {"DAC", NULL, "ACTIVE"}, | ||
209 | {"ADC", NULL, "ACTIVE"}, | ||
207 | 210 | ||
208 | /* output mixer */ | 211 | /* output mixer */ |
209 | {"Output Mixer", "Line Bypass Switch", "Line Input"}, | 212 | {"Output Mixer", "Line Bypass Switch", "Line Input"}, |
@@ -315,29 +318,6 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream, | |||
315 | return 0; | 318 | return 0; |
316 | } | 319 | } |
317 | 320 | ||
318 | static int wm8731_pcm_prepare(struct snd_pcm_substream *substream, | ||
319 | struct snd_soc_dai *dai) | ||
320 | { | ||
321 | struct snd_soc_codec *codec = dai->codec; | ||
322 | |||
323 | /* set active */ | ||
324 | snd_soc_write(codec, WM8731_ACTIVE, 0x0001); | ||
325 | |||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | static void wm8731_shutdown(struct snd_pcm_substream *substream, | ||
330 | struct snd_soc_dai *dai) | ||
331 | { | ||
332 | struct snd_soc_codec *codec = dai->codec; | ||
333 | |||
334 | /* deactivate */ | ||
335 | if (!codec->active) { | ||
336 | udelay(50); | ||
337 | snd_soc_write(codec, WM8731_ACTIVE, 0x0); | ||
338 | } | ||
339 | } | ||
340 | |||
341 | static int wm8731_mute(struct snd_soc_dai *dai, int mute) | 321 | static int wm8731_mute(struct snd_soc_dai *dai, int mute) |
342 | { | 322 | { |
343 | struct snd_soc_codec *codec = dai->codec; | 323 | struct snd_soc_codec *codec = dai->codec; |
@@ -480,7 +460,6 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec, | |||
480 | snd_soc_write(codec, WM8731_PWR, reg | 0x0040); | 460 | snd_soc_write(codec, WM8731_PWR, reg | 0x0040); |
481 | break; | 461 | break; |
482 | case SND_SOC_BIAS_OFF: | 462 | case SND_SOC_BIAS_OFF: |
483 | snd_soc_write(codec, WM8731_ACTIVE, 0x0); | ||
484 | snd_soc_write(codec, WM8731_PWR, 0xffff); | 463 | snd_soc_write(codec, WM8731_PWR, 0xffff); |
485 | regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), | 464 | regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), |
486 | wm8731->supplies); | 465 | wm8731->supplies); |
@@ -496,9 +475,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec, | |||
496 | SNDRV_PCM_FMTBIT_S24_LE) | 475 | SNDRV_PCM_FMTBIT_S24_LE) |
497 | 476 | ||
498 | static struct snd_soc_dai_ops wm8731_dai_ops = { | 477 | static struct snd_soc_dai_ops wm8731_dai_ops = { |
499 | .prepare = wm8731_pcm_prepare, | ||
500 | .hw_params = wm8731_hw_params, | 478 | .hw_params = wm8731_hw_params, |
501 | .shutdown = wm8731_shutdown, | ||
502 | .digital_mute = wm8731_mute, | 479 | .digital_mute = wm8731_mute, |
503 | .set_sysclk = wm8731_set_dai_sysclk, | 480 | .set_sysclk = wm8731_set_dai_sysclk, |
504 | .set_fmt = wm8731_set_dai_fmt, | 481 | .set_fmt = wm8731_set_dai_fmt, |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 970a95c5360b..83014a7c2e14 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -1190,7 +1190,6 @@ SND_SOC_DAPM_INPUT("DMIC1DAT"), | |||
1190 | SND_SOC_DAPM_INPUT("DMIC2DAT"), | 1190 | SND_SOC_DAPM_INPUT("DMIC2DAT"), |
1191 | SND_SOC_DAPM_INPUT("Clock"), | 1191 | SND_SOC_DAPM_INPUT("Clock"), |
1192 | 1192 | ||
1193 | SND_SOC_DAPM_MICBIAS("MICBIAS", WM8994_MICBIAS, 2, 0), | ||
1194 | SND_SOC_DAPM_SUPPLY_S("MICBIAS Supply", 1, SND_SOC_NOPM, 0, 0, micbias_ev, | 1193 | SND_SOC_DAPM_SUPPLY_S("MICBIAS Supply", 1, SND_SOC_NOPM, 0, 0, micbias_ev, |
1195 | SND_SOC_DAPM_PRE_PMU), | 1194 | SND_SOC_DAPM_PRE_PMU), |
1196 | 1195 | ||
@@ -1509,8 +1508,10 @@ static const struct snd_soc_dapm_route wm8994_revd_intercon[] = { | |||
1509 | { "AIF2DACDAT", NULL, "AIF1DACDAT" }, | 1508 | { "AIF2DACDAT", NULL, "AIF1DACDAT" }, |
1510 | { "AIF1ADCDAT", NULL, "AIF2ADCDAT" }, | 1509 | { "AIF1ADCDAT", NULL, "AIF2ADCDAT" }, |
1511 | { "AIF2ADCDAT", NULL, "AIF1ADCDAT" }, | 1510 | { "AIF2ADCDAT", NULL, "AIF1ADCDAT" }, |
1512 | { "MICBIAS", NULL, "CLK_SYS" }, | 1511 | { "MICBIAS1", NULL, "CLK_SYS" }, |
1513 | { "MICBIAS", NULL, "MICBIAS Supply" }, | 1512 | { "MICBIAS1", NULL, "MICBIAS Supply" }, |
1513 | { "MICBIAS2", NULL, "CLK_SYS" }, | ||
1514 | { "MICBIAS2", NULL, "MICBIAS Supply" }, | ||
1514 | }; | 1515 | }; |
1515 | 1516 | ||
1516 | static const struct snd_soc_dapm_route wm8994_intercon[] = { | 1517 | static const struct snd_soc_dapm_route wm8994_intercon[] = { |
@@ -1713,6 +1714,8 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, | |||
1713 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset, | 1714 | snd_soc_update_bits(codec, WM8994_FLL1_CONTROL_1 + reg_offset, |
1714 | WM8994_FLL1_ENA | WM8994_FLL1_FRAC, | 1715 | WM8994_FLL1_ENA | WM8994_FLL1_FRAC, |
1715 | reg); | 1716 | reg); |
1717 | |||
1718 | msleep(5); | ||
1716 | } | 1719 | } |
1717 | 1720 | ||
1718 | wm8994->fll[id].in = freq_in; | 1721 | wm8994->fll[id].in = freq_in; |
@@ -2761,7 +2764,7 @@ static void wm8958_default_micdet(u16 status, void *data) | |||
2761 | report = SND_JACK_MICROPHONE; | 2764 | report = SND_JACK_MICROPHONE; |
2762 | 2765 | ||
2763 | /* Everything else is buttons; just assign slots */ | 2766 | /* Everything else is buttons; just assign slots */ |
2764 | if (status & 0x1c0) | 2767 | if (status & 0x1c) |
2765 | report |= SND_JACK_BTN_0; | 2768 | report |= SND_JACK_BTN_0; |
2766 | 2769 | ||
2767 | done: | 2770 | done: |
diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c index d6f4703b3c07..770a71a15366 100644 --- a/sound/soc/sh/fsi-ak4642.c +++ b/sound/soc/sh/fsi-ak4642.c | |||
@@ -97,7 +97,7 @@ static int fsi_ak4642_remove(struct platform_device *pdev) | |||
97 | 97 | ||
98 | static struct fsi_ak4642_data fsi_a_ak4642 = { | 98 | static struct fsi_ak4642_data fsi_a_ak4642 = { |
99 | .name = "AK4642", | 99 | .name = "AK4642", |
100 | .card = "FSIA (AK4642)", | 100 | .card = "FSIA-AK4642", |
101 | .cpu_dai = "fsia-dai", | 101 | .cpu_dai = "fsia-dai", |
102 | .codec = "ak4642-codec.0-0012", | 102 | .codec = "ak4642-codec.0-0012", |
103 | .platform = "sh_fsi.0", | 103 | .platform = "sh_fsi.0", |
@@ -106,7 +106,7 @@ static struct fsi_ak4642_data fsi_a_ak4642 = { | |||
106 | 106 | ||
107 | static struct fsi_ak4642_data fsi_b_ak4642 = { | 107 | static struct fsi_ak4642_data fsi_b_ak4642 = { |
108 | .name = "AK4642", | 108 | .name = "AK4642", |
109 | .card = "FSIB (AK4642)", | 109 | .card = "FSIB-AK4642", |
110 | .cpu_dai = "fsib-dai", | 110 | .cpu_dai = "fsib-dai", |
111 | .codec = "ak4642-codec.0-0012", | 111 | .codec = "ak4642-codec.0-0012", |
112 | .platform = "sh_fsi.0", | 112 | .platform = "sh_fsi.0", |
@@ -115,7 +115,7 @@ static struct fsi_ak4642_data fsi_b_ak4642 = { | |||
115 | 115 | ||
116 | static struct fsi_ak4642_data fsi_a_ak4643 = { | 116 | static struct fsi_ak4642_data fsi_a_ak4643 = { |
117 | .name = "AK4643", | 117 | .name = "AK4643", |
118 | .card = "FSIA (AK4643)", | 118 | .card = "FSIA-AK4643", |
119 | .cpu_dai = "fsia-dai", | 119 | .cpu_dai = "fsia-dai", |
120 | .codec = "ak4642-codec.0-0013", | 120 | .codec = "ak4642-codec.0-0013", |
121 | .platform = "sh_fsi.0", | 121 | .platform = "sh_fsi.0", |
@@ -124,7 +124,7 @@ static struct fsi_ak4642_data fsi_a_ak4643 = { | |||
124 | 124 | ||
125 | static struct fsi_ak4642_data fsi_b_ak4643 = { | 125 | static struct fsi_ak4642_data fsi_b_ak4643 = { |
126 | .name = "AK4643", | 126 | .name = "AK4643", |
127 | .card = "FSIB (AK4643)", | 127 | .card = "FSIB-AK4643", |
128 | .cpu_dai = "fsib-dai", | 128 | .cpu_dai = "fsib-dai", |
129 | .codec = "ak4642-codec.0-0013", | 129 | .codec = "ak4642-codec.0-0013", |
130 | .platform = "sh_fsi.0", | 130 | .platform = "sh_fsi.0", |
@@ -133,7 +133,7 @@ static struct fsi_ak4642_data fsi_b_ak4643 = { | |||
133 | 133 | ||
134 | static struct fsi_ak4642_data fsi2_a_ak4642 = { | 134 | static struct fsi_ak4642_data fsi2_a_ak4642 = { |
135 | .name = "AK4642", | 135 | .name = "AK4642", |
136 | .card = "FSI2A (AK4642)", | 136 | .card = "FSI2A-AK4642", |
137 | .cpu_dai = "fsia-dai", | 137 | .cpu_dai = "fsia-dai", |
138 | .codec = "ak4642-codec.0-0012", | 138 | .codec = "ak4642-codec.0-0012", |
139 | .platform = "sh_fsi2", | 139 | .platform = "sh_fsi2", |
@@ -142,7 +142,7 @@ static struct fsi_ak4642_data fsi2_a_ak4642 = { | |||
142 | 142 | ||
143 | static struct fsi_ak4642_data fsi2_b_ak4642 = { | 143 | static struct fsi_ak4642_data fsi2_b_ak4642 = { |
144 | .name = "AK4642", | 144 | .name = "AK4642", |
145 | .card = "FSI2B (AK4642)", | 145 | .card = "FSI2B-AK4642", |
146 | .cpu_dai = "fsib-dai", | 146 | .cpu_dai = "fsib-dai", |
147 | .codec = "ak4642-codec.0-0012", | 147 | .codec = "ak4642-codec.0-0012", |
148 | .platform = "sh_fsi2", | 148 | .platform = "sh_fsi2", |
@@ -151,7 +151,7 @@ static struct fsi_ak4642_data fsi2_b_ak4642 = { | |||
151 | 151 | ||
152 | static struct fsi_ak4642_data fsi2_a_ak4643 = { | 152 | static struct fsi_ak4642_data fsi2_a_ak4643 = { |
153 | .name = "AK4643", | 153 | .name = "AK4643", |
154 | .card = "FSI2A (AK4643)", | 154 | .card = "FSI2A-AK4643", |
155 | .cpu_dai = "fsia-dai", | 155 | .cpu_dai = "fsia-dai", |
156 | .codec = "ak4642-codec.0-0013", | 156 | .codec = "ak4642-codec.0-0013", |
157 | .platform = "sh_fsi2", | 157 | .platform = "sh_fsi2", |
@@ -160,7 +160,7 @@ static struct fsi_ak4642_data fsi2_a_ak4643 = { | |||
160 | 160 | ||
161 | static struct fsi_ak4642_data fsi2_b_ak4643 = { | 161 | static struct fsi_ak4642_data fsi2_b_ak4643 = { |
162 | .name = "AK4643", | 162 | .name = "AK4643", |
163 | .card = "FSI2B (AK4643)", | 163 | .card = "FSI2B-AK4643", |
164 | .cpu_dai = "fsib-dai", | 164 | .cpu_dai = "fsib-dai", |
165 | .codec = "ak4642-codec.0-0013", | 165 | .codec = "ak4642-codec.0-0013", |
166 | .platform = "sh_fsi2", | 166 | .platform = "sh_fsi2", |
diff --git a/sound/soc/sh/fsi-da7210.c b/sound/soc/sh/fsi-da7210.c index dbafd7ac5590..59553fd8c2fb 100644 --- a/sound/soc/sh/fsi-da7210.c +++ b/sound/soc/sh/fsi-da7210.c | |||
@@ -42,7 +42,7 @@ static struct snd_soc_dai_link fsi_da7210_dai = { | |||
42 | }; | 42 | }; |
43 | 43 | ||
44 | static struct snd_soc_card fsi_soc_card = { | 44 | static struct snd_soc_card fsi_soc_card = { |
45 | .name = "FSI (DA7210)", | 45 | .name = "FSI-DA7210", |
46 | .dai_link = &fsi_da7210_dai, | 46 | .dai_link = &fsi_da7210_dai, |
47 | .num_links = 1, | 47 | .num_links = 1, |
48 | }; | 48 | }; |
diff --git a/sound/soc/sh/fsi-hdmi.c b/sound/soc/sh/fsi-hdmi.c index 9719985eb82d..d3d9fd880680 100644 --- a/sound/soc/sh/fsi-hdmi.c +++ b/sound/soc/sh/fsi-hdmi.c | |||
@@ -83,13 +83,13 @@ static int fsi_hdmi_remove(struct platform_device *pdev) | |||
83 | 83 | ||
84 | static struct fsi_hdmi_data fsi2_a_hdmi = { | 84 | static struct fsi_hdmi_data fsi2_a_hdmi = { |
85 | .cpu_dai = "fsia-dai", | 85 | .cpu_dai = "fsia-dai", |
86 | .card = "FSI2A (SH MOBILE HDMI)", | 86 | .card = "FSI2A-HDMI", |
87 | .id = FSI_PORT_A, | 87 | .id = FSI_PORT_A, |
88 | }; | 88 | }; |
89 | 89 | ||
90 | static struct fsi_hdmi_data fsi2_b_hdmi = { | 90 | static struct fsi_hdmi_data fsi2_b_hdmi = { |
91 | .cpu_dai = "fsib-dai", | 91 | .cpu_dai = "fsib-dai", |
92 | .card = "FSI2B (SH MOBILE HDMI)", | 92 | .card = "FSI2B-HDMI", |
93 | .id = FSI_PORT_B, | 93 | .id = FSI_PORT_B, |
94 | }; | 94 | }; |
95 | 95 | ||
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index d75043ed7fc0..b194be09e74d 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -1929,8 +1929,9 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) | |||
1929 | "%s", card->name); | 1929 | "%s", card->name); |
1930 | snprintf(card->snd_card->longname, sizeof(card->snd_card->longname), | 1930 | snprintf(card->snd_card->longname, sizeof(card->snd_card->longname), |
1931 | "%s", card->long_name ? card->long_name : card->name); | 1931 | "%s", card->long_name ? card->long_name : card->name); |
1932 | snprintf(card->snd_card->driver, sizeof(card->snd_card->driver), | 1932 | if (card->driver_name) |
1933 | "%s", card->driver_name ? card->driver_name : card->name); | 1933 | strlcpy(card->snd_card->driver, card->driver_name, |
1934 | sizeof(card->snd_card->driver)); | ||
1934 | 1935 | ||
1935 | if (card->late_probe) { | 1936 | if (card->late_probe) { |
1936 | ret = card->late_probe(card); | 1937 | ret = card->late_probe(card); |
diff --git a/sound/soc/tegra/tegra_i2s.c b/sound/soc/tegra/tegra_i2s.c index 6b817e20548c..95f03c10b4f7 100644 --- a/sound/soc/tegra/tegra_i2s.c +++ b/sound/soc/tegra/tegra_i2s.c | |||
@@ -222,12 +222,18 @@ static int tegra_i2s_hw_params(struct snd_pcm_substream *substream, | |||
222 | if (i2sclock % (2 * srate)) | 222 | if (i2sclock % (2 * srate)) |
223 | reg |= TEGRA_I2S_TIMING_NON_SYM_ENABLE; | 223 | reg |= TEGRA_I2S_TIMING_NON_SYM_ENABLE; |
224 | 224 | ||
225 | if (!i2s->clk_refs) | ||
226 | clk_enable(i2s->clk_i2s); | ||
227 | |||
225 | tegra_i2s_write(i2s, TEGRA_I2S_TIMING, reg); | 228 | tegra_i2s_write(i2s, TEGRA_I2S_TIMING, reg); |
226 | 229 | ||
227 | tegra_i2s_write(i2s, TEGRA_I2S_FIFO_SCR, | 230 | tegra_i2s_write(i2s, TEGRA_I2S_FIFO_SCR, |
228 | TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS | | 231 | TEGRA_I2S_FIFO_SCR_FIFO2_ATN_LVL_FOUR_SLOTS | |
229 | TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS); | 232 | TEGRA_I2S_FIFO_SCR_FIFO1_ATN_LVL_FOUR_SLOTS); |
230 | 233 | ||
234 | if (!i2s->clk_refs) | ||
235 | clk_disable(i2s->clk_i2s); | ||
236 | |||
231 | return 0; | 237 | return 0; |
232 | } | 238 | } |
233 | 239 | ||